diff --git a/.gitignore b/.gitignore
index a8ea9cb1eb..a83a93d01f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,7 @@ npm-debug.log
node_modules/
sftp-config.json
config.json
+jsconfig.json
public/src/nodebb.min.js
!src/views/config.json
public/css/*.css
diff --git a/app.js b/app.js
index 2158d61282..c633af9932 100644
--- a/app.js
+++ b/app.js
@@ -103,6 +103,10 @@ function loadConfig() {
nconf.set('themes_path', path.resolve(__dirname, nconf.get('themes_path')));
nconf.set('core_templates_path', path.join(__dirname, 'src/views'));
nconf.set('base_templates_path', path.join(nconf.get('themes_path'), 'nodebb-theme-persona/templates'));
+
+ if (nconf.get('url')) {
+ nconf.set('url_parsed', url.parse(nconf.get('url')));
+ }
}
@@ -120,7 +124,7 @@ function start() {
nconf.set('secure', urlObject.protocol === 'https:');
nconf.set('use_port', !!urlObject.port);
nconf.set('relative_path', relativePath);
- nconf.set('port', urlObject.port || nconf.get('port') || nconf.get('PORT') || 4567);
+ nconf.set('port', urlObject.port || nconf.get('port') || nconf.get('PORT') || (nconf.get('PORT_ENV_VAR') ? nconf.get(nconf.get('PORT_ENV_VAR')) : false) || 4567);
nconf.set('upload_url', nconf.get('upload_path').replace(/^\/public/, ''));
if (nconf.get('isPrimary') === 'true') {
diff --git a/package.json b/package.json
index 4d62cadea3..1b62333fda 100644
--- a/package.json
+++ b/package.json
@@ -36,6 +36,7 @@
"html-to-text": "2.0.0",
"ip": "1.1.2",
"jimp": "0.2.21",
+ "jquery": "^3.1.0",
"json-2-csv": "^2.0.22",
"less": "^2.0.0",
"logrotate-stream": "^0.2.3",
@@ -47,7 +48,7 @@
"morgan": "^1.3.2",
"mousetrap": "^1.5.3",
"nconf": "~0.8.2",
- "nodebb-plugin-composer-default": "4.1.8",
+ "nodebb-plugin-composer-default": "4.2.2",
"nodebb-plugin-dbsearch": "1.0.2",
"nodebb-plugin-emoji-extended": "1.1.1",
"nodebb-plugin-emoji-one": "1.1.5",
@@ -57,8 +58,8 @@
"nodebb-plugin-spam-be-gone": "0.4.10",
"nodebb-rewards-essentials": "0.0.9",
"nodebb-theme-lavender": "3.0.13",
- "nodebb-theme-persona": "4.1.23",
- "nodebb-theme-vanilla": "5.1.11",
+ "nodebb-theme-persona": "4.1.37",
+ "nodebb-theme-vanilla": "5.1.21",
"nodebb-widget-essentials": "2.0.10",
"nodemailer": "2.0.0",
"nodemailer-sendmail-transport": "1.0.0",
@@ -117,4 +118,4 @@
"url": "https://github.com/barisusakli"
}
]
-}
\ No newline at end of file
+}
diff --git a/public/language/ar/global.json b/public/language/ar/global.json
index 96356a3bce..fc94028a36 100644
--- a/public/language/ar/global.json
+++ b/public/language/ar/global.json
@@ -7,8 +7,10 @@
"403.login": "Perhaps you should try logging in?",
"404.title": "لم يتم العثور",
"404.message": "You seem to have stumbled upon a page that does not exist. Return to the home page.",
- "500.title": "خطأ داخلي.",
+ "500.title": "Internal Error.",
"500.message": "عفوا! يبدو وكأنه شيء ذهب على نحو خاطئ!",
+ "400.title": "Bad Request.",
+ "400.message": "It looks like this link is malformed, please double-check and try again. Otherwise, return to the home page.",
"register": "تسجيل",
"login": "دخول",
"please_log_in": "المرجو تسجيل الدخول",
@@ -93,5 +95,6 @@
"upload_file": "Upload file",
"upload": "Upload",
"allowed-file-types": "Allowed file types are %1",
- "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?"
+ "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?",
+ "reconnecting-message": "Looks like your connection to %1 was lost, please wait while we try to reconnect."
}
\ No newline at end of file
diff --git a/public/language/bg/global.json b/public/language/bg/global.json
index 189c8d3990..d4ffed8334 100644
--- a/public/language/bg/global.json
+++ b/public/language/bg/global.json
@@ -9,6 +9,8 @@
"404.message": "Изглежда сте се опитали да посетите страница, която не съществува. Върнете се към началната страница.",
"500.title": "Вътрешна грешка.",
"500.message": "Опа! Изглежда нещо се обърка!",
+ "400.title": "Грешна заявка.",
+ "400.message": "Тази връзка изглежда повредена. Моля, проверете я и опитайте отново. В противен случай се върнете на началната страница.",
"register": "Регистрация",
"login": "Вход",
"please_log_in": "Моля, влезте",
@@ -93,5 +95,6 @@
"upload_file": "Качване на файл",
"upload": "Качване",
"allowed-file-types": "Разрешените файлови типове са: %1",
- "unsaved-changes": "Имате незапазени промени. Наистина ли искате да напуснете тази страница?"
+ "unsaved-changes": "Имате незапазени промени. Наистина ли искате да напуснете тази страница?",
+ "reconnecting-message": "Изглежда връзката Ви към %1 беше прекъсната. Моля, изчакайте докато се опитаме да Ви свържем отново."
}
\ No newline at end of file
diff --git a/public/language/bn/global.json b/public/language/bn/global.json
index bfde1d9003..545020267d 100644
--- a/public/language/bn/global.json
+++ b/public/language/bn/global.json
@@ -7,8 +7,10 @@
"403.login": "Perhaps you should try logging in?",
"404.title": "পাওয়া যায়নি",
"404.message": "You seem to have stumbled upon a page that does not exist. Return to the home page.",
- "500.title": "অভ্যন্তরীণ ত্রুটি।",
+ "500.title": "Internal Error.",
"500.message": "ওহো! কিছু ভুল হয়েছে মনে হচ্ছে!",
+ "400.title": "Bad Request.",
+ "400.message": "It looks like this link is malformed, please double-check and try again. Otherwise, return to the home page.",
"register": "নিবন্ধন",
"login": "প্রবেশ",
"please_log_in": "অনুগ্রহ করে প্রবেশ করুন",
@@ -93,5 +95,6 @@
"upload_file": "Upload file",
"upload": "Upload",
"allowed-file-types": "Allowed file types are %1",
- "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?"
+ "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?",
+ "reconnecting-message": "Looks like your connection to %1 was lost, please wait while we try to reconnect."
}
\ No newline at end of file
diff --git a/public/language/cs/global.json b/public/language/cs/global.json
index d78d3797f4..e822b289c3 100644
--- a/public/language/cs/global.json
+++ b/public/language/cs/global.json
@@ -7,8 +7,10 @@
"403.login": "Možná byste měli se zkusit přihlásit?",
"404.title": "Stránka nenalezena",
"404.message": "Zdá se, že jste narazil/a na stránku která neexistuje. Vrátit se zpět na domovskou stránku.",
- "500.title": "Neznámá chyba",
+ "500.title": "Internal Error.",
"500.message": "Jejda, vypadá to, že se něco pokazilo.",
+ "400.title": "Bad Request.",
+ "400.message": "It looks like this link is malformed, please double-check and try again. Otherwise, return to the home page.",
"register": "Registrovat",
"login": "Přihlásit se",
"please_log_in": "Přihlašte se, prosím",
@@ -93,5 +95,6 @@
"upload_file": "Nahrár soubor",
"upload": "Nahrát",
"allowed-file-types": "Povolené typy souborů jsou %1",
- "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?"
+ "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?",
+ "reconnecting-message": "Looks like your connection to %1 was lost, please wait while we try to reconnect."
}
\ No newline at end of file
diff --git a/public/language/da/global.json b/public/language/da/global.json
index 2eda261502..5ef9da2842 100644
--- a/public/language/da/global.json
+++ b/public/language/da/global.json
@@ -7,8 +7,10 @@
"403.login": "Måske du skulle prøve og logge ind?",
"404.title": "Ikke fundet",
"404.message": "Det ser ud til du er stødt på en side der ikke finder. Retuner til forsiden.",
- "500.title": "Intern fejl.",
+ "500.title": "Internal Error.",
"500.message": "Ups! Ser ud til at noget gik galt!",
+ "400.title": "Bad Request.",
+ "400.message": "It looks like this link is malformed, please double-check and try again. Otherwise, return to the home page.",
"register": "Tilmeld",
"login": "Log ind",
"please_log_in": "Venligst log ind",
@@ -93,5 +95,6 @@
"upload_file": "Upload fil",
"upload": "Upload",
"allowed-file-types": "Tilladte filtyper er %1",
- "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?"
+ "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?",
+ "reconnecting-message": "Looks like your connection to %1 was lost, please wait while we try to reconnect."
}
\ No newline at end of file
diff --git a/public/language/de/global.json b/public/language/de/global.json
index 496c212943..2793fc58cf 100644
--- a/public/language/de/global.json
+++ b/public/language/de/global.json
@@ -7,8 +7,10 @@
"403.login": "Du solltest Dich anmelden.",
"404.title": " Nicht Gefunden",
"404.message": "Diese Seite existiert nicht. Zur Homepage zurückkehren.",
- "500.title": "Interner Fehler.",
+ "500.title": "Internal Error.",
"500.message": "Ups! Scheint als wäre etwas schief gelaufen!",
+ "400.title": "Bad Request.",
+ "400.message": "It looks like this link is malformed, please double-check and try again. Otherwise, return to the home page.",
"register": "Registrieren",
"login": "Anmelden",
"please_log_in": "Bitte anmelden",
@@ -93,5 +95,6 @@
"upload_file": "Datei hochladen",
"upload": "Hochladen",
"allowed-file-types": "Erlaubte Dateitypen sind %1",
- "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?"
+ "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?",
+ "reconnecting-message": "Looks like your connection to %1 was lost, please wait while we try to reconnect."
}
\ No newline at end of file
diff --git a/public/language/el/global.json b/public/language/el/global.json
index 32eacb6466..34df3b45bf 100644
--- a/public/language/el/global.json
+++ b/public/language/el/global.json
@@ -7,8 +7,10 @@
"403.login": "Perhaps you should try logging in?",
"404.title": "Δεν βρέθηκε",
"404.message": "You seem to have stumbled upon a page that does not exist. Return to the home page.",
- "500.title": "Εσωτερικό σφάλμα.",
+ "500.title": "Internal Error.",
"500.message": "Ουπς! Φαίνεται πως κάτι πήγε στραβά!",
+ "400.title": "Bad Request.",
+ "400.message": "It looks like this link is malformed, please double-check and try again. Otherwise, return to the home page.",
"register": "Εγγραφή",
"login": "Σύνδεση",
"please_log_in": "Παρακαλώ Συνδέσου",
@@ -93,5 +95,6 @@
"upload_file": "Upload file",
"upload": "Upload",
"allowed-file-types": "Allowed file types are %1",
- "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?"
+ "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?",
+ "reconnecting-message": "Looks like your connection to %1 was lost, please wait while we try to reconnect."
}
\ No newline at end of file
diff --git a/public/language/en@pirate/global.json b/public/language/en@pirate/global.json
index 6c86c89999..aa50d9d08a 100644
--- a/public/language/en@pirate/global.json
+++ b/public/language/en@pirate/global.json
@@ -7,8 +7,10 @@
"403.login": "Perhaps you should try logging in?",
"404.title": "T'ere be nut'in 'ere",
"404.message": "You seem to have stumbled upon a page that does not exist. Return to the home page.",
- "500.title": "Broken beam.",
+ "500.title": "Internal Error.",
"500.message": "Looks like we've got somethin' in th' sails.",
+ "400.title": "Bad Request.",
+ "400.message": "It looks like this link is malformed, please double-check and try again. Otherwise, return to the home page.",
"register": "Register",
"login": "Login",
"please_log_in": "Please Log In",
@@ -93,5 +95,6 @@
"upload_file": "Upload file",
"upload": "Upload",
"allowed-file-types": "Allowed file types are %1",
- "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?"
+ "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?",
+ "reconnecting-message": "Looks like your connection to %1 was lost, please wait while we try to reconnect."
}
\ No newline at end of file
diff --git a/public/language/en_GB/category.json b/public/language/en_GB/category.json
index d4da76f356..d581c8277d 100644
--- a/public/language/en_GB/category.json
+++ b/public/language/en_GB/category.json
@@ -18,8 +18,8 @@
"watching.description": "Show topics in unread",
"ignoring.description": "Do not show topics in unread",
- "watch.message": "You are now watching updates from this category",
- "ignore.message": "You are now ignoring updates from this category",
+ "watch.message": "You are now watching updates from this category and all subcategories",
+ "ignore.message": "You are now ignoring updates from this category and all subcategories",
"watched-categories": "Watched categories"
}
diff --git a/public/language/en_GB/global.json b/public/language/en_GB/global.json
index b8cadf0bc6..e2785de2f5 100644
--- a/public/language/en_GB/global.json
+++ b/public/language/en_GB/global.json
@@ -120,5 +120,7 @@
"upload": "Upload",
"allowed-file-types": "Allowed file types are %1",
- "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?"
+ "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?",
+ "reconnecting-message": "Looks like your connection to %1 was lost, please wait while we try to reconnect.",
+ "play": "Play"
}
diff --git a/public/language/en_GB/user.json b/public/language/en_GB/user.json
index b1cb065de5..5863d4d67c 100644
--- a/public/language/en_GB/user.json
+++ b/public/language/en_GB/user.json
@@ -98,6 +98,10 @@
"posts_per_page": "Posts per Page",
"notification_sounds" : "Play a sound when you receive a notification",
+ "notifications_and_sounds": "Notifications & Sounds",
+ "incoming-message-sound": "Incoming message sound",
+ "outgoing-message-sound": "Outgoing message sound",
+ "notification-sound": "Notification sound",
"browsing": "Browsing Settings",
"open_links_in_new_tab": "Open outgoing links in new tab",
diff --git a/public/language/en_US/global.json b/public/language/en_US/global.json
index e7f511d90a..383516d05c 100644
--- a/public/language/en_US/global.json
+++ b/public/language/en_US/global.json
@@ -7,8 +7,10 @@
"403.login": "Perhaps you should try logging in?",
"404.title": "Not Found",
"404.message": "You seem to have stumbled upon a page that does not exist. Return to the home page.",
- "500.title": "Internal error.",
+ "500.title": "Internal Error.",
"500.message": "Oops! Looks like something went wrong!",
+ "400.title": "Bad Request.",
+ "400.message": "It looks like this link is malformed, please double-check and try again. Otherwise, return to the home page.",
"register": "Register",
"login": "Login",
"please_log_in": "Please Log In",
@@ -93,5 +95,6 @@
"upload_file": "Upload file",
"upload": "Upload",
"allowed-file-types": "Allowed file types are %1",
- "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?"
+ "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?",
+ "reconnecting-message": "Looks like your connection to %1 was lost, please wait while we try to reconnect."
}
\ No newline at end of file
diff --git a/public/language/es/global.json b/public/language/es/global.json
index 3cf4afbbae..2162a64ee7 100644
--- a/public/language/es/global.json
+++ b/public/language/es/global.json
@@ -7,8 +7,10 @@
"403.login": "¿Quizás deberías intentar acceder?",
"404.title": "No encontrado",
"404.message": "Al parecer has llegado a una página a la cual no tienes permisos para acceder. Volver a la página de inicio .",
- "500.title": "Error Interno.",
+ "500.title": "Error interno.",
"500.message": "¡Ooops! ¡Parece que algo salió mal! No te preocupes, ¡nuestros simios hiperinteligentes lo solucionarán!",
+ "400.title": "Petición incorrecta.",
+ "400.message": "Parece que la dirección es errónea, por favor compruébala y prueba otra vez. En caso contrario vuelve al inicio.",
"register": "Registrarse",
"login": "Conectarse",
"please_log_in": "Por favor, identifíquese.",
@@ -93,5 +95,6 @@
"upload_file": "Subir archivo",
"upload": "Subir",
"allowed-file-types": "Los tipos de archivos permitidos son: %1",
- "unsaved-changes": "Tienes cambios sin guardar. Seguro que quieres salir?"
+ "unsaved-changes": "Tienes cambios sin guardar. Seguro que quieres salir?",
+ "reconnecting-message": "Looks like your connection to %1 was lost, please wait while we try to reconnect."
}
\ No newline at end of file
diff --git a/public/language/et/category.json b/public/language/et/category.json
index cdb197eb48..6ff291b297 100644
--- a/public/language/et/category.json
+++ b/public/language/et/category.json
@@ -10,10 +10,10 @@
"share_this_category": "Jaga seda kategooriat",
"watch": "Vaata",
"ignore": "Ignoreeri",
- "watching": "Watching",
- "ignoring": "Ignoring",
- "watching.description": "Show topics in unread",
- "ignoring.description": "Do not show topics in unread",
+ "watching": "Vaatab",
+ "ignoring": "Ignoreerib",
+ "watching.description": "Näita teemasid lugemata teemade hulgas",
+ "ignoring.description": "Ära näita teemasid lugemata teemade hulgas",
"watch.message": "Jälgid nüüdsest teateid sellest kategooriast",
"ignore.message": "Ignoreerid nüüdsest teateid sellest kategooriast",
"watched-categories": "Jälgitavad kategooriad"
diff --git a/public/language/et/error.json b/public/language/et/error.json
index 3aed5d7967..20a047ab3c 100644
--- a/public/language/et/error.json
+++ b/public/language/et/error.json
@@ -20,7 +20,7 @@
"email-taken": "Email on võetud",
"email-not-confirmed": "Su emaili aadress ei ole kinnitatud, vajuta siia et kinnitada.",
"email-not-confirmed-chat": "Sõnumeid ei ole võimalik enne saata kui sinu email on kinnitatud. Kinnitamiseks vajuta siia.",
- "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.",
+ "email-not-confirmed-email-sent": "Su email ei ole veel kinnitatud, palun kontrolli oma e-posti ning kinnita email.",
"no-email-to-confirm": "See foorum nõuab emaili kinnitust, palun vajuta siia, et sisestada email",
"email-confirm-failed": "Meil ei õnnestunud sinu emaili kinnitada, proovi hiljem uuesti.",
"confirm-email-already-sent": "Kinnituskiri on juba saadetud, palun oota %1 minut(it) uue kirja saatmiseks.",
@@ -31,7 +31,7 @@
"user-banned": "Kasutaja bannitud",
"user-too-new": "Vabandust, te peate ootama %1 sekund(it) enne esimese postituse loomist.",
"blacklisted-ip": "Vabandust! Sinu IP-aadress on siin kogukonnas keelatud. Kui arvad, et see on eksitus, palun leia kontakti administraatoriga.",
- "ban-expiry-missing": "Please provide an end date for this ban",
+ "ban-expiry-missing": "Palun sisesta keelu lõpukuupäev",
"no-category": "Kategooriat ei eksisteeri",
"no-topic": "Teemat ei eksisteeri",
"no-post": "Postitust ei eksisteeri",
@@ -48,15 +48,15 @@
"post-edit-duration-expired-hours-minutes": "Teil on lubatud muuta oma postitusi vaid %1 tunni %2 minuti jooksul peale postitamist",
"post-edit-duration-expired-days": "Teil on lubatud muuta oma postitusi vaid %1 päeva jooksul peale postitamist",
"post-edit-duration-expired-days-hours": "Teil on lubatud muuta oma postitusi vaid %1 päeva %2 tunni jooksul peale postitamist",
- "post-delete-duration-expired": "You are only allowed to delete posts for %1 second(s) after posting",
- "post-delete-duration-expired-minutes": "You are only allowed to delete posts for %1 minute(s) after posting",
- "post-delete-duration-expired-minutes-seconds": "You are only allowed to delete posts for %1 minute(s) %2 second(s) after posting",
- "post-delete-duration-expired-hours": "You are only allowed to delete posts for %1 hour(s) after posting",
- "post-delete-duration-expired-hours-minutes": "You are only allowed to delete posts for %1 hour(s) %2 minute(s) after posting",
- "post-delete-duration-expired-days": "You are only allowed to delete posts for %1 day(s) after posting",
- "post-delete-duration-expired-days-hours": "You are only allowed to delete posts for %1 day(s) %2 hour(s) after posting",
- "cant-delete-topic-has-reply": "You can't delete your topic after it has a reply",
- "cant-delete-topic-has-replies": "You can't delete your topic after it has %1 replies",
+ "post-delete-duration-expired": "Teil on lubatud kustutada oma postitusi vaid %1 sekundi jooksul peale postitamist",
+ "post-delete-duration-expired-minutes": "Teil on lubatud kustutada oma postitusi vaid %1 minuti jooksul peale postitamist",
+ "post-delete-duration-expired-minutes-seconds": "Teil on lubatud kustutada oma postitusi vaid %1 minuti %2 sekundi jooksul peale postitamist",
+ "post-delete-duration-expired-hours": "Teil on lubatud kustutada oma postitusi vaid %1 tunni jooksul peale postitamist",
+ "post-delete-duration-expired-hours-minutes": "Teil on lubatud kustutada oma postitusi vaid %1 tunni %2 minuti jooksul peale postitamist",
+ "post-delete-duration-expired-days": "Teil on lubatud kustutada oma postitusi vaid %1 päeva jooksul peale postitamist",
+ "post-delete-duration-expired-days-hours": "Teil on lubatud kustutada oma postitusi vaid %1 päeva %2 tunni jooksul peale postitamist",
+ "cant-delete-topic-has-reply": "Sa ei saa oma postitust kustutada, kui sellele on vastatud",
+ "cant-delete-topic-has-replies": "Sa ei saa oma postitust kustutada pärast seda, kui sellel on %1 vastust",
"content-too-short": "Palun tehke pikem postitus. Postituse pikkus peab olema vähemalt %1 tähemärk(i).",
"content-too-long": "Palun tehke lühem postitus. Postituse pikkus peab olema vähem kui %1 tähemärk(i).",
"title-too-short": "Palun sisesta pikem pealkiri. Pealkirjad ei saa olla lühemad kui %1 tähemärk(i).",
@@ -74,12 +74,12 @@
"already-unfavourited": "Sa oled juba selle postituse järjehoidjatest ära võtnud.",
"cant-ban-other-admins": "Sa ei saa bannida teisi administraatoreid!",
"cant-remove-last-admin": "Te olete ainus administraator. Lisage keegi teine administraatoriks, enne kui eemaldate endalt administraatori.",
- "cant-delete-admin": "Remove administrator privileges from this account before attempting to delete it.",
+ "cant-delete-admin": "Eemalda sellelt kasutajalt administraatori õigused enne selle kustutamist",
"invalid-image-type": "Vigane pildi formaat. Lubatud formaadid on: %1",
"invalid-image-extension": "Vigane pildi formaat",
"invalid-file-type": "Vigane faili formaat. Lubatud formaadid on: %1",
"group-name-too-short": "Grupi nimi liiga lühike",
- "group-name-too-long": "Group name too long",
+ "group-name-too-long": "Grupi nimi liiga pikk",
"group-already-exists": "Grupp juba eksisteerib",
"group-name-change-not-allowed": "Grupi nimevahetus ei ole lubatud",
"group-already-member": "Oled juba selles grupis",
@@ -122,6 +122,6 @@
"not-in-room": "Kasutaja pole ruumis",
"no-users-in-room": "Ühtegi kasutajat ei leidu siit ruumist",
"cant-kick-self": "Sa ei saa ennast ära visata gruppist",
- "no-users-selected": "No user(s) selected",
- "invalid-home-page-route": "Invalid home page route"
+ "no-users-selected": "Ühtki kasutajat pole valitud",
+ "invalid-home-page-route": "Vigane avalehe suunamine"
}
\ No newline at end of file
diff --git a/public/language/et/global.json b/public/language/et/global.json
index 3add6a941c..67ae319e61 100644
--- a/public/language/et/global.json
+++ b/public/language/et/global.json
@@ -7,8 +7,10 @@
"403.login": "Äkki peaksid sisse logima?",
"404.title": "Ei leitud",
"404.message": "Tundub, et lehte mida otsid, ei eksisteeri. Mine tagasi avalehele.",
- "500.title": "Süsteemi viga",
+ "500.title": "Süsteemne error.",
"500.message": "Oih! Midagi läks valesti!",
+ "400.title": "Vigane päring.",
+ "400.message": "Tundub, et see link on vigane, palun kontrolli see üle ja proovi uuesti. Võid ka minna tagasi avalehele.",
"register": "Registreeri",
"login": "Logi sisse",
"please_log_in": "Palun logi sisse",
@@ -50,9 +52,9 @@
"topics": "Teemat",
"posts": "Postitust",
"best": "Parim",
- "upvoters": "Upvoters",
+ "upvoters": "Poolt hääletajad",
"upvoted": "Kiideti heaks",
- "downvoters": "Downvoters",
+ "downvoters": "Vastu hääletajad",
"downvoted": "Hääletas vastu",
"views": "Vaatamist",
"reputation": "Reputatsioon",
@@ -93,5 +95,6 @@
"upload_file": "Lae fail üles",
"upload": "Lae üles",
"allowed-file-types": "Lubatud faili formaadid on %1",
- "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?"
+ "unsaved-changes": "Sul on salvestamata muudatusi. Oled kindel, et soovid lahkuda?",
+ "reconnecting-message": "Looks like your connection to %1 was lost, please wait while we try to reconnect."
}
\ No newline at end of file
diff --git a/public/language/et/login.json b/public/language/et/login.json
index 6c488ec5e2..0b3eb840ff 100644
--- a/public/language/et/login.json
+++ b/public/language/et/login.json
@@ -8,5 +8,5 @@
"failed_login_attempt": "Sisselogimine ebaõnnestus",
"login_successful": "Edukalt sisse logitud!",
"dont_have_account": "Pole veel kasutajat?",
- "logged-out-due-to-inactivity": "You have been logged out of the Admin Control Panel due to inactivity"
+ "logged-out-due-to-inactivity": "Sind on Administraatori Juhtpaneelist ebaaktiivsuse tõttu välja logitud"
}
\ No newline at end of file
diff --git a/public/language/et/pages.json b/public/language/et/pages.json
index 22015dadab..1b7cd02ef6 100644
--- a/public/language/et/pages.json
+++ b/public/language/et/pages.json
@@ -12,7 +12,7 @@
"users/sort-posts": "Kasutajad, kel on enim postitusi",
"users/sort-reputation": "Suurima reputatsiooniga kasutajad",
"users/banned": "Keelustatud Kasutajad",
- "users/most-flags": "Most flagged users",
+ "users/most-flags": "Enim raporteeritud kasutajad",
"users/search": "Kasutajate otsing",
"notifications": "Teated",
"tags": "Märksõnad",
@@ -29,7 +29,7 @@
"account/edit/password": "Redigeerid \"%1\" parooli",
"account/edit/username": "Redigeerid \"%1\" kasutajanime",
"account/edit/email": "Redigeerid \"%1\" emaili",
- "account/info": "Account Info",
+ "account/info": "Kasutaja info",
"account/following": "Kasutaja %1 jälgib",
"account/followers": "Kasutajad, kes jälgivad %1",
"account/posts": "Postitused, mis on tehtud kasutaja %1 poolt",
diff --git a/public/language/et/register.json b/public/language/et/register.json
index c0b7442158..11c8c1e2d0 100644
--- a/public/language/et/register.json
+++ b/public/language/et/register.json
@@ -1,6 +1,6 @@
{
"register": "Registreeri",
- "cancel_registration": "Cancel Registration",
+ "cancel_registration": "Katkesta registreerimine",
"help.email": "Algsättena peidetakse sinu e-mail avalikuse eest.",
"help.username_restrictions": "Unikaalne kasutajanimi, mis on %1 - %2 tähemärki pikk. Teised saavad sind postitustes mainida kasutades @kasutajanime.",
"help.minimum_password_length": "Sinu parooli pikkus peab olema vähemalt %1 tähemärki pikk.",
@@ -16,8 +16,8 @@
"alternative_registration": "Alternatiivne registreerimismeetod",
"terms_of_use": "Foorumi reeglid",
"agree_to_terms_of_use": "Nõustun foorumi reeglitega",
- "terms_of_use_error": "You must agree to the Terms of Use",
+ "terms_of_use_error": "Sa pead nõustuma Tingimustega",
"registration-added-to-queue": "Teie registreerimine vaadatakse üle. Te saate e-kirja kui administraator on aktsepteerinud registreermimise.",
- "interstitial.intro": "We require some additional information before we can create your account.",
- "interstitial.errors-found": "We could not complete your registration:"
+ "interstitial.intro": "Enne kasutaja loomist on meil vaja lisainfot.",
+ "interstitial.errors-found": "Meil ei õnnestunud registreerimist lõpule viia:"
}
\ No newline at end of file
diff --git a/public/language/et/topic.json b/public/language/et/topic.json
index 0e236f149d..a1012d10a4 100644
--- a/public/language/et/topic.json
+++ b/public/language/et/topic.json
@@ -26,14 +26,14 @@
"tools": "Tööriistad",
"flag": "Märgista",
"locked": "Lukustatud",
- "pinned": "Pinned",
- "moved": "Moved",
+ "pinned": "Märgistatud",
+ "moved": "Liigutatud",
"bookmark_instructions": "Vajuta siia, et tagasi minna viimati loetud postituse juurde siin teemas.",
"flag_title": "Märgista see postitus modereerimiseks",
"flag_success": "See postitus on nüüd märgistatud modereerimiseks.",
"deleted_message": "See teema on kustutatud. Ainult kasutajad kellel on piisavalt õigusi saavad seda näha.",
"following_topic.message": "Sulle ei edastata enam teateid uutest postitustest kui keegi postitab siia teemasse.",
- "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.",
+ "not_following_topic.message": "Sa näed seda postitust lugemata postituste nimekirjas, kuid sa ei näe selle kohta teateid, kui keegi sinna postitab.",
"ignoring_topic.message": "Sa ei näe seda teemat enam lugemata teemade nimekirjas. Sind teavitatakse, kui Sind mainitakse või Sinu postitust kiidetakse heaks.",
"login_to_subscribe": "Palun registreeru kasutajaks või logi sisse, et tellida teateid selle postituse kohta.",
"markAsUnreadForAll.success": "Teema märgitud mitte-loetuks kõikidele.",
@@ -86,7 +86,7 @@
"topic_will_be_moved_to": "See teema liigutatakse antud kategooriasse",
"fork_topic_instruction": "Vajuta postitustele, mida soovid forkida",
"fork_no_pids": "Sa ei ole postitusi valinud!",
- "fork_pid_count": "%1 post(s) selected",
+ "fork_pid_count": "%1 postitus(t) valitud",
"fork_success": "Edukalt ''forkisid'' teema! Vajuta siia, et vaadata loodud teemat.",
"delete_posts_instruction": "Klikka postitustel, mida tahad kustutada/puhastada",
"composer.title_placeholder": "Sisesta teema pealkiri siia...",
diff --git a/public/language/et/user.json b/public/language/et/user.json
index 81b9f5b22b..0e94b3198d 100644
--- a/public/language/et/user.json
+++ b/public/language/et/user.json
@@ -6,7 +6,7 @@
"postcount": "Postitusi",
"email": "Email",
"confirm_email": "Kinnita email",
- "account_info": "Account Info",
+ "account_info": "Kasutaja info",
"ban_account": "Bannige kasutaja",
"ban_account_confirm": "Kas te tõesti soovite antud kasutajat bannida?",
"unban_account": "Eemaldage kontolt ban",
@@ -96,8 +96,8 @@
"delay_image_loading": "Viivita pildi laadimisega",
"image_load_delay_help": "Kui lubatud, pildid teemades ei lae kuni nad on nähtavuses",
"scroll_to_my_post": "Pärast vastuse postitamist, näita uut postitust",
- "follow_topics_you_reply_to": "Watch topics that you reply to",
- "follow_topics_you_create": "Watch topics you create",
+ "follow_topics_you_reply_to": "Jälgi teemasid, millele vastad",
+ "follow_topics_you_create": "Jälgi teemasid, mille lood",
"grouptitle": "Grupi tiitel",
"no-group-title": "Grupi tiitel puudub",
"select-skin": "Vali välimus",
@@ -109,10 +109,10 @@
"sso.title": "Ühekordse sisselogimisega teenused",
"sso.associated": "Seotud koos",
"sso.not-associated": "Kliki siia, et siduda koos",
- "info.latest-flags": "Latest Flags",
- "info.no-flags": "No Flagged Posts Found",
- "info.ban-history": "Recent Ban History",
- "info.no-ban-history": "This user has never been banned",
- "info.banned-until": "Banned until %1",
- "info.banned-permanently": "Banned permanently"
+ "info.latest-flags": "Viimased raporteerimised",
+ "info.no-flags": "Raporteeritud postitusi ei leitud",
+ "info.ban-history": "Hiljutiste keeldude ajalugu",
+ "info.no-ban-history": "Seda kasutajat pole kunagi keelustatud",
+ "info.banned-until": "Keelustatud kuni %1",
+ "info.banned-permanently": "Igavesti keelustatud"
}
\ No newline at end of file
diff --git a/public/language/et/users.json b/public/language/et/users.json
index a9b23a1b38..7c5da97116 100644
--- a/public/language/et/users.json
+++ b/public/language/et/users.json
@@ -2,7 +2,7 @@
"latest_users": "Hilised kasutajad",
"top_posters": "Top postitajad",
"most_reputation": "Kõige rohkem reputatsiooni",
- "most_flags": "Most Flags",
+ "most_flags": "Enim raporteerimisi",
"search": "Otsi",
"enter_username": "Sisesta kasutajanimi, keda soovid otsida",
"load_more": "Lae veel",
diff --git a/public/language/fa_IR/global.json b/public/language/fa_IR/global.json
index ce48647e40..7c7e92772d 100644
--- a/public/language/fa_IR/global.json
+++ b/public/language/fa_IR/global.json
@@ -7,8 +7,10 @@
"403.login": "شاید باید وارد شوید؟",
"404.title": "یافت نشد",
"404.message": "به نظر میاید شما به صفحه ای برخورد کرده اید که وجود ندارد. بازگشت به صفحه ی خانه",
- "500.title": "خطای درونی.",
+ "500.title": "خطای داخلی.",
"500.message": "اوه! گویا اشتباهی رخ داده!",
+ "400.title": "درخواست بد.",
+ "400.message": "به نظر میرسد که این پیوند مشکل دارد، لطفا دوباره بررسی کنید که این پیوند صحیح است و دوباره تلاش کنید، در غیر اینصورت به صفحه اصلی بازگردید.",
"register": "نامنویسی",
"login": "درون آمدن",
"please_log_in": "لطفا به درون بیایید",
@@ -93,5 +95,6 @@
"upload_file": "بارگذاری فایل",
"upload": "بارگذاری",
"allowed-file-types": "فایل قابل قبول اینها هستند %1",
- "unsaved-changes": "تغییرات شما ذخیره نشده. شما مطمئن هستید که میخواهید از اینجا دور شوید؟"
+ "unsaved-changes": "تغییرات شما ذخیره نشده. شما مطمئن هستید که میخواهید از اینجا دور شوید؟",
+ "reconnecting-message": "Looks like your connection to %1 was lost, please wait while we try to reconnect."
}
\ No newline at end of file
diff --git a/public/language/fi/global.json b/public/language/fi/global.json
index 8488b07bfe..434aece0f3 100644
--- a/public/language/fi/global.json
+++ b/public/language/fi/global.json
@@ -7,8 +7,10 @@
"403.login": "Sinun pitäisi kai kirjautua sisään?",
"404.title": "Ei löydy",
"404.message": "Olet päätynyt sivulle, jota ei ole olemassa. Palaa etusivulle.",
- "500.title": "Sisäinen virhe.",
+ "500.title": "Internal Error.",
"500.message": "Oho! Jotain meni pieleen!",
+ "400.title": "Bad Request.",
+ "400.message": "It looks like this link is malformed, please double-check and try again. Otherwise, return to the home page.",
"register": "Rekisteröidy",
"login": "Kirjaudu",
"please_log_in": "Kirjaudu, ole hyvä",
@@ -93,5 +95,6 @@
"upload_file": "Upload file",
"upload": "Upload",
"allowed-file-types": "Allowed file types are %1",
- "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?"
+ "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?",
+ "reconnecting-message": "Looks like your connection to %1 was lost, please wait while we try to reconnect."
}
\ No newline at end of file
diff --git a/public/language/fr/global.json b/public/language/fr/global.json
index 10b70a2148..a37d6fa925 100644
--- a/public/language/fr/global.json
+++ b/public/language/fr/global.json
@@ -7,8 +7,10 @@
"403.login": "Peut-être deviez vous essayer de vous connecter?",
"404.title": "Introuvable",
"404.message": "Il semble que vous ayez atteint une page qui n'existe pas. Retourner à la page d'accueil.",
- "500.title": "Erreur interne.",
+ "500.title": "Erreur Interne.",
"500.message": "Oops ! Il semblerait que quelque chose se soit mal passé !",
+ "400.title": "Requête erronée.",
+ "400.message": "Il semble que ce lien ne soit pas correct, merci de le vérifier. Sinon, retournez à la page d'accueil.",
"register": "S'inscrire",
"login": "Se connecter",
"please_log_in": "Veuillez vous connecter",
@@ -93,5 +95,6 @@
"upload_file": "Envoyer un fichier",
"upload": "Envoyer",
"allowed-file-types": "Les types de fichiers autorisés sont : %1",
- "unsaved-changes": "Vous avez des modifications non sauvegardées. Êtes-vous sûr de vouloir naviguer tout de même ?"
+ "unsaved-changes": "Vous avez des modifications non sauvegardées. Êtes-vous sûr de vouloir naviguer tout de même ?",
+ "reconnecting-message": "Il semble que votre connexion ait été perdue, veuillez patienter pendant que nous vous re-connectons."
}
\ No newline at end of file
diff --git a/public/language/gl/category.json b/public/language/gl/category.json
index eb12b9660e..aeafc9f8e0 100644
--- a/public/language/gl/category.json
+++ b/public/language/gl/category.json
@@ -14,7 +14,7 @@
"ignoring": "Ignorando",
"watching.description": "Amosa-los temas en \"non lidos\"",
"ignoring.description": "Non amosa-los temas en \"non lidos\"",
- "watch.message": "Agora Sigues as novidades desta categoría",
- "ignore.message": "Agora ignoras as novidades nesta categoría",
+ "watch.message": "Agora segues as novidades desta categoría.",
+ "ignore.message": "Agora ignoras as novidades nesta categoría.",
"watched-categories": "Categorías vixiadas"
}
\ No newline at end of file
diff --git a/public/language/gl/error.json b/public/language/gl/error.json
index d7cf7fa7da..d372ec2b2e 100644
--- a/public/language/gl/error.json
+++ b/public/language/gl/error.json
@@ -2,13 +2,13 @@
"invalid-data": "Datos non válidos",
"not-logged-in": "Parece que estás desconectado.",
"account-locked": "A túa conta foi bloqueada temporalmente.",
- "search-requires-login": "As buscas requiren unha conta - por favor inicia sesión ou rexístrate.",
+ "search-requires-login": "As buscas requiren unha conta. Por favor inicia sesión ou rexístrate.",
"invalid-cid": "Identificador de Categoría Inválido ",
"invalid-tid": "Identificador de Tema Inválido",
"invalid-pid": "Identificador de Publicación Inválido",
"invalid-uid": "Identificador de Usuario Inválido",
"invalid-username": "Nome de Usuario Inválido",
- "invalid-email": "Correo electrónico inválido",
+ "invalid-email": "Enderezo electrónico inválido",
"invalid-title": "Título inválido!",
"invalid-user-data": "Datos de Usuario Inválidos",
"invalid-password": "Contrasinal Inválido",
@@ -17,12 +17,12 @@
"csrf-invalid": "Non fomos capaces de entrar, probablemente debido a que a sesión expirou. Por favor, téntao de novo",
"invalid-pagination-value": "Valor de paxinación incorreto, ten que estar entre %1 e %2",
"username-taken": "Nome de usuario en uso",
- "email-taken": "Correo en uso",
+ "email-taken": "Enderezo electrónico en uso",
"email-not-confirmed": "O teu correo aínda non está confirmado, por favor pica aquí para confirmalo.",
"email-not-confirmed-chat": "Non podes charlar ata que confirmes o teu correo, por favor pica aquí para confirmalo.",
- "email-not-confirmed-email-sent": "O teu correo electrónico está sen confirmar. Por favor, busca o correo de confirmación na túa bandexa de entrada.",
- "no-email-to-confirm": "Este foro require confirmación de correo, por favor pica aquí para introducir un correo.",
- "email-confirm-failed": "Non podemos confirmar o teu correo, por favor téntao de novo máis tarde.",
+ "email-not-confirmed-email-sent": "O teu enderezo electrónico está sen confirmar. Por favor, busca o correo de confirmación na túa bandexa de entrada.",
+ "no-email-to-confirm": "O foro require confirmación de enderezo electrónico, por favor pica aquí para engadir un.",
+ "email-confirm-failed": "Non podemos confirmar o teu enderezo, por favor téntao de novo máis tarde.",
"confirm-email-already-sent": "O correo de confirmación foi enviado, agarda %1 minute(s) para enviar outro.",
"sendmail-not-found": "Non se atopa o executable \"sendmail\", por favor, asegúrate de que está instalado no teu sistema e que é accesible polo usuario que executa NodeBB. ",
"username-too-short": "Nome de usuario demasiado curto",
diff --git a/public/language/gl/global.json b/public/language/gl/global.json
index 8d1301e078..0f8663d96f 100644
--- a/public/language/gl/global.json
+++ b/public/language/gl/global.json
@@ -7,8 +7,10 @@
"403.login": "Quizais deberías tentar iniciar sesión?",
"404.title": "Non Atopado",
"404.message": "Ao parecer, esta páxina non existe. Volver ao Inicio.",
- "500.title": "Erro interno.",
+ "500.title": "Internal Error.",
"500.message": "Ups! Parece que algo saíu mal!",
+ "400.title": "Bad Request.",
+ "400.message": "It looks like this link is malformed, please double-check and try again. Otherwise, return to the home page.",
"register": "Rexistrarse",
"login": "Conectarse",
"please_log_in": "Por favor, conéctate",
@@ -93,5 +95,6 @@
"upload_file": "Subir arquivo ",
"upload": "Subir",
"allowed-file-types": "Os tipos de arquivos permitidos son: %1",
- "unsaved-changes": "Non gardaches tódolos cambios. Queres continuar e saír da páxina?"
+ "unsaved-changes": "Non gardaches tódolos cambios. Queres continuar e saír da páxina?",
+ "reconnecting-message": "Looks like your connection to %1 was lost, please wait while we try to reconnect."
}
\ No newline at end of file
diff --git a/public/language/gl/notifications.json b/public/language/gl/notifications.json
index deeb2835a5..326680a2fd 100644
--- a/public/language/gl/notifications.json
+++ b/public/language/gl/notifications.json
@@ -15,7 +15,7 @@
"upvoted_your_post_in_dual": "%1 e %2 votaron positivamente a túa mensaxe en %3.",
"upvoted_your_post_in_multiple": "%1 e %2 máis votaron positivamente a túa mensaxe en %3.",
"moved_your_post": "%1 moveu a túa publicación a%2",
- "moved_your_topic": "%1 foi movido %2",
+ "moved_your_topic": "%1 moveu %2",
"user_flagged_post_in": "%1 reportou unha mensaxe en %2",
"user_flagged_post_in_dual": "%1 e %2 reportaron a túa mensaxe en %3",
"user_flagged_post_in_multiple": "%1 e outras %2 persoas reportaron unha mensaxe en %3",
diff --git a/public/language/he/global.json b/public/language/he/global.json
index 6e76c19ea3..e6b0d8e31b 100644
--- a/public/language/he/global.json
+++ b/public/language/he/global.json
@@ -7,8 +7,10 @@
"403.login": "נסה להתחבר.",
"404.title": "לא נמצא",
"404.message": "נראה שהגעת לעמוד שלא קיים. חזור לעמוד הבית",
- "500.title": "שגיאה פנימית.",
+ "500.title": "Internal Error.",
"500.message": "אופס! נראה שמשהו השתבש!",
+ "400.title": "Bad Request.",
+ "400.message": "It looks like this link is malformed, please double-check and try again. Otherwise, return to the home page.",
"register": "הרשמה",
"login": "התחברות",
"please_log_in": "אנא התחבר",
@@ -93,5 +95,6 @@
"upload_file": "העלה קובץ",
"upload": "העלה",
"allowed-file-types": "פורמטי הקבצים המורשים הם %1",
- "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?"
+ "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?",
+ "reconnecting-message": "Looks like your connection to %1 was lost, please wait while we try to reconnect."
}
\ No newline at end of file
diff --git a/public/language/hu/global.json b/public/language/hu/global.json
index b7f0edef28..1aae7c960b 100644
--- a/public/language/hu/global.json
+++ b/public/language/hu/global.json
@@ -7,8 +7,10 @@
"403.login": "Talán meg kellene próbálnod belépni?",
"404.title": "Nincs találat",
"404.message": "Úgy tűnik, hogy rábukkantál egy olyan oldalra ami nem létezik. Visszatérés a kezdőlapra",
- "500.title": "Belső hiba.",
+ "500.title": "Internal Error.",
"500.message": "Hoppá! Úgy tűnik valami hiba történt!",
+ "400.title": "Bad Request.",
+ "400.message": "It looks like this link is malformed, please double-check and try again. Otherwise, return to the home page.",
"register": "Regisztráció",
"login": "Belépés",
"please_log_in": "Jelentkezzünk be",
@@ -93,5 +95,6 @@
"upload_file": "Upload file",
"upload": "Upload",
"allowed-file-types": "Allowed file types are %1",
- "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?"
+ "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?",
+ "reconnecting-message": "Looks like your connection to %1 was lost, please wait while we try to reconnect."
}
\ No newline at end of file
diff --git a/public/language/id/global.json b/public/language/id/global.json
index aac14e74d7..313a120729 100644
--- a/public/language/id/global.json
+++ b/public/language/id/global.json
@@ -7,8 +7,10 @@
"403.login": "Mungkin kamu harus mencoba untuk login?",
"404.title": "Tidak ditemukan",
"404.message": "Kamu kelihatan mengakses halaman yang tidak ada. Kembali ke beranda.",
- "500.title": "Kesalahan internal",
+ "500.title": "Internal Error.",
"500.message": "Oops! Terjadi kesalahan",
+ "400.title": "Bad Request.",
+ "400.message": "It looks like this link is malformed, please double-check and try again. Otherwise, return to the home page.",
"register": "Daftar",
"login": "Login",
"please_log_in": "Silakan Log In",
@@ -93,5 +95,6 @@
"upload_file": "Upload file",
"upload": "Upload",
"allowed-file-types": "Allowed file types are %1",
- "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?"
+ "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?",
+ "reconnecting-message": "Looks like your connection to %1 was lost, please wait while we try to reconnect."
}
\ No newline at end of file
diff --git a/public/language/it/email.json b/public/language/it/email.json
index ef28eac56e..f30f93b9f5 100644
--- a/public/language/it/email.json
+++ b/public/language/it/email.json
@@ -5,8 +5,8 @@
"greeting_no_name": "Ciao",
"greeting_with_name": "Ciao %1",
"welcome.text1": "Grazie per esserti registrato su %1!",
- "welcome.text2": "Per attivare completamente il tuo account dobbiamo verificare che sei il proprietario dell'indiritto email con cui ti sei registrato.",
- "welcome.text3": "Un Amministratora ha accettato la tua registrazione. Puoi adesso collegarti con il tuo nome utente e la tua password.",
+ "welcome.text2": "Per attivare completamente il tuo account dobbiamo verificare che sei il proprietario dell'indirizzo email con cui ti sei registrato.",
+ "welcome.text3": "Un Amministratora ha accettato la tua registrazione. Adesso puoi collegarti con il tuo nome utente/ password.",
"welcome.cta": "Clicca qui per confermare il tuo indirizzo email",
"invitation.text1": "%1 ti ha invitato a entrare in %2",
"invitation.ctr": "Clicca qui per creare il tuo account.",
@@ -17,18 +17,18 @@
"reset.notify.text1": "Ti informiamo che in data %1, la password è stata cambiata con successo.",
"reset.notify.text2": "Se non hai autorizzato questo, per favore notifica immediatamente un amministratore.",
"digest.notifications": "Hai una notifica non letta da %1:",
- "digest.latest_topics": "Ultimi argomenti su %1",
+ "digest.latest_topics": "Ultime discussioni su %1",
"digest.cta": "Clicca qui per visitare %1",
"digest.unsub.info": "Questo sommario ti è stato inviato perché lo hai sottoscritto nelle tue impostazioni.",
"digest.no_topics": "Non ci sono state discussioni attive nell'ultimo %1",
"digest.day": "giorno",
"digest.week": "settimana",
"digest.month": "mese",
- "digest.subject": "Digest for %1",
+ "digest.subject": "Sommario per %1",
"notif.chat.subject": "Nuovo messaggio in chat da %1",
"notif.chat.cta": "Clicca qui per continuare la conversazione",
"notif.chat.unsub.info": "Questa notifica di chat ti è stata inviata perché l'hai scelta nelle impostazioni.",
- "notif.post.cta": "Clicca qui per leggere il topic completo.",
+ "notif.post.cta": "Clicca qui per leggere la discussione completa",
"notif.post.unsub.info": "Questo post ti è stato notificato in base alle tue impostazioni di sottoscrizione.",
"test.text1": "Questa è una email di test per verificare che il servizio di invio email è configurato correttamente sul tuo NodeBB.",
"unsub.cta": "Clicca qui per modificare queste impostazioni",
diff --git a/public/language/it/error.json b/public/language/it/error.json
index 23b0710512..4412fbc484 100644
--- a/public/language/it/error.json
+++ b/public/language/it/error.json
@@ -24,16 +24,16 @@
"no-email-to-confirm": "Questo forum richiede la conferma dell'indirizzo email, per favore clicca qui per inserirne uno",
"email-confirm-failed": "Non possiamo confermare la tua email, per favore prova ancora più tardi.",
"confirm-email-already-sent": "Email di conferma già inviata, per favore attendere %1 minuti per richiederne un'altra.",
- "sendmail-not-found": "The sendmail executable could not be found, please ensure it is installed and executable by the user running NodeBB.",
+ "sendmail-not-found": "Non è stato possibile trovare l'eseguibile sendmail, per favore assicurati che sia installato ed eseguibile dall'utente su cui è installato NodeBB.",
"username-too-short": "Nome utente troppo corto",
"username-too-long": "Nome utente troppo lungo",
"password-too-long": "Password troppo lunga",
"user-banned": "Utente bannato",
"user-too-new": "Devi attendere %1 secondi prima di creare il tuo primo post",
- "blacklisted-ip": "Sorry, your IP address has been banned from this community. If you feel this is in error, please contact an administrator.",
- "ban-expiry-missing": "Please provide an end date for this ban",
+ "blacklisted-ip": "Purtroppo il tuo indirizzo IP è stato bannato da questa community. Se credi che ci sia stato un errore contatta un amministratore.",
+ "ban-expiry-missing": "Per favore fornisci una data finale per questo ban",
"no-category": "La Categoria non esiste",
- "no-topic": "Il Topic non esiste",
+ "no-topic": "La discussione non esiste",
"no-post": "Il Post non esiste",
"no-group": "Il Gruppo non esiste",
"no-user": "L'User non esiste",
@@ -42,21 +42,21 @@
"category-disabled": "Categoria disabilitata",
"topic-locked": "Discussione Bloccata",
"post-edit-duration-expired": "Ti è consentito modificare un post per %1 secondi dopo averlo inviato",
- "post-edit-duration-expired-minutes": "You are only allowed to edit posts for %1 minute(s) after posting",
- "post-edit-duration-expired-minutes-seconds": "You are only allowed to edit posts for %1 minute(s) %2 second(s) after posting",
- "post-edit-duration-expired-hours": "You are only allowed to edit posts for %1 hour(s) after posting",
- "post-edit-duration-expired-hours-minutes": "You are only allowed to edit posts for %1 hour(s) %2 minute(s) after posting",
- "post-edit-duration-expired-days": "You are only allowed to edit posts for %1 day(s) after posting",
- "post-edit-duration-expired-days-hours": "You are only allowed to edit posts for %1 day(s) %2 hour(s) after posting",
- "post-delete-duration-expired": "You are only allowed to delete posts for %1 second(s) after posting",
- "post-delete-duration-expired-minutes": "You are only allowed to delete posts for %1 minute(s) after posting",
- "post-delete-duration-expired-minutes-seconds": "You are only allowed to delete posts for %1 minute(s) %2 second(s) after posting",
- "post-delete-duration-expired-hours": "You are only allowed to delete posts for %1 hour(s) after posting",
- "post-delete-duration-expired-hours-minutes": "You are only allowed to delete posts for %1 hour(s) %2 minute(s) after posting",
- "post-delete-duration-expired-days": "You are only allowed to delete posts for %1 day(s) after posting",
- "post-delete-duration-expired-days-hours": "You are only allowed to delete posts for %1 day(s) %2 hour(s) after posting",
- "cant-delete-topic-has-reply": "You can't delete your topic after it has a reply",
- "cant-delete-topic-has-replies": "You can't delete your topic after it has %1 replies",
+ "post-edit-duration-expired-minutes": "Ti è permesso modificare i post solo per %1 minuto(i) dopo averli inviati",
+ "post-edit-duration-expired-minutes-seconds": "Ti è permesso modificare i post solo per %1 minuto(i) %secondo(i) dopo averli inviati",
+ "post-edit-duration-expired-hours": "Ti è permesso modificare i post solo per %1 ora(e) dopo averli inviati",
+ "post-edit-duration-expired-hours-minutes": "Ti è permesso modificare i post solo per %1 ora(e) %2 minuto(i) dopo averli inviati",
+ "post-edit-duration-expired-days": "Ti è permesso modificare i post solo per %1 giorno(i) dopo averli inviati",
+ "post-edit-duration-expired-days-hours": "Ti è permesso modificare i post solo per %1 giorno(i) %2 ora(e) dopo averli inviati",
+ "post-delete-duration-expired": "Ti è permesso eliminare i post solo per %1 secondo(i) dopo averli inviati",
+ "post-delete-duration-expired-minutes": "Ti è permesso eliminare i post solo per %1 minuto(i) dopo averli inviati",
+ "post-delete-duration-expired-minutes-seconds": "Ti è permesso eliminare i post solo per %1 minuto(i) %secondo(i) dopo averli inviati",
+ "post-delete-duration-expired-hours": "Ti è permesso eliminare i post solo per %1 ora(e) dopo averli inviati",
+ "post-delete-duration-expired-hours-minutes": "Ti è permesso eliminare i post solo per %1 giorno(i) %2 ora(e) dopo averli inviati",
+ "post-delete-duration-expired-days": "Ti è permesso eliminare i post solo per %1 giorno(i) dopo averli inviati",
+ "post-delete-duration-expired-days-hours": "Ti è permesso eliminare i post solo per %1 giorno(i) %2 ora(e) dopo averli inviati",
+ "cant-delete-topic-has-reply": "Non puoi eliminare la tua discussione se ha una risposta",
+ "cant-delete-topic-has-replies": "Non puoi eliminare la tua discussione se ha %1 risposte",
"content-too-short": "Inserisci un testo più lungo. Il messaggio deve contenere almeno %1 caratteri.",
"content-too-long": "Inserisci un post più breve. I post non possono essere più lunghi di %1 caratteri.",
"title-too-short": "Inserisci un titolo più lungo. I titoli devono contenere almeno %1 caratteri.",
@@ -65,31 +65,31 @@
"too-many-posts-newbie": "Come nuovo utente puoi postare solamente una volta ogni %1 secondi finché non hai raggiunto un livello di reputazione %2 - per favore attendi prima di scrivere ancora",
"tag-too-short": "Inserisci un tag più lungo. I tag devono contenere almeno %1 caratteri.",
"tag-too-long": "Per favore inserisci un tag più corto. I tags non dovrebbero essere più lunghi di %1 caratteri",
- "not-enough-tags": "Tag non sufficienti. Gli argomenti devono avere almeno %1 Tag",
- "too-many-tags": "Troppi Tag. Gli argomenti non possono avere più di %1 Tag",
+ "not-enough-tags": "Tag non sufficienti. Le discussioni devono avere almeno %1 Tag",
+ "too-many-tags": "Troppi Tag. Le discussioni non possono avere più di %1 Tag",
"still-uploading": "Per favore attendere il completamento degli uploads.",
"file-too-big": "La dimensione massima consentita è di %1 kB - si prega di caricare un file più piccolo",
- "guest-upload-disabled": "Guest uploading has been disabled",
- "already-favourited": "You have already bookmarked this post",
- "already-unfavourited": "You have already unbookmarked this post",
+ "guest-upload-disabled": "Il caricamento da ospite è stato disattivato",
+ "already-favourited": "Hai già aggiunto questo post ai favoriti",
+ "already-unfavourited": "Hai già tolto questo post dai favoriti",
"cant-ban-other-admins": "Non puoi bannare altri amministratori!",
"cant-remove-last-admin": "Sei l'unico Amministratore. Aggiungi un altro amministratore prima di rimuovere il tuo ruolo",
- "cant-delete-admin": "Remove administrator privileges from this account before attempting to delete it.",
+ "cant-delete-admin": "Togli i privilegi amministrativi da questo account prima di provare ad eliminarlo.",
"invalid-image-type": "Tipo dell'immagine non valido. I tipi permessi sono: %1",
"invalid-image-extension": "Estensione immagine non valida",
"invalid-file-type": "Tipo di file non valido. I formati consentiti sono: %1",
"group-name-too-short": "Nome del Gruppo troppo corto",
- "group-name-too-long": "Group name too long",
+ "group-name-too-long": "Il nome del gruppo è troppo lungo",
"group-already-exists": "Il Gruppo esiste già",
"group-name-change-not-allowed": "Il cambio di nome al Gruppo non è consentito",
- "group-already-member": "Already part of this group",
- "group-not-member": "Not a member of this group",
+ "group-already-member": "Fa già parte di questo gruppo",
+ "group-not-member": "Non è membro di questo gruppo",
"group-needs-owner": "Questo gruppo richiede almeno un proprietario.",
"group-already-invited": "Questo utente è già stato invitato",
"group-already-requested": "La tua richiesta di partecipazione è già stata inviata",
"post-already-deleted": "Questo Post è già stato cancellato",
"post-already-restored": "Questo Post è già stato ripristinato",
- "topic-already-deleted": "Questo Topic è già stato cancellato",
+ "topic-already-deleted": "Questo topic è già stato eliminato",
"topic-already-restored": "Questo Topic è già stato ripristinato",
"cant-purge-main-post": "Non puoi svuotare il primo messaggio, elimina invece l'intera discussione",
"topic-thumbnails-are-disabled": "Le anteprime della Discussione sono disabilitate.",
@@ -99,14 +99,14 @@
"about-me-too-long": "Spiacenti, il testo non può essere più lungo di %1 caratteri.",
"cant-chat-with-yourself": "Non puoi chattare con te stesso!",
"chat-restricted": "Questo utente ha ristretto i suoi messaggi in chat alle persone che segue. Per poter chattare con te ti deve prima seguire.",
- "chat-disabled": "Chat system disabled",
+ "chat-disabled": "Il sistema di chat è stato disabilitato",
"too-many-messages": "Hai inviato troppi messaggi, aspetta un attimo.",
"invalid-chat-message": "Messaggio chat non valido",
"chat-message-too-long": "Il messaggio chat è troppo lungo",
- "cant-edit-chat-message": "You are not allowed to edit this message",
- "cant-remove-last-user": "You can't remove the last user",
- "cant-delete-chat-message": "You are not allowed to delete this message",
- "already-voting-for-this-post": "You have already voted for this post.",
+ "cant-edit-chat-message": "Non ti è permesso di modificare questo messaggio",
+ "cant-remove-last-user": "Non puoi rimuovere l'ultimo utente",
+ "cant-delete-chat-message": "Non ti è permesso di eliminare questo messaggio",
+ "already-voting-for-this-post": "Hai già votato per questo post",
"reputation-system-disabled": "Il sistema di reputazione è disabilitato.",
"downvoting-disabled": "Il Downvoting è disabilitato",
"not-enough-reputation-to-downvote": "Non hai i privilegi per votare negativamente questo post",
@@ -117,11 +117,11 @@
"parse-error": "Qualcosa è andato storto durante l'analisi della risposta proveniente dal server",
"wrong-login-type-email": "Per favore usa la tua email per accedere",
"wrong-login-type-username": "Per favore usa il tuo nome utente per accedere",
- "invite-maximum-met": "You have invited the maximum amount of people (%1 out of %2).",
- "no-session-found": "No login session found!",
- "not-in-room": "User not in room",
- "no-users-in-room": "No users in this room",
- "cant-kick-self": "You can't kick yourself from the group",
- "no-users-selected": "No user(s) selected",
- "invalid-home-page-route": "Invalid home page route"
+ "invite-maximum-met": "Hai invitato il massimo numero di persone possibili (%1 su %2).",
+ "no-session-found": "Nessuna sessione valida di login trovata!",
+ "not-in-room": "L'utente non è in questa stanza",
+ "no-users-in-room": "Nessun utente in questa stanza",
+ "cant-kick-self": "Non puoi espellerti dal gruppo",
+ "no-users-selected": "Nessun utente selezionato",
+ "invalid-home-page-route": "Percorso della pagina iniziale non valido"
}
\ No newline at end of file
diff --git a/public/language/it/global.json b/public/language/it/global.json
index b20daeef18..f35e9b5791 100644
--- a/public/language/it/global.json
+++ b/public/language/it/global.json
@@ -9,6 +9,8 @@
"404.message": "Sembra tu sia arrivato ad una pagina che non esiste. Torna alla home page.",
"500.title": "Errore interno.",
"500.message": "Oops! Qualcosa non funziona come si deve!",
+ "400.title": "Bad Request.",
+ "400.message": "Sembra che questo link sia stato mal formulato, per favore ricontrolla e riprova. Altrimenti ritorna alla home page.",
"register": "Registrazione",
"login": "Login",
"please_log_in": "Per favore Accedi",
@@ -49,9 +51,9 @@
"users": "Utenti",
"topics": "Discussioni",
"posts": "Post",
- "best": "Best",
+ "best": "Migliore",
"upvoters": "Upvoters",
- "upvoted": "Upvoted",
+ "upvoted": "Apprezzati",
"downvoters": "Downvoters",
"downvoted": "Downvoted",
"views": "Visualizzazioni",
@@ -61,15 +63,15 @@
"posted_ago_by_guest": "scritto %1 di Ospite",
"posted_ago_by": "scritto %1 di %2",
"posted_ago": "postato %1",
- "posted_in": "posted in %1",
- "posted_in_by": "posted in %1 by %2",
+ "posted_in": "postato in %1",
+ "posted_in_by": "postato in %1 da %2",
"posted_in_ago": "postato in %1 %2",
"posted_in_ago_by": "postato in %1 %2 da %3",
"user_posted_ago": "%1 ha postato %2",
"guest_posted_ago": "Ospite ha scritto %1",
- "last_edited_by": "last edited by %1",
+ "last_edited_by": "ultima modifica di %1",
"norecentposts": "Nessun Post Recente",
- "norecenttopics": "Nessun Argomento Recente",
+ "norecenttopics": "Nessuna Discussione Recente",
"recentposts": "Post Recenti",
"recentips": "Indirizzi IP Recentemente Loggati",
"away": "Non disponibile",
@@ -87,11 +89,12 @@
"unfollow": "Non seguire",
"delete_all": "Elimina Tutto",
"map": "Mappa",
- "sessions": "Login Sessions",
- "ip_address": "IP Address",
- "enter_page_number": "Enter page number",
- "upload_file": "Upload file",
- "upload": "Upload",
- "allowed-file-types": "Allowed file types are %1",
- "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?"
+ "sessions": "Sessioni di Login",
+ "ip_address": "Indirizzo IP",
+ "enter_page_number": "Inserisci il numero della pagina",
+ "upload_file": "Carica file",
+ "upload": "Carica",
+ "allowed-file-types": "Le estensioni permesse dei file sono %1",
+ "unsaved-changes": "Hai delle modifiche non salvate. Sei sicuro che vuoi lasciare la pagina?",
+ "reconnecting-message": "Looks like your connection to %1 was lost, please wait while we try to reconnect."
}
\ No newline at end of file
diff --git a/public/language/it/groups.json b/public/language/it/groups.json
index ca2d7f898a..45cc2d894b 100644
--- a/public/language/it/groups.json
+++ b/public/language/it/groups.json
@@ -24,7 +24,7 @@
"details.has_no_posts": "I membri di questo gruppo non hanno ancora postato.",
"details.latest_posts": "Ultimi Post",
"details.private": "Privato",
- "details.disableJoinRequests": "Disable join requests",
+ "details.disableJoinRequests": "Disabilita le richieste d'adesione",
"details.grant": "Concedi / Rimuovi la Proprietà",
"details.kick": "Espelli",
"details.owner_options": "Amministratore del Grupo",
@@ -41,7 +41,7 @@
"details.hidden": "Nascosto",
"details.hidden_help": "Se abilitato, questo gruppo non sarà visibile nella lista dei gruppi e gli utenti dovranno essere invitati manualmente",
"details.delete_group": "Elimina il Gruppo",
- "details.private_system_help": "Private groups is disabled at system level, this option does not do anything",
+ "details.private_system_help": "I gruppi privati sono disabilitati dal livello del sistema, questa opzione non fa nulla",
"event.updated": "I dettagli del Gruppo sono stati aggiornati",
"event.deleted": "Il gruppo \"%1\" è stato eliminato",
"membership.accept-invitation": "Accetta l'invito",
@@ -50,5 +50,5 @@
"membership.leave-group": "Lascia il Gruppo",
"membership.reject": "Rifiuta",
"new-group.group_name": "Nome Gruppo:",
- "upload-group-cover": "Upload group cover"
+ "upload-group-cover": "Carica copertina del gruppo"
}
\ No newline at end of file
diff --git a/public/language/it/login.json b/public/language/it/login.json
index 3c875d4195..1561a8484b 100644
--- a/public/language/it/login.json
+++ b/public/language/it/login.json
@@ -5,8 +5,8 @@
"remember_me": "Ricordami?",
"forgot_password": "Password dimenticata?",
"alternative_logins": "Accessi Alternativi",
- "failed_login_attempt": "Login Unsuccessful",
+ "failed_login_attempt": "Tentativo di accesso fallito",
"login_successful": "Sei entrato con successo!",
"dont_have_account": "Non hai un account?",
- "logged-out-due-to-inactivity": "You have been logged out of the Admin Control Panel due to inactivity"
+ "logged-out-due-to-inactivity": "Sei stato disconnesso dal Pannello di Controllo Amministratore per inattività"
}
\ No newline at end of file
diff --git a/public/language/it/modules.json b/public/language/it/modules.json
index d18485ef7d..2eaf84aba9 100644
--- a/public/language/it/modules.json
+++ b/public/language/it/modules.json
@@ -6,9 +6,9 @@
"chat.user_typing": "%1 sta scrivendo...",
"chat.user_has_messaged_you": "%1 ti ha scritto.",
"chat.see_all": "Vedi tutte le chat",
- "chat.mark_all_read": "Mark all chats read",
+ "chat.mark_all_read": "Segna tutti i messaggi come già letti",
"chat.no-messages": "Si prega di selezionare un destinatario per vedere la cronologia dei messaggi",
- "chat.no-users-in-room": "No users in this room",
+ "chat.no-users-in-room": "Nessun utente in questa stanza",
"chat.recent-chats": "Chat Recenti",
"chat.contacts": "Contatti",
"chat.message-history": "Cronologia Messaggi",
@@ -17,9 +17,9 @@
"chat.seven_days": "7 Giorni",
"chat.thirty_days": "30 Giorni",
"chat.three_months": "3 Mesi",
- "chat.delete_message_confirm": "Are you sure you wish to delete this message?",
+ "chat.delete_message_confirm": "Sei sicuro di voler eliminare questo messaggio?",
"chat.roomname": "Chat Room %1",
- "chat.add-users-to-room": "Add users to room",
+ "chat.add-users-to-room": "Aggiungi utenti alla stanza",
"composer.compose": "Componi",
"composer.show_preview": "Visualizza Anteprima",
"composer.hide_preview": "Nascondi Anteprima",
@@ -28,20 +28,20 @@
"composer.discard": "Sei sicuro di voler scartare questo post?",
"composer.submit_and_lock": "Invia e Blocca",
"composer.toggle_dropdown": "Mostra/Nascondi menu a discesa",
- "composer.uploading": "Uploading %1",
- "composer.formatting.bold": "Bold",
- "composer.formatting.italic": "Italic",
- "composer.formatting.list": "List",
+ "composer.uploading": "Caricamento %1",
+ "composer.formatting.bold": "Grassetto",
+ "composer.formatting.italic": "Corsivo",
+ "composer.formatting.list": "Lista",
"composer.formatting.strikethrough": "Strikethrough",
- "composer.formatting.link": "Link",
- "composer.formatting.picture": "Picture",
- "composer.upload-picture": "Upload Image",
- "composer.upload-file": "Upload File",
+ "composer.formatting.link": "Collegamento",
+ "composer.formatting.picture": "Immagine",
+ "composer.upload-picture": "Carica immagine",
+ "composer.upload-file": "Carica file",
"composer.zen_mode": "Zen Mode",
"bootbox.ok": "OK",
"bootbox.cancel": "Annulla",
"bootbox.confirm": "Conferma",
- "cover.dragging_title": "Cover Photo Positioning",
- "cover.dragging_message": "Drag the cover photo to the desired position and click \"Save\"",
- "cover.saved": "Cover photo image and position saved"
+ "cover.dragging_title": "Posizionando la foto copertina",
+ "cover.dragging_message": "Trascina l'immagine di copertina nella posizione desiderata e clicca su \"Salva\"",
+ "cover.saved": "Immagine di copertina e posizione salvati"
}
\ No newline at end of file
diff --git a/public/language/it/notifications.json b/public/language/it/notifications.json
index bd224b2cea..82fa25deec 100644
--- a/public/language/it/notifications.json
+++ b/public/language/it/notifications.json
@@ -5,29 +5,29 @@
"mark_all_read": "Segna tutte le notifiche come già lette",
"back_to_home": "Indietro a %1",
"outgoing_link": "Link in uscita",
- "outgoing_link_message": "You are now leaving %1",
+ "outgoing_link_message": "Stai lasciando %1",
"continue_to": "Continua a %1",
"return_to": "Ritorna a %1",
"new_notification": "Nuova Notifica",
"you_have_unread_notifications": "Hai notifiche non lette.",
"new_message_from": "Nuovo messaggio da %1",
"upvoted_your_post_in": "%1 ha votato positivamente il tuo post in %2.",
- "upvoted_your_post_in_dual": "%1 and %2 have upvoted your post in %3.",
- "upvoted_your_post_in_multiple": "%1 and %2 others have upvoted your post in %3.",
- "moved_your_post": "%1 has moved your post to %2",
- "moved_your_topic": "%1 has moved %2",
+ "upvoted_your_post_in_dual": "%1 e %2 hanno apprezzato il tuo post in %3.",
+ "upvoted_your_post_in_multiple": "%1 ed altri %2 hanno apprezzato il tuo post in %3.",
+ "moved_your_post": "%1 ha spostato il tuo post su %2",
+ "moved_your_topic": "%1 è stato spostato %2",
"user_flagged_post_in": "%1 ha segnalato un post in %2",
- "user_flagged_post_in_dual": "%1 and %2 flagged a post in %3",
- "user_flagged_post_in_multiple": "%1 and %2 others flagged a post in %3",
+ "user_flagged_post_in_dual": "%1 e %2 hanno segnalato un post in %3",
+ "user_flagged_post_in_multiple": "%1 ed altri %2 hanno segnalato un post in %3",
"user_posted_to": "%1 ha postato una risposta a: %2",
- "user_posted_to_dual": "%1 and %2 have posted replies to: %3",
- "user_posted_to_multiple": "%1 and %2 others have posted replies to: %3",
- "user_posted_topic": "%1 ha postato un nuovo Topic: %2",
+ "user_posted_to_dual": "%1 e %2 hanno postato una risposta su: %3",
+ "user_posted_to_multiple": "%1 ed altri %2 hanno postato una risposta su: %3",
+ "user_posted_topic": "%1 ha postato una nuova discussione: %2",
"user_started_following_you": "%1 ha iniziato a seguirti.",
- "user_started_following_you_dual": "%1 and %2 started following you.",
- "user_started_following_you_multiple": "%1 and %2 others started following you.",
+ "user_started_following_you_dual": "%1 e %2 hanno iniziato a seguirti.",
+ "user_started_following_you_multiple": "%1 ed altri %2 hanno iniziato a seguirti.",
"new_register": "%1 ha inviato una richiesta di registrazione.",
- "new_register_multiple": "There are %1 registration requests awaiting review.",
+ "new_register_multiple": "Ci sono %1 richieste di registrazione che attendono di essere esaminate.",
"email-confirmed": "Email Confermata",
"email-confirmed-message": "Grazie per aver validato la tua email. Il tuo account è ora completamente attivato.",
"email-confirm-error-message": "C'è stato un problema nella validazione del tuo indirizzo email. Potrebbe essere il codice non valido o scaduto.",
diff --git a/public/language/it/pages.json b/public/language/it/pages.json
index da115161ee..b0920945fc 100644
--- a/public/language/it/pages.json
+++ b/public/language/it/pages.json
@@ -6,13 +6,13 @@
"popular-month": "Discussioni popolari questo mese",
"popular-alltime": "Discussioni più popolari di sempre",
"recent": "Discussioni Recenti",
- "flagged-posts": "Flagged Posts",
+ "flagged-posts": "Post Segnalati",
"users/online": "Utenti Online",
"users/latest": "Ultimi Utenti",
"users/sort-posts": "Utenti maggiori contributori",
"users/sort-reputation": "Utenti con la reputazione più alta",
- "users/banned": "Banned Users",
- "users/most-flags": "Most flagged users",
+ "users/banned": "Utenti Bannati",
+ "users/most-flags": "Gli utenti più segnalati",
"users/search": "Ricerca Utenti",
"notifications": "Notifiche",
"tags": "Tags",
@@ -26,23 +26,23 @@
"chats": "Chat",
"chat": "In chat con %1",
"account/edit": "Modificando \"%1\"",
- "account/edit/password": "Editing password of \"%1\"",
- "account/edit/username": "Editing username of \"%1\"",
- "account/edit/email": "Editing email of \"%1\"",
- "account/info": "Account Info",
+ "account/edit/password": "Modificando la password di \"%1\"",
+ "account/edit/username": "Modificando il nome utente di \"%1\"",
+ "account/edit/email": "Modificando l'email di \"%1\"",
+ "account/info": "Informazioni dell'account",
"account/following": "Persone seguite da %1",
"account/followers": "Persone che seguono %1",
"account/posts": "Post creati da %1",
"account/topics": "Discussioni create da %1",
"account/groups": "Gruppi di %1",
- "account/favourites": "%1's Bookmarked Posts",
+ "account/favourites": "Post Preferiti da %1",
"account/settings": "Impostazioni Utente",
"account/watched": "Discussioni osservate da %1",
- "account/upvoted": "Posts upvoted by %1",
+ "account/upvoted": "Post apprezzati da %1",
"account/downvoted": "Posts downvoted by %1",
- "account/best": "Best posts made by %1",
- "confirm": "Email Confirmed",
+ "account/best": "I migliori post di %1",
+ "confirm": "Email Confermata",
"maintenance.text": "%1 è attualmente in manutenzione. Per favore ritorna più tardi.",
"maintenance.messageIntro": "Inoltre, l'amministratore ha lasciato questo messaggio:",
- "throttled.text": "%1 is currently unavailable due to excessive load. Please come back another time."
+ "throttled.text": "%1 non è al momento disponibile a causa di un carico eccessivo. Per favore ritorna più tardi."
}
\ No newline at end of file
diff --git a/public/language/it/recent.json b/public/language/it/recent.json
index c61e51f150..a32a7b5d3c 100644
--- a/public/language/it/recent.json
+++ b/public/language/it/recent.json
@@ -6,7 +6,7 @@
"year": "Anno",
"alltime": "Sempre",
"no_recent_topics": "Non ci sono discussioni recenti.",
- "no_popular_topics": "Non ci sono argomenti popolari.",
+ "no_popular_topics": "Non ci sono discussioni popolari.",
"there-is-a-new-topic": "C'è un nuovo topic.",
"there-is-a-new-topic-and-a-new-post": "C'è un nuovo topic e un nuovo post.",
"there-is-a-new-topic-and-new-posts": "C'è una nuova discussione e %1 nuovi post.",
diff --git a/public/language/it/register.json b/public/language/it/register.json
index 58a04bf477..e3afd5aed2 100644
--- a/public/language/it/register.json
+++ b/public/language/it/register.json
@@ -1,6 +1,6 @@
{
"register": "Registrazione",
- "cancel_registration": "Cancel Registration",
+ "cancel_registration": "Cancella Registrazione",
"help.email": "Come opzione predefinita, il tuo indirizzo email non verrà reso pubblico.",
"help.username_restrictions": "Un nome utente unico, di almeno %1 caratteri e al massimo di %2. Gli altri utenti ti possono menzionare usando @username.",
"help.minimum_password_length": "La lunghezza della password deve essere di almeno %1 caratteri.",
@@ -16,8 +16,8 @@
"alternative_registration": "Altri metodi di registrazione",
"terms_of_use": "Termini di Utilizzo",
"agree_to_terms_of_use": "Accetto i Termini di Utilizzo",
- "terms_of_use_error": "You must agree to the Terms of Use",
+ "terms_of_use_error": "Devi accettare i Termini d'Utilizzo",
"registration-added-to-queue": "La tua registrazione è stata aggiunta alla coda di moderazione. Riceverai una mail quando verrà accettata da un amministratore.",
- "interstitial.intro": "We require some additional information before we can create your account.",
- "interstitial.errors-found": "We could not complete your registration:"
+ "interstitial.intro": "Abbiamo bisogno di qualche informazione in più prima di poter creare il tuo account.",
+ "interstitial.errors-found": "Non abbiamo potuto completare la tua registrazione:"
}
\ No newline at end of file
diff --git a/public/language/it/search.json b/public/language/it/search.json
index a3e73da887..9234c43389 100644
--- a/public/language/it/search.json
+++ b/public/language/it/search.json
@@ -24,10 +24,10 @@
"one-year": "Un anno",
"sort-by": "Ordina per",
"last-reply-time": "Ora dell'ultima risposta",
- "topic-title": "Titolo argomento",
+ "topic-title": "Titolo discussione",
"number-of-replies": "Numero di risposte",
"number-of-views": "Numero di visite",
- "topic-start-date": "Data inizio argomento",
+ "topic-start-date": "Discussione iniziata",
"username": "Nome utente",
"category": "Categoria",
"descending": "In ordine decrescente",
diff --git a/public/language/it/topic.json b/public/language/it/topic.json
index 1834ff19cd..59a99d3c71 100644
--- a/public/language/it/topic.json
+++ b/public/language/it/topic.json
@@ -5,7 +5,7 @@
"no_topics_found": "Nessuna discussione trovata!",
"no_posts_found": "Nessun post trovato!",
"post_is_deleted": "Questo post è eliminato!",
- "topic_is_deleted": "Questa discussione é stata eliminata",
+ "topic_is_deleted": "Questa discussione è stata eliminata",
"profile": "Profilo",
"posted_by": "Pubblicato da: %1",
"posted_by_guest": "Scritto da Ospite",
@@ -26,30 +26,30 @@
"tools": "Strumenti",
"flag": "Segnala",
"locked": "Bloccato",
- "pinned": "Pinned",
- "moved": "Moved",
- "bookmark_instructions": "Click here to return to the last read post in this thread.",
+ "pinned": "Appeso",
+ "moved": "Spostato",
+ "bookmark_instructions": "Clicca qui per tornare all'ultimo post letto in questa discussione.",
"flag_title": "Segnala questo post per la moderazione",
"flag_success": "Questo post è stato contrassegnato per la moderazione.",
"deleted_message": "Questa discussione è stata cancellata. Solo gli utenti con diritti di gestione possono vederla.",
"following_topic.message": "Da ora riceverai notifiche quando qualcuno posterà in questa discussione.",
- "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.",
- "ignoring_topic.message": "You will no longer see this topic in the unread topics list. You will be notified when you are mentioned or your post is up voted.",
+ "not_following_topic.message": "Vedrai questa discussione nella lista delle discussioni non lette, ma non riceverai notifiche quando qualcuno risponde a questa discussione.",
+ "ignoring_topic.message": "Non vedrai più questa discussione tra la lista dei non letti. Sarai notificato in caso qualcuno ti menzioni o se un tuo post viene votato positivamente.",
"login_to_subscribe": "Si prega di accedere o registrarsi per potersi iscrivere a questa discussione.",
"markAsUnreadForAll.success": "Discussione segnata come non letta per tutti.",
"mark_unread": "Segna come non letto",
- "mark_unread.success": "Topic marked as unread.",
+ "mark_unread.success": "Discussione è stata marcata come non letta.",
"watch": "Osserva",
"unwatch": "Non osservare più",
"watch.title": "Ricevi notifiche di nuove risposte in questa discussione",
"unwatch.title": "Smetti di osservare questa discussione",
"share_this_post": "Condividi questo Post",
- "watching": "Watching",
- "not-watching": "Not Watching",
- "ignoring": "Ignoring",
- "watching.description": "Notify me of new replies.
Show topic in unread.",
- "not-watching.description": "Do not notify me of new replies.
Show topic in unread if category is not ignored.",
- "ignoring.description": "Do not notify me of new replies.
Do not show topic in unread.",
+ "watching": "Seguito",
+ "not-watching": "Non Seguito",
+ "ignoring": "Ignorato",
+ "watching.description": "Notificami sulle nuove risposte.
Mostra la discussione tra le non lette.",
+ "not-watching.description": "Non notificarmi sulle nuove risposte.
Mostra la discussione fra le non lette se la categoria non è ignorata.",
+ "ignoring.description": "Non notificarmi sulle nuove risposte.
Non mostrare la discussione fra le non lette.",
"thread_tools.title": "Strumenti per la Discussione",
"thread_tools.markAsUnreadForAll": "Segna come non letto",
"thread_tools.pin": "Fissa Discussione",
@@ -61,7 +61,7 @@
"thread_tools.fork": "Dividi Discussione",
"thread_tools.delete": "Elimina Discussione",
"thread_tools.delete-posts": "Cancella post",
- "thread_tools.delete_confirm": "Sei sicuro di voler cancellare questa discussione?",
+ "thread_tools.delete_confirm": "Sei sicuro di voler eliminare questa discussione?",
"thread_tools.restore": "Ripristina Discussione",
"thread_tools.restore_confirm": "Sei sicuro di voler ripristinare questa discussione?",
"thread_tools.purge": "Svuota Discussione",
@@ -74,9 +74,9 @@
"disabled_categories_note": "Le Categorie disabilitate sono in grigio",
"confirm_move": "Sposta",
"confirm_fork": "Dividi",
- "favourite": "Bookmark",
- "favourites": "Bookmarks",
- "favourites.has_no_favourites": "You haven't bookmarked any posts yet.",
+ "favourite": "Favorito",
+ "favourites": "Favoriti",
+ "favourites.has_no_favourites": "Non hai ancora aggiunto nessun post tra i favoriti",
"loading_more_posts": "Caricamento altri post",
"move_topic": "Sposta Discussione",
"move_topics": "Sposta Discussioni",
@@ -86,7 +86,7 @@
"topic_will_be_moved_to": "Questa discussione verrà spostata nella categoria",
"fork_topic_instruction": "Clicca sui post che vuoi dividere",
"fork_no_pids": "Nessun post selezionato!",
- "fork_pid_count": "%1 post(s) selected",
+ "fork_pid_count": "%1 post selezionati",
"fork_success": "Topic Diviso con successo ! Clicca qui per andare al Topic Diviso.",
"delete_posts_instruction": "Clicca sui post che vuoi cancellare/eliminare",
"composer.title_placeholder": "Inserisci qui il titolo della discussione...",
@@ -94,7 +94,7 @@
"composer.discard": "Annulla",
"composer.submit": "Invia",
"composer.replying_to": "Rispondendo a %1",
- "composer.new_topic": "Nuovo Argomento",
+ "composer.new_topic": "Nuova Discussione",
"composer.uploading": "caricamento...",
"composer.thumb_url_label": "Incolla l'URL di una immagine per la discussione",
"composer.thumb_title": "Aggiungi un'immagine a questa discussione",
@@ -111,10 +111,10 @@
"newest_to_oldest": "Da Nuovi a Vecchi",
"most_votes": "Più votati",
"most_posts": "Ulteriori post",
- "stale.title": "Preferisci creare un nuovo topic?",
+ "stale.title": "Preferisci creare una nuova discussione?",
"stale.warning": "Il topic al quale stai rispondendo è abbastanza vecchio. Vorresti piuttosto creare un nuovo topic in riferimento a questo nella tua risposta?",
- "stale.create": "Crea un topic nuovo",
- "stale.reply_anyway": "Rispondi a questo topic comunque",
+ "stale.create": "Crea una nuova discussione",
+ "stale.reply_anyway": "Rispondi comunque a questa discussione",
"link_back": "Re: [%1](%2)",
"spam": "Spam",
"offensive": "Offensivo",
diff --git a/public/language/it/unread.json b/public/language/it/unread.json
index 94c4a315a3..f03f876183 100644
--- a/public/language/it/unread.json
+++ b/public/language/it/unread.json
@@ -7,7 +7,7 @@
"all": "Tutti",
"all_categories": "Tutte le categorie",
"topics_marked_as_read.success": "Discussione marcata come letta!",
- "all-topics": "All Topics",
- "new-topics": "New Topics",
- "watched-topics": "Watched Topics"
+ "all-topics": "Tutte le Discussioni",
+ "new-topics": "Nuova Discussione",
+ "watched-topics": "Discussioni seguite"
}
\ No newline at end of file
diff --git a/public/language/it/uploads.json b/public/language/it/uploads.json
index 1622cb5693..fcc163f5c7 100644
--- a/public/language/it/uploads.json
+++ b/public/language/it/uploads.json
@@ -1,6 +1,6 @@
{
- "uploading-file": "Uploading the file...",
- "select-file-to-upload": "Select a file to upload!",
- "upload-success": "File uploaded successfully!",
- "maximum-file-size": "Maximum %1 kb"
+ "uploading-file": "Sto caricando il file...",
+ "select-file-to-upload": "Seleziona un file da caricare!",
+ "upload-success": "File caricato con successo!",
+ "maximum-file-size": "Massimo %1 kb"
}
\ No newline at end of file
diff --git a/public/language/it/user.json b/public/language/it/user.json
index 1c864d034b..303a2cbe6b 100644
--- a/public/language/it/user.json
+++ b/public/language/it/user.json
@@ -6,7 +6,7 @@
"postcount": "Numero post",
"email": "Email",
"confirm_email": "Conferma Email",
- "account_info": "Account Info",
+ "account_info": "Informazioni dell'account",
"ban_account": "BAN dell'account",
"ban_account_confirm": "Sei sicuro di voler bannare questo utente?",
"unban_account": "Togli il BAN",
@@ -23,7 +23,7 @@
"profile": "Profilo",
"profile_views": "Visite al profilo",
"reputation": "Reputazione",
- "favourites": "Bookmarks",
+ "favourites": "Preferiti",
"watched": "Osservati",
"followers": "Da chi è seguito",
"following": "Chi segue",
@@ -31,17 +31,17 @@
"signature": "Firma",
"birthday": "Data di nascita",
"chat": "Chat",
- "chat_with": "Chat with %1",
+ "chat_with": "Chatta con %1",
"follow": "Segui",
"unfollow": "Smetti di seguire",
"more": "Altro",
"profile_update_success": "Profilo aggiornato correttamente!",
"change_picture": "Cambia Foto",
- "change_username": "Change Username",
- "change_email": "Change Email",
+ "change_username": "Modifica il nome utente",
+ "change_email": "Modifica Email",
"edit": "Modifica",
- "edit-profile": "Edit Profile",
- "default_picture": "Default Icon",
+ "edit-profile": "Modifica Profilo",
+ "default_picture": "Icona di default",
"uploaded_picture": "Foto caricata",
"upload_new_picture": "Carica una nuova foto",
"upload_new_picture_from_url": "Carica nuova immagine da URL",
@@ -57,32 +57,32 @@
"password": "Password",
"username_taken_workaround": "Il nome utente che hai richiesto era già stato utilizzato, quindi lo abbiamo modificato leggermente. Ora il tuo è %1",
"password_same_as_username": "La tua password è uguale al tuo username, per piacere scegli un'altra password",
- "password_same_as_email": "Your password is the same as your email, please select another password.",
+ "password_same_as_email": "La tua password sembra coincidere con la tua email, per favore fornisci un'altra password.",
"upload_picture": "Carica foto",
"upload_a_picture": "Carica una foto",
"remove_uploaded_picture": "Elimina foto caricata",
- "upload_cover_picture": "Upload cover picture",
+ "upload_cover_picture": "Carica immagine di copertina",
"settings": "Impostazioni",
"show_email": "Mostra la mia Email",
- "show_fullname": "Vedi il Mio Nome Completo",
+ "show_fullname": "Mostra il mio nome completo",
"restrict_chats": "Abilita messaggi in chat soltanto dagli utenti che seguo",
"digest_label": "Iscriviti al Sommario",
- "digest_description": "Abbonati agli aggiornamenti via email di questo forum (nuove notifiche e argomenti) secondo una pianificazione impostata",
+ "digest_description": "Abbonati agli aggiornamenti via email di questo forum (nuove notifiche e discussioni) secondo una pianificazione impostata",
"digest_off": "Spento",
"digest_daily": "Quotidiano",
"digest_weekly": "Settimanale",
"digest_monthly": "Mensile",
"send_chat_notifications": "Invia una email se arriva un nuovo messaggio di chat e non sono online",
- "send_post_notifications": "Invia una email quando le risposte sono fatte a discussioni a cui sono sottoscritto",
+ "send_post_notifications": "Invia una email quando ci sono nuove risposte a discussioni a cui sono sottoscritto",
"settings-require-reload": "Alcuni cambiamenti di impostazioni richiedono un ricaricamento. Clicca qui per ricaricare la pagina.",
"has_no_follower": "Questo utente non è seguito da nessuno :(",
"follows_no_one": "Questo utente non segue nessuno :(",
"has_no_posts": "Questo utente non ha ancora scritto niente.",
"has_no_topics": "Questo utente non ha ancora avviato discussioni.",
"has_no_watched_topics": "Questo utente non sta osservando discussioni.",
- "has_no_upvoted_posts": "This user hasn't upvoted any posts yet.",
+ "has_no_upvoted_posts": "Questo utente non ha ancora apprezzato nessun post.",
"has_no_downvoted_posts": "This user hasn't downvoted any posts yet.",
- "has_no_voted_posts": "This user has no voted posts",
+ "has_no_voted_posts": "Questo utente non ha post votati",
"email_hidden": "Email Nascosta",
"hidden": "nascosta",
"paginate_description": "Non utilizzare lo scroll infinito per discussioni e messaggi",
@@ -93,26 +93,26 @@
"open_links_in_new_tab": "Apri i link web in una nuova pagina",
"enable_topic_searching": "Abilita la ricerca negli argomenti",
"topic_search_help": "Se abilitata, la ricerca negli argomenti ignorerà il comportamento predefinito del browser per consentirti di cercare all'interno delle discussioni, anziché soltanto nel contenuto visibile a schermo",
- "delay_image_loading": "Delay Image Loading",
- "image_load_delay_help": "If enabled, images in topics will not load until they are scrolled into view",
- "scroll_to_my_post": "After posting a reply, show the new post",
- "follow_topics_you_reply_to": "Watch topics that you reply to",
- "follow_topics_you_create": "Watch topics you create",
- "grouptitle": "Group Title",
+ "delay_image_loading": "Ritarda il caricamento delle immagini",
+ "image_load_delay_help": "Se selezionato, le immagini nelle discussioni non saranno caricate finché non sono visibili nello schermo",
+ "scroll_to_my_post": "Dopo aver postato una risposta, mostra il nuovo post",
+ "follow_topics_you_reply_to": "Segui le discussioni a cui rispondi",
+ "follow_topics_you_create": "Segui le discussioni che crei",
+ "grouptitle": "Titolo del Gruppo",
"no-group-title": "Nessun titolo al gruppo",
"select-skin": "Seleziona uno Skin",
- "select-homepage": "Select a Homepage",
- "homepage": "Homepage",
- "homepage_description": "Select a page to use as the forum homepage or 'None' to use the default homepage.",
- "custom_route": "Custom Homepage Route",
- "custom_route_help": "Enter a route name here, without any preceding slash (e.g. \"recent\", or \"popular\")",
+ "select-homepage": "Seleziona una Pagina Iniziale",
+ "homepage": "Pagina iniziale",
+ "homepage_description": "Seleziona una pagina da usare come pagina iniziale o \"Nessuna\" per usare quella di default.",
+ "custom_route": "Percorso della Homepage personalizzato",
+ "custom_route_help": "Inserisci qui un nome percorso, senza nessuno slash precedente (p.es. \"recent\", o \"popular\")",
"sso.title": "Servizi Single-Sign-On",
"sso.associated": "Associa con",
"sso.not-associated": "Clicca qui per associare con",
- "info.latest-flags": "Latest Flags",
- "info.no-flags": "No Flagged Posts Found",
- "info.ban-history": "Recent Ban History",
- "info.no-ban-history": "This user has never been banned",
- "info.banned-until": "Banned until %1",
- "info.banned-permanently": "Banned permanently"
+ "info.latest-flags": "Ultime Segnalazioni",
+ "info.no-flags": "Non è stato trovato nessun post segnalato",
+ "info.ban-history": "Storico dei Ban recenti",
+ "info.no-ban-history": "Questo utente non è mai stato bannato",
+ "info.banned-until": "Bannato fino %1",
+ "info.banned-permanently": "Bannato permanentemente"
}
\ No newline at end of file
diff --git a/public/language/it/users.json b/public/language/it/users.json
index 3299cd0459..c88f786172 100644
--- a/public/language/it/users.json
+++ b/public/language/it/users.json
@@ -17,5 +17,5 @@
"unread_topics": "Discussioni non lette",
"categories": "Categorie",
"tags": "Tag",
- "no-users-found": "No users found!"
+ "no-users-found": "Nessun utente trovato!"
}
\ No newline at end of file
diff --git a/public/language/ja/global.json b/public/language/ja/global.json
index 1e89ac1a32..107ae13ee7 100644
--- a/public/language/ja/global.json
+++ b/public/language/ja/global.json
@@ -7,8 +7,10 @@
"403.login": "権限を持っている場合はログインすると閲覧出来ます。",
"404.title": "見つかりません",
"404.message": "あなたは存在してないページを訪問してます。ホームページに戻ります。",
- "500.title": "内部エラー",
+ "500.title": "Internal Error.",
"500.message": "何か問題が発生しているようです。",
+ "400.title": "Bad Request.",
+ "400.message": "It looks like this link is malformed, please double-check and try again. Otherwise, return to the home page.",
"register": "登録",
"login": "ログイン",
"please_log_in": "ログインください",
@@ -93,5 +95,6 @@
"upload_file": "Upload file",
"upload": "Upload",
"allowed-file-types": "Allowed file types are %1",
- "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?"
+ "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?",
+ "reconnecting-message": "Looks like your connection to %1 was lost, please wait while we try to reconnect."
}
\ No newline at end of file
diff --git a/public/language/ko/global.json b/public/language/ko/global.json
index e404ac910a..6e9b7b3a93 100644
--- a/public/language/ko/global.json
+++ b/public/language/ko/global.json
@@ -7,8 +7,10 @@
"403.login": "로그인되어 있는지 확인해 주세요.",
"404.title": "페이지를 찾을 수 없습니다.",
"404.message": "존재하지 않는 페이지에 접근하였습니다. 홈 페이지로 이동합니다.",
- "500.title": "내부 오류가 발생했습니다.",
+ "500.title": "Internal Error.",
"500.message": "알 수 없는 오류가 발생했습니다.",
+ "400.title": "Bad Request.",
+ "400.message": "It looks like this link is malformed, please double-check and try again. Otherwise, return to the home page.",
"register": "회원가입",
"login": "로그인",
"please_log_in": "로그인해 주세요.",
@@ -93,5 +95,6 @@
"upload_file": "파일 업로드",
"upload": "업로드",
"allowed-file-types": "사용가능한 파일 유형: %1",
- "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?"
+ "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?",
+ "reconnecting-message": "Looks like your connection to %1 was lost, please wait while we try to reconnect."
}
\ No newline at end of file
diff --git a/public/language/lt/global.json b/public/language/lt/global.json
index 3892b4ede8..1ffeb7040a 100644
--- a/public/language/lt/global.json
+++ b/public/language/lt/global.json
@@ -7,8 +7,10 @@
"403.login": "Tikriausiai tu turėtum pabandyt prisijungt?",
"404.title": "Nerasta",
"404.message": "Pasirodo sėdi puslapyje kurio net nėra. Grįžk į namų puslapį.",
- "500.title": "Vidinė klaida.",
+ "500.title": "Internal Error.",
"500.message": "Oops! Atrodo, kad kažkas nutiko!",
+ "400.title": "Bad Request.",
+ "400.message": "It looks like this link is malformed, please double-check and try again. Otherwise, return to the home page.",
"register": "Registruotis",
"login": "Prisijungti",
"please_log_in": "Prašome prisijungti",
@@ -93,5 +95,6 @@
"upload_file": "Upload file",
"upload": "Upload",
"allowed-file-types": "Allowed file types are %1",
- "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?"
+ "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?",
+ "reconnecting-message": "Looks like your connection to %1 was lost, please wait while we try to reconnect."
}
\ No newline at end of file
diff --git a/public/language/ms/global.json b/public/language/ms/global.json
index e226d5f93c..40d6209ba9 100644
--- a/public/language/ms/global.json
+++ b/public/language/ms/global.json
@@ -7,8 +7,10 @@
"403.login": "Mungkin anda boleh cuba log masuk?",
"404.title": "tidak dijumpai",
"404.message": "Halaman yang diminta tidak wujud. Kembali ke halaman utama.",
- "500.title": "ralat dalaman",
+ "500.title": "Internal Error.",
"500.message": "Oops! Macam ada yang tidak kena",
+ "400.title": "Bad Request.",
+ "400.message": "It looks like this link is malformed, please double-check and try again. Otherwise, return to the home page.",
"register": "Daftar",
"login": "Log Masuk",
"please_log_in": "Sila log masuk",
@@ -93,5 +95,6 @@
"upload_file": "Upload file",
"upload": "Upload",
"allowed-file-types": "Allowed file types are %1",
- "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?"
+ "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?",
+ "reconnecting-message": "Looks like your connection to %1 was lost, please wait while we try to reconnect."
}
\ No newline at end of file
diff --git a/public/language/nb/global.json b/public/language/nb/global.json
index 1e8af5dc12..020fe6aa62 100644
--- a/public/language/nb/global.json
+++ b/public/language/nb/global.json
@@ -7,8 +7,10 @@
"403.login": "Kanskje du skal prøve å logge inn?",
"404.title": "Ikke funnet",
"404.message": "Du har funnet en side som ikke eksisterer. Returner til startsiden?",
- "500.title": "Intern feil.",
+ "500.title": "Internal Error.",
"500.message": "Oops! Ser ut som noe gikk galt!",
+ "400.title": "Bad Request.",
+ "400.message": "It looks like this link is malformed, please double-check and try again. Otherwise, return to the home page.",
"register": "Registrer",
"login": "Logg inn",
"please_log_in": "Vennligst logg inn",
@@ -93,5 +95,6 @@
"upload_file": "Upload file",
"upload": "Upload",
"allowed-file-types": "Allowed file types are %1",
- "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?"
+ "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?",
+ "reconnecting-message": "Looks like your connection to %1 was lost, please wait while we try to reconnect."
}
\ No newline at end of file
diff --git a/public/language/nl/global.json b/public/language/nl/global.json
index c2cf89003a..bf94e340b2 100644
--- a/public/language/nl/global.json
+++ b/public/language/nl/global.json
@@ -7,8 +7,10 @@
"403.login": "Je kan proberen in te loggen?",
"404.title": "Niet gevonden",
"404.message": "Deze pagina bestaat niet. Klik hier om naar de hoofdpagina van deze website te navigeren.",
- "500.title": "Interne fout.",
+ "500.title": "Internal Error.",
"500.message": "Oeps! Ziet er naar uit dat iets fout ging!",
+ "400.title": "Bad Request.",
+ "400.message": "It looks like this link is malformed, please double-check and try again. Otherwise, return to the home page.",
"register": "Registeren",
"login": "Login",
"please_log_in": "Aanmelden",
@@ -93,5 +95,6 @@
"upload_file": "Upload bestand",
"upload": "Upload",
"allowed-file-types": "Toegestane bestandstypen zijn %1",
- "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?"
+ "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?",
+ "reconnecting-message": "Looks like your connection to %1 was lost, please wait while we try to reconnect."
}
\ No newline at end of file
diff --git a/public/language/pl/global.json b/public/language/pl/global.json
index f3a25ee6b2..0a88d05532 100644
--- a/public/language/pl/global.json
+++ b/public/language/pl/global.json
@@ -7,8 +7,10 @@
"403.login": "Może powinieneś się zalogować?",
"404.title": "Nie znaleziono",
"404.message": "Wygląda na to, że trafiłeś na stronę, która nie istnieje. Wróć do strony głównej.",
- "500.title": "Błąd wewnętrzny",
+ "500.title": "Internal Error.",
"500.message": "Ups! Coś poszło nie tak.",
+ "400.title": "Bad Request.",
+ "400.message": "It looks like this link is malformed, please double-check and try again. Otherwise, return to the home page.",
"register": "Zarejestruj się",
"login": "Zaloguj się",
"please_log_in": "Proszę się zalogować",
@@ -93,5 +95,6 @@
"upload_file": "Załaduj plik",
"upload": "Załaduj",
"allowed-file-types": "Dozwolone typy plików %1",
- "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?"
+ "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?",
+ "reconnecting-message": "Looks like your connection to %1 was lost, please wait while we try to reconnect."
}
\ No newline at end of file
diff --git a/public/language/pt_BR/global.json b/public/language/pt_BR/global.json
index 69c907a516..71543c8896 100644
--- a/public/language/pt_BR/global.json
+++ b/public/language/pt_BR/global.json
@@ -7,8 +7,10 @@
"403.login": "Talvez você deveria tentar fazer login?",
"404.title": "Não Encontrado",
"404.message": "Parece que você chegou à uma página que não existe. Voltar para a página inicial.",
- "500.title": "Erro interno.",
+ "500.title": "Internal Error.",
"500.message": "Oops! Parece que algo deu errado!",
+ "400.title": "Bad Request.",
+ "400.message": "It looks like this link is malformed, please double-check and try again. Otherwise, return to the home page.",
"register": "Cadastrar",
"login": "Login",
"please_log_in": "Por Favor Efetue o Login",
@@ -93,5 +95,6 @@
"upload_file": "Fazer upload de arquivo",
"upload": "Upload",
"allowed-file-types": "Os tipos de arquivo permitidos são %1",
- "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?"
+ "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?",
+ "reconnecting-message": "Looks like your connection to %1 was lost, please wait while we try to reconnect."
}
\ No newline at end of file
diff --git a/public/language/ro/global.json b/public/language/ro/global.json
index 7d2f15e71c..c634e3a1c8 100644
--- a/public/language/ro/global.json
+++ b/public/language/ro/global.json
@@ -7,8 +7,10 @@
"403.login": "Poate ar trebui să te autentifici?",
"404.title": "Nu a fost găsit",
"404.message": "You seem to have stumbled upon a page that does not exist. Return to the home page.",
- "500.title": "Eroare internă.",
+ "500.title": "Internal Error.",
"500.message": "Oops! Se pare că ceva a mers greșit!",
+ "400.title": "Bad Request.",
+ "400.message": "It looks like this link is malformed, please double-check and try again. Otherwise, return to the home page.",
"register": "Înregistrare",
"login": "Autentificare",
"please_log_in": "Autentifică-te",
@@ -93,5 +95,6 @@
"upload_file": "Încărcați fișierul",
"upload": "Încărcați",
"allowed-file-types": "Tipuri de fișiere permise sunt %1",
- "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?"
+ "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?",
+ "reconnecting-message": "Looks like your connection to %1 was lost, please wait while we try to reconnect."
}
\ No newline at end of file
diff --git a/public/language/ru/global.json b/public/language/ru/global.json
index d5ed6dc2b9..24cef36d23 100644
--- a/public/language/ru/global.json
+++ b/public/language/ru/global.json
@@ -7,8 +7,10 @@
"403.login": "Возможно Вам следует войти под своим аккаунтом?",
"404.title": "Страница не найдена",
"404.message": "Вы пытаетесь перейти на страницу, которой не существует. Вам стоит вернутся на главную страницу.",
- "500.title": "Внутренняя ошибка.",
+ "500.title": "Internal Error.",
"500.message": "Упс! Похоже, что-то пошло не так!",
+ "400.title": "Bad Request.",
+ "400.message": "It looks like this link is malformed, please double-check and try again. Otherwise, return to the home page.",
"register": "Зарегистрироваться",
"login": "Войти",
"please_log_in": "Пожалуйста, войдите под своим аккаунтом",
@@ -93,5 +95,6 @@
"upload_file": "Загрузить файл",
"upload": "Загрузить",
"allowed-file-types": "Разрешенные форматы файлов %1",
- "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?"
+ "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?",
+ "reconnecting-message": "Looks like your connection to %1 was lost, please wait while we try to reconnect."
}
\ No newline at end of file
diff --git a/public/language/rw/global.json b/public/language/rw/global.json
index 1f82d7cdfd..bb0164820c 100644
--- a/public/language/rw/global.json
+++ b/public/language/rw/global.json
@@ -7,8 +7,10 @@
"403.login": "Wenda ahari ukeneye kugerageza kwinjiramo",
"404.title": "Ntacyabonetse",
"404.message": "Biragaragara ko wageze kuri paji itariho ikintu. Subira Imbere.",
- "500.title": "Hari ikibazo cya tekinike imbere. ",
+ "500.title": "Internal Error.",
"500.message": "Ye baba we! Ntibikunze!",
+ "400.title": "Bad Request.",
+ "400.message": "It looks like this link is malformed, please double-check and try again. Otherwise, return to the home page.",
"register": "Iyandikishe",
"login": "Injiramo",
"please_log_in": "Injiramo",
@@ -93,5 +95,6 @@
"upload_file": "Pakira ifayilo",
"upload": "Pakira",
"allowed-file-types": "Ubwoko bw'amafayilo bwemewe ni %1",
- "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?"
+ "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?",
+ "reconnecting-message": "Looks like your connection to %1 was lost, please wait while we try to reconnect."
}
\ No newline at end of file
diff --git a/public/language/sc/global.json b/public/language/sc/global.json
index 9f7f952155..a5b6a3e20f 100644
--- a/public/language/sc/global.json
+++ b/public/language/sc/global.json
@@ -7,8 +7,10 @@
"403.login": "Perhaps you should try logging in?",
"404.title": "No Agatadu",
"404.message": "You seem to have stumbled upon a page that does not exist. Return to the home page.",
- "500.title": "Faddina interna.",
+ "500.title": "Internal Error.",
"500.message": "Oops! Paret chi carchi cosa est andada male!",
+ "400.title": "Bad Request.",
+ "400.message": "It looks like this link is malformed, please double-check and try again. Otherwise, return to the home page.",
"register": "Registra·ti",
"login": "Intra",
"please_log_in": "Pro praghere Intra",
@@ -93,5 +95,6 @@
"upload_file": "Upload file",
"upload": "Upload",
"allowed-file-types": "Allowed file types are %1",
- "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?"
+ "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?",
+ "reconnecting-message": "Looks like your connection to %1 was lost, please wait while we try to reconnect."
}
\ No newline at end of file
diff --git a/public/language/sk/global.json b/public/language/sk/global.json
index 14cc91fb07..7a2ac8cbaa 100644
--- a/public/language/sk/global.json
+++ b/public/language/sk/global.json
@@ -7,8 +7,10 @@
"403.login": "Perhaps you should try logging in?",
"404.title": "Stránka nenájdená",
"404.message": "You seem to have stumbled upon a page that does not exist. Return to the home page.",
- "500.title": "Neznámá chyba",
+ "500.title": "Internal Error.",
"500.message": "Jejda, vyzerá, že sa niečo pokazilo.",
+ "400.title": "Bad Request.",
+ "400.message": "It looks like this link is malformed, please double-check and try again. Otherwise, return to the home page.",
"register": "Registrovať",
"login": "Prihlásiť sa",
"please_log_in": "Prosím, prihláste sa",
@@ -93,5 +95,6 @@
"upload_file": "Upload file",
"upload": "Upload",
"allowed-file-types": "Allowed file types are %1",
- "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?"
+ "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?",
+ "reconnecting-message": "Looks like your connection to %1 was lost, please wait while we try to reconnect."
}
\ No newline at end of file
diff --git a/public/language/sl/global.json b/public/language/sl/global.json
index 911fb6a7ff..101d3c3af2 100644
--- a/public/language/sl/global.json
+++ b/public/language/sl/global.json
@@ -7,8 +7,10 @@
"403.login": "Morda bi se raje prijavili?",
"404.title": "Ni mogoče najti",
"404.message": "Kot kaže ste naleteli na stran, ki ne obstaja. Vrnite se na začetno stran.",
- "500.title": "Notranja napaka.",
+ "500.title": "Internal Error.",
"500.message": "Ups! Nekaj je šlo narobe!",
+ "400.title": "Bad Request.",
+ "400.message": "It looks like this link is malformed, please double-check and try again. Otherwise, return to the home page.",
"register": "Registracija",
"login": "Prijava",
"please_log_in": "Prosimo prijavite se",
@@ -93,5 +95,6 @@
"upload_file": "Upload file",
"upload": "Upload",
"allowed-file-types": "Allowed file types are %1",
- "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?"
+ "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?",
+ "reconnecting-message": "Looks like your connection to %1 was lost, please wait while we try to reconnect."
}
\ No newline at end of file
diff --git a/public/language/sr/global.json b/public/language/sr/global.json
index 97e71581ea..8af7ca5b1d 100644
--- a/public/language/sr/global.json
+++ b/public/language/sr/global.json
@@ -7,8 +7,10 @@
"403.login": "Можда би требало да се пријавите?",
"404.title": "Не постоји",
"404.message": "Изгледа да сте наишли на страницу која не постоји. Вратите се на почетну страницу..",
- "500.title": "Унутрашња грешка.",
+ "500.title": "Internal Error.",
"500.message": "Упс! Изгледа да нешто ије како треба!",
+ "400.title": "Bad Request.",
+ "400.message": "It looks like this link is malformed, please double-check and try again. Otherwise, return to the home page.",
"register": "Регистрација",
"login": "Пријава",
"please_log_in": "Молимо, пријавите се",
@@ -93,5 +95,6 @@
"upload_file": "Upload file",
"upload": "Upload",
"allowed-file-types": "Allowed file types are %1",
- "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?"
+ "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?",
+ "reconnecting-message": "Looks like your connection to %1 was lost, please wait while we try to reconnect."
}
\ No newline at end of file
diff --git a/public/language/sv/global.json b/public/language/sv/global.json
index 5c1b98522e..992f2a32fe 100644
--- a/public/language/sv/global.json
+++ b/public/language/sv/global.json
@@ -7,8 +7,10 @@
"403.login": "Du kanske bör försöka logga in?",
"404.title": "Sidan saknas",
"404.message": "Du verkar ha ramlat in på en sida som inte finns. Återgå till första sidan.",
- "500.title": "Internt fel.",
+ "500.title": "Internal Error.",
"500.message": "Hoppsan! Något verkar ha gått fel!",
+ "400.title": "Bad Request.",
+ "400.message": "It looks like this link is malformed, please double-check and try again. Otherwise, return to the home page.",
"register": "Registrera",
"login": "Logga in",
"please_log_in": "Var god logga in",
@@ -93,5 +95,6 @@
"upload_file": "Ladda upp en fil",
"upload": "Ladda upp",
"allowed-file-types": "Tillåtna filtyper är %1",
- "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?"
+ "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?",
+ "reconnecting-message": "Looks like your connection to %1 was lost, please wait while we try to reconnect."
}
\ No newline at end of file
diff --git a/public/language/th/global.json b/public/language/th/global.json
index eb81fb4ba5..09e26d956a 100644
--- a/public/language/th/global.json
+++ b/public/language/th/global.json
@@ -7,8 +7,10 @@
"403.login": "Perhaps you should try logging in?",
"404.title": "ไม่พบ",
"404.message": "You seem to have stumbled upon a page that does not exist. Return to the home page.",
- "500.title": "มีข้อผิดพลาดภายในระบบ",
+ "500.title": "Internal Error.",
"500.message": "อุ่ย! มีสิ่งที่ไม่ถูกต้องเกิดขึ้น!",
+ "400.title": "Bad Request.",
+ "400.message": "It looks like this link is malformed, please double-check and try again. Otherwise, return to the home page.",
"register": "ลงทะเบียน",
"login": "เข้าสู่ระบบ",
"please_log_in": "กรุณาเข้าสู่ระบบ",
@@ -93,5 +95,6 @@
"upload_file": "Upload file",
"upload": "Upload",
"allowed-file-types": "Allowed file types are %1",
- "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?"
+ "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?",
+ "reconnecting-message": "Looks like your connection to %1 was lost, please wait while we try to reconnect."
}
\ No newline at end of file
diff --git a/public/language/tr/global.json b/public/language/tr/global.json
index 9e3c328dae..9f9e5a1377 100644
--- a/public/language/tr/global.json
+++ b/public/language/tr/global.json
@@ -7,8 +7,10 @@
"403.login": "Belki de tekrar giriş yapmayı denersiniz?",
"404.title": "Bulunamadı",
"404.message": "Erişim izniniz olmayan bir sayfaya denk gelmiş gibisiniz. Anasayfa'ya geri dönün.",
- "500.title": "Dahili hata.",
+ "500.title": "Internal Error.",
"500.message": "Ups! Bir şeyler ters gitti sanki!",
+ "400.title": "Geçersiz istek.",
+ "400.message": "It looks like this link is malformed, please double-check and try again. Otherwise, return to the home page.",
"register": "Kayıt Ol",
"login": "Giriş",
"please_log_in": "Lütfen Giriş Yapınız",
@@ -93,5 +95,6 @@
"upload_file": "Dosya yükle",
"upload": "Yükle",
"allowed-file-types": "İzin verilen dosya tipleri %1",
- "unsaved-changes": "Kaydedilmemiş değişiklikler var. Çıkmak istediğinize emin misiniz?"
+ "unsaved-changes": "Kaydedilmemiş değişiklikler var. Çıkmak istediğinize emin misiniz?",
+ "reconnecting-message": "Looks like your connection to %1 was lost, please wait while we try to reconnect."
}
\ No newline at end of file
diff --git a/public/language/vi/global.json b/public/language/vi/global.json
index 2cbb1536c8..01890dcd33 100644
--- a/public/language/vi/global.json
+++ b/public/language/vi/global.json
@@ -7,8 +7,10 @@
"403.login": "Có lẽ bạn nên thử đăng nhập?",
"404.title": "Không tìm thấy",
"404.message": "Có vẻ như bạn đang cố vào một trang không tồn tại. Hãy trở lại trang chủ.",
- "500.title": "Lỗi nội bộ",
+ "500.title": "Internal Error.",
"500.message": "Úi chà! Có vẻ như có trục trặc rồi!",
+ "400.title": "Bad Request.",
+ "400.message": "It looks like this link is malformed, please double-check and try again. Otherwise, return to the home page.",
"register": "Đăng ký",
"login": "Đăng nhập",
"please_log_in": "Xin hãy đăng nhập",
@@ -93,5 +95,6 @@
"upload_file": "Tải file lên",
"upload": "Tải lên",
"allowed-file-types": "Các định dạng file được cho phép là %1",
- "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?"
+ "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?",
+ "reconnecting-message": "Looks like your connection to %1 was lost, please wait while we try to reconnect."
}
\ No newline at end of file
diff --git a/public/language/zh_CN/error.json b/public/language/zh_CN/error.json
index 5788c57c59..e3d3aa55d4 100644
--- a/public/language/zh_CN/error.json
+++ b/public/language/zh_CN/error.json
@@ -20,7 +20,7 @@
"email-taken": "此电子邮箱已被占用",
"email-not-confirmed": "您的电子邮箱尚未确认,请点击这里确认您的电子邮箱。",
"email-not-confirmed-chat": "您的电子邮箱尚未确认,无法聊天,请点击这里确认您的电子邮箱。",
- "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email.",
+ "email-not-confirmed-email-sent": "您的邮箱地址还没有被确认,请检查邮箱中的确认邮件。",
"no-email-to-confirm": "本论坛需要电子邮箱确认,请点击这里输入电子邮箱地址",
"email-confirm-failed": "我们无法确认您的电子邮箱,请重试",
"confirm-email-already-sent": "确认邮件已发出,如需重新发送请等待 %1 分钟后再试。",
@@ -55,8 +55,8 @@
"post-delete-duration-expired-hours-minutes": "您只能在发表 %1 小时 %2 分钟后删除帖子",
"post-delete-duration-expired-days": "您只能在发表 %1 天后删除帖子",
"post-delete-duration-expired-days-hours": "您只能在发表 %1 天 %2 小时后删除帖子",
- "cant-delete-topic-has-reply": "You can't delete your topic after it has a reply",
- "cant-delete-topic-has-replies": "You can't delete your topic after it has %1 replies",
+ "cant-delete-topic-has-reply": "您不能删除您的主题,因为已有回复。",
+ "cant-delete-topic-has-replies": "您不能删除您的主题,因为已有 %1 条回复。",
"content-too-short": "请增添发帖内容,不能少于 %1 个字符。",
"content-too-long": "请删减发帖内容,不能超过 %1 个字符。",
"title-too-short": "请增加标题,不能少于 %1 个字符。",
@@ -123,5 +123,5 @@
"no-users-in-room": "这个聊天室中没有用户",
"cant-kick-self": "你不能把自己踢出群组",
"no-users-selected": "尚未选择用户",
- "invalid-home-page-route": "Invalid home page route"
+ "invalid-home-page-route": "无效的首页路径"
}
\ No newline at end of file
diff --git a/public/language/zh_CN/global.json b/public/language/zh_CN/global.json
index 4be989cb9f..c94f323598 100644
--- a/public/language/zh_CN/global.json
+++ b/public/language/zh_CN/global.json
@@ -7,8 +7,10 @@
"403.login": "或许您应该先 登录试试?",
"404.title": "未找到",
"404.message": "您访问的页面不存在。返回首页。",
- "500.title": "内部错误。",
+ "500.title": "内部错误",
"500.message": "哎呀!看来是哪里出错了!",
+ "400.title": "错误的请求",
+ "400.message": "看起来这个链接的格式不正确,请再次检查并重试。或者返回主页。",
"register": "注册",
"login": "登录",
"please_log_in": "请登录",
@@ -93,5 +95,6 @@
"upload_file": "上传文件",
"upload": "上传",
"allowed-file-types": "允许的文件类型有 %1",
- "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?"
+ "unsaved-changes": "您有未保存的更改,您确定您要离开么?",
+ "reconnecting-message": "Looks like your connection to %1 was lost, please wait while we try to reconnect."
}
\ No newline at end of file
diff --git a/public/language/zh_CN/login.json b/public/language/zh_CN/login.json
index d9d5e10980..d46196e47d 100644
--- a/public/language/zh_CN/login.json
+++ b/public/language/zh_CN/login.json
@@ -8,5 +8,5 @@
"failed_login_attempt": "登录失败",
"login_successful": "您已经成功登录!",
"dont_have_account": "没有帐号?",
- "logged-out-due-to-inactivity": "You have been logged out of the Admin Control Panel due to inactivity"
+ "logged-out-due-to-inactivity": "由于长时间不活动,您已从控制面板注销"
}
\ No newline at end of file
diff --git a/public/language/zh_CN/modules.json b/public/language/zh_CN/modules.json
index 869a8bf0c0..b00e1c9aa4 100644
--- a/public/language/zh_CN/modules.json
+++ b/public/language/zh_CN/modules.json
@@ -37,7 +37,7 @@
"composer.formatting.picture": "图片",
"composer.upload-picture": "上传图片",
"composer.upload-file": "上传文件",
- "composer.zen_mode": "Zen Mode",
+ "composer.zen_mode": "无干扰模式",
"bootbox.ok": "确认",
"bootbox.cancel": "取消",
"bootbox.confirm": "确认",
diff --git a/public/language/zh_CN/topic.json b/public/language/zh_CN/topic.json
index 072da54e1a..0d4168ffdc 100644
--- a/public/language/zh_CN/topic.json
+++ b/public/language/zh_CN/topic.json
@@ -26,8 +26,8 @@
"tools": "工具",
"flag": "举报",
"locked": "已锁定",
- "pinned": "Pinned",
- "moved": "Moved",
+ "pinned": "已固定",
+ "moved": "已移动",
"bookmark_instructions": "点击阅读本主题帖中的最新回复",
"flag_title": "举报此帖",
"flag_success": "已举报此回帖。",
@@ -86,7 +86,7 @@
"topic_will_be_moved_to": "此主题将被移动到版块",
"fork_topic_instruction": "点击将分割的帖子",
"fork_no_pids": "未选中帖子!",
- "fork_pid_count": "%1 post(s) selected",
+ "fork_pid_count": "选择了 %1 个帖子",
"fork_success": "成功分割主题! 点这里跳转到分割后的主题。",
"delete_posts_instruction": "点击想要删除/永久删除的帖子",
"composer.title_placeholder": "在此输入您主题的标题...",
diff --git a/public/language/zh_TW/global.json b/public/language/zh_TW/global.json
index d530c0ace1..02e6ba741d 100644
--- a/public/language/zh_TW/global.json
+++ b/public/language/zh_TW/global.json
@@ -7,8 +7,10 @@
"403.login": "或許是你應該 試著登入?",
"404.title": "無法找到該頁",
"404.message": "你所查找的頁面並不存在。返回首頁。",
- "500.title": "內部錯誤",
+ "500.title": "Internal Error.",
"500.message": "糟糕! 看來是不知道哪裡出錯了!",
+ "400.title": "Bad Request.",
+ "400.message": "It looks like this link is malformed, please double-check and try again. Otherwise, return to the home page.",
"register": "註冊",
"login": "登入",
"please_log_in": "請先登入",
@@ -93,5 +95,6 @@
"upload_file": "上傳檔案",
"upload": "上傳",
"allowed-file-types": "允許的檔案類型是 %1",
- "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?"
+ "unsaved-changes": "You have unsaved changes. Are you sure you wish to navigate away?",
+ "reconnecting-message": "Looks like your connection to %1 was lost, please wait while we try to reconnect."
}
\ No newline at end of file
diff --git a/public/language/zh_TW/modules.json b/public/language/zh_TW/modules.json
index e02c0908f1..61d9b00cea 100644
--- a/public/language/zh_TW/modules.json
+++ b/public/language/zh_TW/modules.json
@@ -37,7 +37,7 @@
"composer.formatting.picture": "圖片",
"composer.upload-picture": "上傳圖片",
"composer.upload-file": "上傳檔案",
- "composer.zen_mode": "Zen Mode",
+ "composer.zen_mode": "禪(Zen)模式",
"bootbox.ok": "好",
"bootbox.cancel": "取消",
"bootbox.confirm": "確認",
diff --git a/public/less/admin/admin.less b/public/less/admin/admin.less
index ed15e562e4..0ceeb050e5 100644
--- a/public/less/admin/admin.less
+++ b/public/less/admin/admin.less
@@ -265,4 +265,10 @@ body {
[class^="col-"] .mdl-switch__label {
padding-right: 15px;
+}
+
+.ui-selectable-helper {
+ border: 1px dashed @brand-success;
+ background: lighten(@brand-success, 10%);
+ opacity: 0.5;
}
\ No newline at end of file
diff --git a/public/less/admin/bootstrap/bootstrap.less b/public/less/admin/bootstrap/bootstrap.less
index 1c0477805f..f0aa08f3a6 100644
--- a/public/less/admin/bootstrap/bootstrap.less
+++ b/public/less/admin/bootstrap/bootstrap.less
@@ -1,6 +1,6 @@
/*!
- * Bootstrap v3.3.6 (http://getbootstrap.com)
- * Copyright 2011-2015 Twitter, Inc.
+ * Bootstrap v3.3.7 (http://getbootstrap.com)
+ * Copyright 2011-2016 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
diff --git a/public/less/admin/bootstrap/button-groups.less b/public/less/admin/bootstrap/button-groups.less
index 293245a650..16db0c6135 100644
--- a/public/less/admin/bootstrap/button-groups.less
+++ b/public/less/admin/bootstrap/button-groups.less
@@ -59,7 +59,7 @@
.border-right-radius(0);
}
}
-// Need .dropdown-toggle since :last-child doesn't apply given a .dropdown-menu immediately after it
+// Need .dropdown-toggle since :last-child doesn't apply, given that a .dropdown-menu is used immediately after it
.btn-group > .btn:last-child:not(:first-child),
.btn-group > .dropdown-toggle:not(:first-child) {
.border-left-radius(0);
diff --git a/public/less/admin/bootstrap/forms.less b/public/less/admin/bootstrap/forms.less
index e8b071a138..9377d3846b 100644
--- a/public/less/admin/bootstrap/forms.less
+++ b/public/less/admin/bootstrap/forms.less
@@ -181,7 +181,7 @@ input[type="search"] {
// set a pixel line-height that matches the given height of the input, but only
// for Safari. See https://bugs.webkit.org/show_bug.cgi?id=139848
//
-// Note that as of 8.3, iOS doesn't support `datetime` or `week`.
+// Note that as of 9.3, iOS doesn't support `week`.
@media screen and (-webkit-min-device-pixel-ratio: 0) {
input[type="date"],
diff --git a/public/less/admin/bootstrap/input-groups.less b/public/less/admin/bootstrap/input-groups.less
index 5f73eec40c..d0763db7ff 100644
--- a/public/less/admin/bootstrap/input-groups.less
+++ b/public/less/admin/bootstrap/input-groups.less
@@ -29,7 +29,7 @@
width: 100%;
margin-bottom: 0;
-
+
&:focus {
z-index: 3;
}
diff --git a/public/less/admin/bootstrap/mixins/tab-focus.less b/public/less/admin/bootstrap/mixins/tab-focus.less
index 1f1f05ab05..d12d23629f 100644
--- a/public/less/admin/bootstrap/mixins/tab-focus.less
+++ b/public/less/admin/bootstrap/mixins/tab-focus.less
@@ -1,9 +1,9 @@
// WebKit-style focus
.tab-focus() {
- // Default
- outline: thin dotted;
- // WebKit
+ // WebKit-specific. Other browsers will keep their default outline style.
+ // (Initially tried to also force default via `outline: initial`,
+ // but that seems to erroneously remove the outline in Firefox altogether.)
outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px;
}
diff --git a/public/less/admin/bootstrap/panels.less b/public/less/admin/bootstrap/panels.less
index 425eb5e642..65aa3a83f3 100644
--- a/public/less/admin/bootstrap/panels.less
+++ b/public/less/admin/bootstrap/panels.less
@@ -214,7 +214,7 @@
}
-// Collapsable panels (aka, accordion)
+// Collapsible panels (aka, accordion)
//
// Wrap a series of panels in `.panel-group` to turn them into an accordion with
// the help of our collapse JavaScript plugin.
diff --git a/public/less/admin/bootstrap/scaffolding.less b/public/less/admin/bootstrap/scaffolding.less
index 1929bfc5cf..64a29c6a5e 100644
--- a/public/less/admin/bootstrap/scaffolding.less
+++ b/public/less/admin/bootstrap/scaffolding.less
@@ -120,7 +120,7 @@ hr {
// Only display content to screen readers
//
-// See: http://a11yproject.com/posts/how-to-hide-content/
+// See: http://a11yproject.com/posts/how-to-hide-content
.sr-only {
position: absolute;
diff --git a/public/less/admin/bootstrap/theme.less b/public/less/admin/bootstrap/theme.less
index 8f51d913dc..fb6174427b 100644
--- a/public/less/admin/bootstrap/theme.less
+++ b/public/less/admin/bootstrap/theme.less
@@ -1,6 +1,6 @@
/*!
- * Bootstrap v3.3.6 (http://getbootstrap.com)
- * Copyright 2011-2015 Twitter, Inc.
+ * Bootstrap v3.3.7 (http://getbootstrap.com)
+ * Copyright 2011-2016 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
diff --git a/public/less/admin/bootstrap/variables.less b/public/less/admin/bootstrap/variables.less
index d0cf54f043..eed5b3cfae 100644
--- a/public/less/admin/bootstrap/variables.less
+++ b/public/less/admin/bootstrap/variables.less
@@ -1,4 +1,4 @@
-// Paper 3.3.5
+// Paper 3.3.7
// Variables
// --------------------------------------------------
@@ -102,16 +102,16 @@
@line-height-large: 1.3333333; // extra decimals for Win 8.1 Chrome
@line-height-small: 1.5;
-@border-radius-base: 0px;
-@border-radius-large: 0px;
-@border-radius-small: 0px;
+@border-radius-base: 3px;
+@border-radius-large: 3px;
+@border-radius-small: 3px;
//** Global color for active items (e.g., navs or dropdowns).
@component-active-color: #fff;
//** Global background color for active items (e.g., navs or dropdowns).
@component-active-bg: @brand-primary;
-//** Width of the `border` for generating carets that indicator dropdowns.
+//** Width of the `border` for generating carets that indicate dropdowns.
@caret-width-base: 4px;
//** Carets increase slightly in size for larger components.
@caret-width-large: 5px;
@@ -486,7 +486,7 @@
@jumbotron-padding: 30px;
@jumbotron-color: inherit;
-@jumbotron-bg: #f9f9f9;
+@jumbotron-bg: #f5f5f5;
@jumbotron-heading-color: @headings-color;
@jumbotron-font-size: ceil((@font-size-base * 1.5));
@jumbotron-heading-font-size: ceil((@font-size-base * 4.5));
@@ -555,7 +555,7 @@
//** Popover outer arrow width
@popover-arrow-outer-width: (@popover-arrow-width + 1);
//** Popover outer arrow color
-@popover-arrow-outer-color: fadein(@popover-border-color, 7.5%);
+@popover-arrow-outer-color: fadein(@popover-border-color, 12%);
//** Popover outer arrow fallback color
@popover-arrow-outer-fallback-color: darken(@popover-fallback-border-color, 20%);
@@ -760,7 +760,7 @@
//
//##
-@well-bg: #f9f9f9;
+@well-bg: #f5f5f5;
@well-border: transparent;
@@ -866,4 +866,4 @@
//** Point at which .dl-horizontal becomes horizontal
@dl-horizontal-breakpoint: @grid-float-breakpoint;
//** Horizontal line color.
-@hr-border: @gray-lighter;
+@hr-border: @gray-lighter;
\ No newline at end of file
diff --git a/public/less/admin/general/navigation.less b/public/less/admin/general/navigation.less
index e56f4cc409..86fd3cae62 100644
--- a/public/less/admin/general/navigation.less
+++ b/public/less/admin/general/navigation.less
@@ -1,7 +1,8 @@
#navigation {
#active-navigation {
width: 100%;
-
+ min-height: 50px;
+ border: 1px solid #eee;
.active {
background-color: #eee;
}
diff --git a/public/less/admin/manage/tags.less b/public/less/admin/manage/tags.less
index 6800778237..34075816b1 100644
--- a/public/less/admin/manage/tags.less
+++ b/public/less/admin/manage/tags.less
@@ -5,14 +5,23 @@
}
.tag-row {
- padding: 5px;
+ padding: 0.5rem;
float: left;
+ margin-left: 0.5rem;
.tag-item {
cursor: pointer;
display: inline-block;
font-size: 11px;
}
+
+ &.ui-selected {
+ background: lighten(@brand-success, 25%);
+ }
+
+ &.ui-selecting {
+ background: lighten(@brand-success, 40%);
+ }
}
}
diff --git a/public/less/admin/manage/users.less b/public/less/admin/manage/users.less
index bed33b77a1..0ab74c7544 100644
--- a/public/less/admin/manage/users.less
+++ b/public/less/admin/manage/users.less
@@ -16,6 +16,7 @@
height: auto;
max-width: 145px;
min-width: 145px;
+ padding: 1rem;
img, .user-icon {
.user-icon-style(80px, 4rem);
@@ -44,5 +45,13 @@
}
}
}
+
+ .ui-selected {
+ background: lighten(@brand-success, 25%);
+ }
+
+ .ui-selecting {
+ background: lighten(@brand-success, 40%);
+ }
}
}
\ No newline at end of file
diff --git a/public/src/admin/general/navigation.js b/public/src/admin/general/navigation.js
index 94fbe01549..9ebdce555a 100644
--- a/public/src/admin/general/navigation.js
+++ b/public/src/admin/general/navigation.js
@@ -66,7 +66,7 @@ define('admin/general/navigation', ['translator', 'iconSelect'], function(transl
data = id === 'custom' ? {iconClass: 'fa-navicon'} : available[id];
data.enabled = false;
- data.index = parseInt($('#enabled').children().last().attr('data-index'), 10) + 1;
+ data.index = (parseInt($('#enabled').children().last().attr('data-index'), 10) || 0) + 1;
templates.parse('admin/general/navigation', 'navigation', {navigation: [data]}, function(li) {
li = $(translator.unescape(li));
diff --git a/public/src/admin/manage/flags.js b/public/src/admin/manage/flags.js
index 7a89c24845..a686c4a07e 100644
--- a/public/src/admin/manage/flags.js
+++ b/public/src/admin/manage/flags.js
@@ -3,10 +3,9 @@
define('admin/manage/flags', [
'forum/infinitescroll',
- 'admin/modules/selectable',
'autocomplete',
'Chart'
-], function(infinitescroll, selectable, autocomplete, Chart) {
+], function(infinitescroll, autocomplete, Chart) {
var Flags = {};
diff --git a/public/src/admin/manage/tags.js b/public/src/admin/manage/tags.js
index 9fda81eccb..0c0bc368c3 100644
--- a/public/src/admin/manage/tags.js
+++ b/public/src/admin/manage/tags.js
@@ -80,7 +80,7 @@ define('admin/manage/tags', [
function handleModify() {
$('#modify').on('click', function() {
- var tagsToModify = $('.tag-row.selected');
+ var tagsToModify = $('.tag-row.ui-selected');
if (!tagsToModify.length) {
return;
}
@@ -120,7 +120,7 @@ define('admin/manage/tags', [
function handleDeleteSelected() {
$('#deleteSelected').on('click', function() {
- var tagsToDelete = $('.tag-row.selected');
+ var tagsToDelete = $('.tag-row.ui-selected');
if (!tagsToDelete.length) {
return;
}
diff --git a/public/src/admin/manage/users.js b/public/src/admin/manage/users.js
index 7138bb01b9..d570941940 100644
--- a/public/src/admin/manage/users.js
+++ b/public/src/admin/manage/users.js
@@ -1,34 +1,41 @@
"use strict";
-/* global socket, define, templates, bootbox, app, ajaxify */
+/* global config, socket, define, templates, bootbox, app, ajaxify */
-define('admin/manage/users', ['admin/modules/selectable'], function(selectable) {
+define('admin/manage/users', ['admin/modules/selectable', 'translator'], function(selectable, translator) {
var Users = {};
Users.init = function() {
- selectable.enable('#users-container', '.user-selectable');
+ selectable.enable('#users-container', '.users-box');
+
+ var navPills = $('.nav-pills li');
+ var pathname = window.location.pathname;
+ if (!navPills.find('a[href="' + pathname + '"]').length) {
+ pathname = config.relative_path + '/admin/manage/users/latest';
+ }
+ navPills.removeClass('active').find('a[href="' + pathname + '"]').parent().addClass('active');
function getSelectedUids() {
var uids = [];
- $('#users-container .users-box .selected').each(function() {
- uids.push($(this).parents('[data-uid]').attr('data-uid'));
+ $('#users-container .users-box.ui-selected').each(function() {
+ uids.push(this.getAttribute('data-uid'));
});
return uids;
}
function update(className, state) {
- $('#users-container .users-box .selected').siblings('.labels').find(className).each(function() {
+ $('#users-container .users-box.ui-selected .labels').find(className).each(function() {
$(this).toggleClass('hide', !state);
});
}
function unselectAll() {
- $('#users-container .users-box .selected').removeClass('selected');
+ $('#users-container .users-box.ui-selected').removeClass('ui-selected');
}
function removeSelected() {
- $('#users-container .users-box .selected').parents('.users-box').remove();
+ $('#users-container .users-box.ui-selected').remove();
}
function done(successMessage, className, flag) {
@@ -231,47 +238,68 @@ define('admin/manage/users', ['admin/modules/selectable'], function(selectable)
});
function handleUserCreate() {
- var errorEl = $('#create-modal-error');
$('#createUser').on('click', function() {
- $('#create-modal').modal('show');
- $('#create-modal form')[0].reset();
- errorEl.addClass('hide');
+ templates.parse('admin/partials/create_user_modal', {}, function(html) {
+ translator.translate(html, function(html) {
+ bootbox.dialog({
+ message: html,
+ title: 'Create User',
+ onEscape: true,
+ buttons: {
+ cancel: {
+ label: 'Cancel',
+ className: 'btn-link'
+ },
+ create: {
+ label: 'Create',
+ className: 'btn-primary',
+ callback: function() {
+ createUser.call(this);
+ return false;
+ }
+ }
+ }
+ });
+ });
+ });
});
+ }
- $('#create-modal-go').on('click', function() {
- var username = $('#create-user-name').val(),
- email = $('#create-user-email').val(),
- password = $('#create-user-password').val(),
- passwordAgain = $('#create-user-password-again').val();
+ function createUser() {
+ var modal = this;
+ var username = document.getElementById('create-user-name').value;
+ var email = document.getElementById('create-user-email').value;
+ var password = document.getElementById('create-user-password').value;
+ var passwordAgain = document.getElementById('create-user-password-again').value;
+ var errorEl = $('#create-modal-error');
- if (password !== passwordAgain) {
- return errorEl.html('Error
Passwords must match!
').removeClass('hide'); + if (password !== passwordAgain) { + return errorEl.html('ErrorPasswords must match!
').removeClass('hide'); + } + + var user = { + username: username, + email: email, + password: password + }; + + socket.emit('admin.user.createUser', user, function(err) { + if(err) { + return errorEl.translateHtml('Error' + err.message + '
').removeClass('hide'); } - var user = { - username: username, - email: email, - password: password - }; - - socket.emit('admin.user.createUser', user, function(err) { - if(err) { - return errorEl.translateHtml('Error' + err.message + '
').removeClass('hide'); - } - $('#create-modal').modal('hide'); - $('#create-modal').on('hidden.bs.modal', function() { - ajaxify.refresh(); - }); - app.alertSuccess('User created!'); + modal.modal('hide'); + modal.on('hidden.bs.modal', function() { + ajaxify.refresh(); }); - + app.alertSuccess('User created!'); }); } var timeoutId = 0; - $('.nav-pills li').removeClass('active').find('a[href="' + window.location.pathname + '"]').parent().addClass('active'); + $('#search-user-name, #search-user-email, #search-user-ip').on('keyup', function() { if (timeoutId !== 0) { @@ -307,7 +335,7 @@ define('admin/manage/users', ['admin/modules/selectable'], function(selectable) .removeClass('label-danger'); } - selectable.enable('#users-container', '.user-selectable'); + selectable.enable('#users-container', '.users-box'); }); }); }, 250); diff --git a/public/src/admin/modules/selectable.js b/public/src/admin/modules/selectable.js index 81b4fcf06f..815fa26d0f 100644 --- a/public/src/admin/modules/selectable.js +++ b/public/src/admin/modules/selectable.js @@ -5,74 +5,11 @@ define('admin/modules/selectable', function() { var selectable = {}; - // modified from http://threedubmedia.com/code/event/drop/demo/selection - selectable.enable = function(parentElement, elementsToSelect, events) { - function selected(element) { - var $element = $(element).toggleClass('selected'); - - if (events && typeof events.onSelected === 'function') { - events.onSelected($element); - } - } - - function unselected(element) { - var $element = $(element).removeClass('selected'); - - if (events && typeof events.onUnselected === 'function') { - events.onUnselected($element); - } - } - - parentElement = $(parentElement); - elementsToSelect = $(elementsToSelect).not('.selection'); - - var offset = parentElement.offset(); - - parentElement - .addClass('selectable') - .on('mousedown', function(ev) { - if (!ev.shiftKey) { - unselected(elementsToSelect); - } - }) - .drag('start',function(ev, dd) { - if (!ev.shiftKey) { - unselected(elementsToSelect); - } - - return $('') - .css('opacity', 0.65 ) - .appendTo(parentElement); - }) - .drag(function(ev, dd){ - $(dd.proxy).css({ - top: Math.min(ev.pageY - offset.top, dd.startY - offset.top), - left: Math.min(ev.pageX - offset.left, dd.startX - offset.left), - height: Math.abs(ev.pageY - dd.startY), - width: Math.abs(ev.pageX - dd.startX) - }); - }) - .drag('end',function(ev, dd){ - $(dd.proxy).remove(); + selectable.enable = function(containerEl, targets) { + app.loadJQueryUI(function() { + $(containerEl).selectable({ + filter: targets }); - - elementsToSelect - .addClass('selection') - .on('mouseup', function(ev) { - selected(this); - }) - .drop('start',function(){ - $(this).addClass('active'); - }) - .drop(function( ev, dd ){ - selected(this); - }) - .drop('end',function(){ - $(this).removeClass('active'); - }); - - $.drop({ - multi: true }); }; diff --git a/public/src/admin/settings.js b/public/src/admin/settings.js index 9e616cfe80..d6436ccefc 100644 --- a/public/src/admin/settings.js +++ b/public/src/admin/settings.js @@ -93,6 +93,8 @@ define('admin/settings', ['uploader'], function(uploader) { message: 'Your changes to the NodeBB configuration have been saved.', type: 'success' }); + + $(window).trigger('action:admin.settingsSaved'); }); }); @@ -109,7 +111,9 @@ define('admin/settings', ['uploader'], function(uploader) { callback(); } - $(window).trigger('action:admin.settingsLoaded'); + setTimeout(function() { + $(window).trigger('action:admin.settingsLoaded'); + }, 0); }; function handleUploads() { diff --git a/public/src/admin/settings/email.js b/public/src/admin/settings/email.js index e6015b3b32..78a058e19d 100644 --- a/public/src/admin/settings/email.js +++ b/public/src/admin/settings/email.js @@ -8,6 +8,11 @@ define('admin/settings/email', ['admin/settings'], function(settings) { module.init = function() { configureEmailTester(); configureEmailEditor(); + + $(window).on('action:admin.settingsLoaded action:admin.settingsSaved', handleDigestHourChange); + $(window).on('action:admin.settingsSaved', function() { + socket.emit('admin.user.restartJobs'); + }); }; function configureEmailTester() { @@ -57,5 +62,30 @@ define('admin/settings/email', ['admin/settings'], function(settings) { }); } + function handleDigestHourChange() { + var hour = parseInt($('#digestHour').val(), 10); + + if (isNaN(hour)) { + hour = 17; + } else if (hour > 23 || hour < 0) { + hour = 0; + } + + socket.emit('meta.getServerTime', {}, function(err, now) { + now = new Date(now); + + $('#serverTime').text(now.toString()); + + now.setHours(parseInt(hour, 10), 0, 0, 0); + + // If adjusted time is in the past, move to next day + if (now.getTime() < Date.now()) { + now.setDate(now.getDate() + 1); + } + + $('#nextDigestTime').text(now.toString()); + }); + } + return module; }); diff --git a/public/src/ajaxify.js b/public/src/ajaxify.js index de20693eb0..87122bf78c 100644 --- a/public/src/ajaxify.js +++ b/public/src/ajaxify.js @@ -198,8 +198,6 @@ $(document).ready(function() { } var count = 2; - ajaxify.variables.parse(); - ajaxify.loadScript(tpl_url, done); ajaxify.widgets.render(tpl_url, url, done); @@ -209,6 +207,14 @@ $(document).ready(function() { app.processPage(); }; + ajaxify.parseData = function() { + var dataEl = $('#ajaxify-data'); + if (dataEl.length) { + ajaxify.data = JSON.parse(dataEl.text()); + dataEl.remove(); + } + }; + ajaxify.removeRelativePath = function(url) { if (url.startsWith(RELATIVE_PATH.slice(1))) { url = url.slice(RELATIVE_PATH.length); @@ -216,11 +222,7 @@ $(document).ready(function() { return url; }; - ajaxify.refresh = function(e, callback) { - if (e && e instanceof jQuery.Event) { - e.preventDefault(); - } - + ajaxify.refresh = function(callback) { ajaxify.go(ajaxify.currentPage + window.location.search + window.location.hash, callback, true); }; @@ -334,9 +336,7 @@ $(document).ready(function() { return; } - var internalLink = this.host === '' || // Relative paths are always internal links - (this.host === window.location.host && this.protocol === window.location.protocol && // Otherwise need to check if protocol and host match - (RELATIVE_PATH.length > 0 ? this.pathname.indexOf(RELATIVE_PATH) === 0 : true)); // Subfolder installs need this additional check + var internalLink = utils.isInternalURI(this, window.location, RELATIVE_PATH); if ($(this).attr('data-ajaxify') === 'false') { if (!internalLink) { @@ -381,7 +381,8 @@ $(document).ready(function() { app.load(); $('[data-template]').each(function() { - templates.cache[$(this).attr('data-template')] = $(this).html(); + templates.cache[$(this).attr('data-template')] = $('').html($(this).html()).text(); + $(this).parent().remove(); }); }); \ No newline at end of file diff --git a/public/src/app.js b/public/src/app.js index 66257e7980..e086787215 100644 --- a/public/src/app.js +++ b/public/src/app.js @@ -24,6 +24,7 @@ app.cacheBuster = null; var url = ajaxify.start(window.location.pathname.slice(1) + window.location.search + window.location.hash); ajaxify.updateHistory(url, true); + ajaxify.parseData(); ajaxify.end(url, app.template); handleStatusChange(); @@ -189,12 +190,12 @@ app.cacheBuster = null; } } - app.createUserTooltips = function(els) { + app.createUserTooltips = function(els, placement) { els = els || $('body'); els.find('.avatar,img[title].teaser-pic,img[title].user-img,div.user-icon,span.user-icon').each(function() { if (!utils.isTouchDevice()) { $(this).tooltip({ - placement: 'top', + placement: placement || $(this).attr('title-placement') || 'top', title: $(this).attr('title') }); } @@ -500,7 +501,7 @@ app.cacheBuster = null; var scriptEl = document.createElement('script'); scriptEl.type = 'text/javascript'; - scriptEl.src = config.relative_path + '/vendor/jquery/js/jquery-ui-1.10.4.custom.js' + (app.cacheBuster ? '?v=' + app.cacheBuster : ''); + scriptEl.src = config.relative_path + '/vendor/jquery/js/jquery-ui.js' + (app.cacheBuster ? '?v=' + app.cacheBuster : ''); scriptEl.onload = callback; document.head.appendChild(scriptEl); }; diff --git a/public/src/client/account/edit.js b/public/src/client/account/edit.js index db600a2f55..6cbea282d0 100644 --- a/public/src/client/account/edit.js +++ b/public/src/client/account/edit.js @@ -2,12 +2,10 @@ /* globals define, ajaxify, socket, app, config, templates, bootbox */ -define('forum/account/edit', ['forum/account/header', 'uploader', 'translator'], function(header, uploader, translator) { - var AccountEdit = {}, - uploadedPicture = ''; +define('forum/account/edit', ['forum/account/header', 'uploader', 'translator', 'components'], function(header, uploader, translator, components) { + var AccountEdit = {}; AccountEdit.init = function() { - uploadedPicture = ajaxify.data.uploadedpicture; header.init(); @@ -59,17 +57,15 @@ define('forum/account/edit', ['forum/account/header', 'uploader', 'translator'], } function updateHeader(picture) { - require(['components'], function(components) { - if (parseInt(ajaxify.data.theirid, 10) !== parseInt(ajaxify.data.yourid, 10)) { - return; - } + if (parseInt(ajaxify.data.theirid, 10) !== parseInt(ajaxify.data.yourid, 10)) { + return; + } - components.get('header/userpicture')[picture ? 'show' : 'hide'](); - components.get('header/usericon')[!picture ? 'show' : 'hide'](); - if (picture) { - components.get('header/userpicture').attr('src', picture); - } - }); + components.get('header/userpicture')[picture ? 'show' : 'hide'](); + components.get('header/usericon')[!picture ? 'show' : 'hide'](); + if (picture) { + components.get('header/userpicture').attr('src', picture); + } } function handleImageChange() { @@ -137,8 +133,8 @@ define('forum/account/edit', ['forum/account/header', 'uploader', 'translator'], } function saveSelection() { - var type = modal.find('.list-group-item.active').attr('data-type'), - src = modal.find('.list-group-item.active img').attr('src'); + var type = modal.find('.list-group-item.active').attr('data-type'); + changeUserPicture(type, function(err) { if (err) { return app.alertError(err.message); @@ -176,7 +172,7 @@ define('forum/account/edit', ['forum/account/header', 'uploader', 'translator'], if (err) { return app.alertError(err.message); } - + window.location.href = config.relative_path + '/'; }); } @@ -192,15 +188,17 @@ define('forum/account/edit', ['forum/account/header', 'uploader', 'translator'], function handleImageUpload(modal) { function onUploadComplete(urlOnServer) { - urlOnServer = urlOnServer + '?' + new Date().getTime(); + urlOnServer = urlOnServer + '?' + Date.now(); updateHeader(urlOnServer); if (ajaxify.data.picture.length) { $('#user-current-picture, img.avatar').attr('src', urlOnServer); - uploadedPicture = urlOnServer; + ajaxify.data.uploadedpicture = urlOnServer; } else { - ajaxify.refresh(); + ajaxify.refresh(function() { + $('#user-current-picture, img.avatar').attr('src', urlOnServer); + }); } } diff --git a/public/src/client/account/followers.js b/public/src/client/account/followers.js index 91d3f4daaa..8a2d15f0b0 100644 --- a/public/src/client/account/followers.js +++ b/public/src/client/account/followers.js @@ -1,43 +1,13 @@ 'use strict'; -/* globals define, socket, utils */ +/* globals define */ -define('forum/account/followers', ['forum/account/header', 'forum/infinitescroll'], function(header, infinitescroll) { +define('forum/account/followers', ['forum/account/header'], function(header) { var Followers = {}; Followers.init = function() { header.init(); - - infinitescroll.init(function(direction) { - Followers.loadMore(direction, 'account/followers', 'followers:' + ajaxify.data.uid); - }); }; - Followers.loadMore = function(direction, tpl, set) { - if (direction < 0) { - return; - } - - infinitescroll.loadMore('user.loadMore', { - set: set, - after: $('#users-container').attr('data-nextstart') - }, function(data, done) { - if (data.users && data.users.length) { - onUsersLoaded(tpl, data.users, done); - $('#users-container').attr('data-nextstart', data.nextStart); - } else { - done(); - } - }); - }; - - function onUsersLoaded(tpl, users, callback) { - app.parseAndTranslate(tpl, 'users', {users: users}, function(html) { - $('#users-container').append(html); - utils.addCommasToNumbers(html.find('.formatted-number')); - callback(); - }); - } - return Followers; }); diff --git a/public/src/client/account/following.js b/public/src/client/account/following.js index 8e421b1892..04230fb979 100644 --- a/public/src/client/account/following.js +++ b/public/src/client/account/following.js @@ -2,15 +2,11 @@ /* globals define */ -define('forum/account/following', ['forum/account/header', 'forum/infinitescroll', 'forum/account/followers'], function(header, infinitescroll, followers) { +define('forum/account/following', ['forum/account/header'], function(header) { var Following = {}; Following.init = function() { header.init(); - - infinitescroll.init(function(direction) { - followers.loadMore(direction, 'account/following', 'following:' + ajaxify.data.uid); - }); }; return Following; diff --git a/public/src/client/account/header.js b/public/src/client/account/header.js index 6b39b7f2da..97f062de11 100644 --- a/public/src/client/account/header.js +++ b/public/src/client/account/header.js @@ -1,23 +1,26 @@ 'use strict'; -/* globals define, app, config, ajaxify, socket, bootbox, translator */ +/* globals define, app, config, ajaxify, socket, bootbox, templates */ define('forum/account/header', [ 'coverPhoto', 'uploader', - 'components' -], function(coverPhoto, uploader, components) { - var AccountHeader = {}, - yourid, - theirid; + 'components', + 'translator' +], function(coverPhoto, uploader, components, translator) { + var AccountHeader = {}; + var yourid; + var theirid; + var isAdminOrSelfOrGlobalMod; AccountHeader.init = function() { yourid = ajaxify.data.yourid; theirid = ajaxify.data.theirid; + isAdminOrSelfOrGlobalMod = ajaxify.data.isAdmin || ajaxify.data.isSelf || ajaxify.data.isGlobalModerator; hidePrivateLinks(); selectActivePill(); - if (parseInt(yourid, 10) === parseInt(theirid, 10)) { + if (isAdminOrSelfOrGlobalMod) { setupCoverPhoto(); } diff --git a/public/src/client/account/settings.js b/public/src/client/account/settings.js index 1060492bf0..cc9aaf0439 100644 --- a/public/src/client/account/settings.js +++ b/public/src/client/account/settings.js @@ -2,7 +2,7 @@ /*global define, socket, app, ajaxify, config*/ -define('forum/account/settings', ['forum/account/header', 'components'], function(header, components) { +define('forum/account/settings', ['forum/account/header', 'components', 'sounds'], function(header, components, sounds) { var AccountSettings = {}; AccountSettings.init = function() { @@ -33,6 +33,13 @@ define('forum/account/settings', ['forum/account/header', 'components'], functio $('[data-property="homePageRoute"]').on('change', toggleCustomRoute); + $('.account').find('button[data-action="play"]').on('click', function(e) { + e.preventDefault(); + + var fileName = $(this).parent().parent().find('select').val(); + sounds.playFile(fileName); + }); + toggleCustomRoute(); components.get('user/sessions').find('.timeago').timeago(); @@ -77,10 +84,14 @@ define('forum/account/settings', ['forum/account/header', 'components'], functio if (key === 'userLang' && config.userLang !== newSettings.userLang) { requireReload = true; } - config[key] = newSettings[key]; + if (config.hasOwnProperty(key)) { + config[key] = newSettings[key]; + } } } + sounds.reloadMapping(); + if (requireReload && parseInt(app.user.uid, 10) === parseInt(ajaxify.data.theirid, 10)) { app.alert({ id: 'setting-change', diff --git a/public/src/client/infinitescroll.js b/public/src/client/infinitescroll.js index 42443aa27e..ed21602b01 100644 --- a/public/src/client/infinitescroll.js +++ b/public/src/client/infinitescroll.js @@ -1,8 +1,8 @@ 'use strict'; -/* globals define, socket, ajaxify, templates, app */ +/* globals define, socket, app */ -define('forum/infinitescroll', ['translator'], function(translator) { +define('forum/infinitescroll', function() { var scroll = {}; var callback; diff --git a/public/src/client/register.js b/public/src/client/register.js index ce51d695b3..4b5d5a02d6 100644 --- a/public/src/client/register.js +++ b/public/src/client/register.js @@ -6,7 +6,7 @@ define('forum/register', ['translator'], function(translator) { var Register = {}, validationError = false, - successIcon = ''; + successIcon = ''; Register.init = function() { var email = $('#email'), @@ -211,8 +211,8 @@ define('forum/register', ['translator'], function(translator) { translator.translate(msg, function(msg) { element.html(msg); element.parent() - .removeClass('alert-success') - .addClass('alert-danger'); + .removeClass('register-success') + .addClass('register-danger'); element.show(); }); validationError = true; @@ -222,8 +222,8 @@ define('forum/register', ['translator'], function(translator) { translator.translate(msg, function(msg) { element.html(msg); element.parent() - .removeClass('alert-danger') - .addClass('alert-success'); + .removeClass('register-danger') + .addClass('register-success'); element.show(); }); } diff --git a/public/src/client/search.js b/public/src/client/search.js index bf07ad70b6..b9632513bc 100644 --- a/public/src/client/search.js +++ b/public/src/client/search.js @@ -22,15 +22,10 @@ define('forum/search', ['search', 'autocomplete'], function(searchModule, autoco $('#advanced-search').off('submit').on('submit', function(e) { e.preventDefault(); - - var input = $('#search-input'); - - var searchData = getSearchData(); - searchData.term = input.val(); - - searchModule.query(searchData, function() { - input.val(''); + searchModule.query(getSearchData(), function() { + $('#search-input').val(''); }); + return false; }); handleSavePreferences(); @@ -43,7 +38,7 @@ define('forum/search', ['search', 'autocomplete'], function(searchModule, autoco var searchData = { in: $('#search-in').val() }; - + searchData.term = $('#search-input').val(); if (searchData.in === 'posts' || searchData.in === 'titlesposts' || searchData.in === 'titles') { searchData.by = form.find('#posted-by-user').val(); searchData.categories = form.find('#posted-in-categories').val(); @@ -71,6 +66,10 @@ define('forum/search', ['search', 'autocomplete'], function(searchModule, autoco params = utils.merge(searchData, params); if (params) { + if (params.term) { + $('#search-input').val(params.term); + } + if (params.in) { $('#search-in').val(params.in); updateFormItemVisiblity(params.in); diff --git a/public/src/client/topic/delete-posts.js b/public/src/client/topic/delete-posts.js index 1a7ce5221b..a40ef3dbc5 100644 --- a/public/src/client/topic/delete-posts.js +++ b/public/src/client/topic/delete-posts.js @@ -1,8 +1,8 @@ 'use strict'; -/* globals define, app, ajaxify, socket, templates, translator */ +/* globals define, app, ajaxify, socket, templates */ -define('forum/topic/delete-posts', ['components', 'postSelect'], function(components, postSelect) { +define('forum/topic/delete-posts', ['components', 'postSelect', 'translator'], function(components, postSelect, translator) { var DeletePosts = {}, modal, diff --git a/public/src/client/topic/postTools.js b/public/src/client/topic/postTools.js index 85a8986a4b..86fe03ce03 100644 --- a/public/src/client/topic/postTools.js +++ b/public/src/client/topic/postTools.js @@ -59,7 +59,7 @@ define('forum/topic/postTools', ['share', 'navigator', 'components', 'translator postEl.find('[component="post/restore"]').toggleClass('hidden', !isDeleted); postEl.find('[component="post/purge"]').toggleClass('hidden', !isDeleted); - postEl.find('.dropdown-menu').html(''); + postEl.find('[component="post/tools"] .dropdown-menu').html(''); }; PostTools.updatePostCount = function(postCount) { diff --git a/public/src/client/topic/posts.js b/public/src/client/topic/posts.js index 656364b3a1..3c70c09712 100644 --- a/public/src/client/topic/posts.js +++ b/public/src/client/topic/posts.js @@ -57,6 +57,7 @@ define('forum/topic/posts', [ function onNewPostPagination(data) { function scrollToPost() { scrollToPostIfSelf(data.posts[0]); + Posts.loadImages(); } var posts = data.posts; @@ -92,12 +93,13 @@ define('forum/topic/posts', [ html.addClass('new'); } scrollToPostIfSelf(data.posts[0]); + Posts.loadImages(); }); } function scrollToPostIfSelf(post) { if (!ajaxify.data.scrollToMyPost) { - return; + return; } var isSelfPost = parseInt(post.uid, 10) === parseInt(app.user.uid, 10); if (isSelfPost) { @@ -335,6 +337,10 @@ define('forum/topic/posts', [ src = $this.attr('src'), suffixRegex = /-resized(\.[\w]+)?$/; + if (src === 'about:blank') { + return; + } + if (utils.isRelativeUrl(src) && suffixRegex.test(src)) { src = src.replace(suffixRegex, '$1'); } diff --git a/public/src/client/users.js b/public/src/client/users.js index 40f221e33f..8f648e6198 100644 --- a/public/src/client/users.js +++ b/public/src/client/users.js @@ -1,16 +1,24 @@ 'use strict'; -/* globals define, socket, app, templates, bootbox, ajaxify */ +/* globals define, socket, app, templates, bootbox, utils */ define('forum/users', ['translator'], function(translator) { var Users = {}; - var loadingMoreUsers = false; + var searchTimeoutID = 0; + + $(window).on('action:ajaxify.start', function() { + if (searchTimeoutID) { + clearTimeout(searchTimeoutID); + searchTimeoutID = 0; + } + }); Users.init = function() { app.enterRoom('user_list'); - $('.nav-pills li').removeClass('active').find('a[href="' + window.location.pathname + '"]').parent().addClass('active'); + var section = utils.params().section ? ('?section=' + utils.params().section) : ''; + $('.nav-pills li').removeClass('active').find('a[href="' + window.location.pathname + section + '"]').parent().addClass('active'); handleSearch(); @@ -18,110 +26,53 @@ define('forum/users', ['translator'], function(translator) { socket.removeListener('event:user_status_change', onUserStatusChange); socket.on('event:user_status_change', onUserStatusChange); - - $('#load-more-users-btn').on('click', loadMoreUsers); - - $(window).off('scroll').on('scroll', function() { - var bottom = ($(document).height() - $(window).height()) * 0.9; - - if ($(window).scrollTop() > bottom && !loadingMoreUsers) { - loadMoreUsers(); - } - }); }; - function loadMoreUsers() { - if ($('#search-user').val()) { - return; - } - - if (ajaxify.data.setName) { - startLoading(ajaxify.data.setName, $('#users-container').children('.registered-user').length); - } - } - - function startLoading(set, after) { - loadingMoreUsers = true; - - socket.emit('user.loadMore', { - set: set, - after: after - }, function(err, data) { - if (err) { - return app.alertError(err.message); - } - - if (data && data.users.length) { - onUsersLoaded(data); - $('#load-more-users-btn').removeClass('disabled'); - } else { - $('#load-more-users-btn').addClass('disabled'); - } - loadingMoreUsers = false; - }); - } - - function onUsersLoaded(data) { - data.users = data.users.filter(function(user) { - return !$('.users-box[data-uid="' + user.uid + '"]').length; - }); - - templates.parse('users', 'users', data, function(html) { - translator.translate(html, function(translated) { - translated = $(translated); - $('#users-container').append(translated); - translated.find('span.timeago').timeago(); - utils.addCommasToNumbers(translated.find('.formatted-number')); - $('#users-container .anon-user').appendTo($('#users-container')); - }); - }); - } - function handleSearch() { - var timeoutId = 0; + searchTimeoutID = 0; $('#search-user').on('keyup', function() { - if (timeoutId) { - clearTimeout(timeoutId); - timeoutId = 0; + if (searchTimeoutID) { + clearTimeout(searchTimeoutID); + searchTimeoutID = 0; } - timeoutId = setTimeout(doSearch, 250); + searchTimeoutID = setTimeout(doSearch, 150); }); $('.search select, .search input[type="checkbox"]').on('change', function() { doSearch(); }); - - $('.users').on('click', '.pagination a', function() { - doSearch($(this).attr('data-page')); - return false; - }); } - function doSearch(page) { + function doSearch() { + $('[component="user/search/icon"]').removeClass('fa-search').addClass('fa-spinner fa-spin'); var username = $('#search-user').val(); - page = page || 1; + var activeSection = getActiveSection(); + + var query = { + section: activeSection, + page: 1 + }; if (!username) { - return loadPage(page); + return loadPage(query); } - var activeSection = getActiveSection(); - socket.emit('user.search', { - query: username, - page: page, - searchBy: 'username', - sortBy: $('.search select').val() || getSortBy(), - onlineOnly: $('.search .online-only').is(':checked') || (activeSection === 'online'), - bannedOnly: activeSection === 'banned', - flaggedOnly: activeSection === 'flagged' - }, function(err, data) { - if (err) { - return app.alertError(err.message); - } - renderSearchResults(data); - }); + query.term = username; + query.sortBy = getSortBy(); + + if ($('.search .online-only').is(':checked') || (activeSection === 'online')) { + query.onlineOnly = true; + } + if (activeSection === 'banned') { + query.bannedOnly = true; + } + if (activeSection === 'flagged') { + query.flaggedOnly = true; + } + + loadPage(query); } function getSortBy() { @@ -137,16 +88,17 @@ define('forum/users', ['translator'], function(translator) { return sortBy; } - function loadPage(page) { - var section = getActiveSection(); - section = section !== 'users' ? section : ''; - $.get('/api/users/' + section + '?page=' + page, function(data) { - renderSearchResults(data); + + function loadPage(query) { + var qs = decodeURIComponent($.param(query)); + $.get('/api/users?' + qs, renderSearchResults).fail(function(xhrErr) { + if (xhrErr && xhrErr.responseJSON && xhrErr.responseJSON.error) { + app.alertError(xhrErr.responseJSON.error); + } }); } function renderSearchResults(data) { - $('#load-more-users-btn').addClass('hide'); templates.parse('partials/paginator', {pagination: data.pagination}, function(html) { $('.pagination-container').replaceWith(html); }); @@ -156,6 +108,7 @@ define('forum/users', ['translator'], function(translator) { translated = $(translated); $('#users-container').html(translated); translated.find('span.timeago').timeago(); + $('[component="user/search/icon"]').addClass('fa-search').removeClass('fa-spinner fa-spin'); }); }); } @@ -173,9 +126,7 @@ define('forum/users', ['translator'], function(translator) { } function getActiveSection() { - var url = window.location.href; - var parts = url.split('/'); - return parts[parts.length - 1]; + return utils.params().section || ''; } function handleInvite() { diff --git a/public/src/modules/chat.js b/public/src/modules/chat.js index 445b4212e4..8e0b435434 100644 --- a/public/src/modules/chat.js +++ b/public/src/modules/chat.js @@ -113,13 +113,12 @@ define('chat', [ return room.teaser; }); - chatsListEl.empty(); - templates.parse('partials/chat_dropdown', { rooms: rooms }, function(html) { translator.translate(html, function(translated) { - chatsListEl.html(translated); + chatsListEl.empty().html(translated); + app.createUserTooltips(chatsListEl, 'right'); }); }); }); diff --git a/public/src/modules/search.js b/public/src/modules/search.js index be6ac6a711..304235c7fa 100644 --- a/public/src/modules/search.js +++ b/public/src/modules/search.js @@ -4,8 +4,8 @@ define('search', ['navigator', 'translator'], function(nav, translator) { var Search = { - current: {} - }; + current: {} + }; Search.query = function(data, callback) { var term = data.term; @@ -22,11 +22,11 @@ define('search', ['navigator', 'translator'], function(nav, translator) { return app.alertError('[[error:invalid-search-term]]'); } - ajaxify.go('search/' + term + '?' + createQueryString(data)); + ajaxify.go('search?' + createQueryString(data)); callback(); } else { - var cleanedTerm = term.replace(topicSearch[0], ''), - tid = topicSearch[1]; + var cleanedTerm = term.replace(topicSearch[0], ''); + var tid = topicSearch[1]; if (cleanedTerm.length > 0) { Search.queryTopic(tid, cleanedTerm, callback); @@ -38,8 +38,9 @@ define('search', ['navigator', 'translator'], function(nav, translator) { var searchIn = data['in'] || 'titlesposts'; var postedBy = data.by || ''; var query = { - 'in': searchIn - }; + term: data.term, + 'in': searchIn + }; if (postedBy && (searchIn === 'posts' || searchIn === 'titles' || searchIn === 'titlesposts')) { query.by = postedBy; @@ -75,7 +76,7 @@ define('search', ['navigator', 'translator'], function(nav, translator) { Search.getSearchPreferences = function() { try { - return JSON.parse(localStorage.getItem('search-preferences')); + return JSON.parse(localStorage.getItem('search-preferences') || '{}'); } catch(e) { return {}; } @@ -179,4 +180,4 @@ define('search', ['navigator', 'translator'], function(nav, translator) { }; return Search; -}); \ No newline at end of file +}); diff --git a/public/src/modules/sounds.js b/public/src/modules/sounds.js index 052e804f6e..a9a1840fd4 100644 --- a/public/src/modules/sounds.js +++ b/public/src/modules/sounds.js @@ -9,13 +9,17 @@ define('sounds', ['buzz'], function(buzz) { var files; socket.on('event:sounds.reloadMapping', function() { + Sounds.reloadMapping(); + }); + + Sounds.reloadMapping = function() { socket.emit('modules.sounds.getMapping', function(err, mapping) { if (err) { - return app.alertError('[sounds] Could not load sound mapping!'); + return app.alertError(err.message); } eventSoundMapping = mapping; }); - }); + } function loadData(callback) { socket.emit('modules.sounds.getData', function(err, data) { @@ -55,10 +59,6 @@ define('sounds', ['buzz'], function(buzz) { Sounds.playFile(eventSoundMapping[name]); } - if (!config.notificationSounds) { - return; - } - if (!eventSoundMapping) { return loadData(play); } diff --git a/public/src/modules/translator.js b/public/src/modules/translator.js index ad18721605..00a9126448 100644 --- a/public/src/modules/translator.js +++ b/public/src/modules/translator.js @@ -96,12 +96,12 @@ break; } - $.getScript(RELATIVE_PATH + '/vendor/jquery/timeago/locales/jquery.timeago.' + languageCode + '.js').success(function() { + $.getScript(RELATIVE_PATH + '/vendor/jquery/timeago/locales/jquery.timeago.' + languageCode + '.js').done(function() { $('.timeago').timeago(); translator.timeagoShort = $.extend({}, jQuery.timeago.settings.strings); // Retrieve the shorthand timeago values as well - $.getScript(RELATIVE_PATH + '/vendor/jquery/timeago/locales/jquery.timeago.' + languageCode + '-short.js').success(function() { + $.getScript(RELATIVE_PATH + '/vendor/jquery/timeago/locales/jquery.timeago.' + languageCode + '-short.js').done(function() { // Switch back to long-form translator.toggleTimeagoShorthand(); }); diff --git a/public/src/overrides.js b/public/src/overrides.js index 62eca1d568..49dce7e754 100644 --- a/public/src/overrides.js +++ b/public/src/overrides.js @@ -68,6 +68,15 @@ if ('undefined' !== typeof window) { return translate(this, 'val', str); }; + $.fn.translateAttr = function(attr, str) { + return this.each(function() { + var el = $(this); + translator.translate(str, function(translated) { + el.attr(attr, translated); + }); + }); + }; + function translate(elements, type, str) { return elements.each(function() { var el = $(this); @@ -107,7 +116,7 @@ if ('undefined' !== typeof window) { var dialog = bootbox.dialog, prompt = bootbox.prompt, confirm = bootbox.confirm; - + function translate(modal) { var header = modal.find('.modal-header'), footer = modal.find('.modal-footer'); diff --git a/public/src/require-config.js b/public/src/require-config.js new file mode 100644 index 0000000000..0ad2f8a58c --- /dev/null +++ b/public/src/require-config.js @@ -0,0 +1,11 @@ +require.config({ + baseUrl: config.relative_path + "/src/modules", + waitSeconds: 7, + urlArgs: "v=" + config['cache-buster'], + paths: { + 'forum': '../client', + 'admin': '../admin', + 'vendor': '../../vendor', + 'plugins': '../../plugins' + } +}); diff --git a/public/src/sockets.js b/public/src/sockets.js index f2a9bfd346..15eee26b5e 100644 --- a/public/src/sockets.js +++ b/public/src/sockets.js @@ -48,9 +48,11 @@ app.isConnected = false; if (reconnecting) { var reconnectEl = $('#reconnect'); + var reconnectAlert = $('#reconnect-alert'); reconnectEl.tooltip('destroy'); reconnectEl.html(''); + reconnectAlert.fadeOut(500); reconnecting = false; reJoinCurrentRoom(); @@ -102,12 +104,14 @@ app.isConnected = false; function onReconnecting() { reconnecting = true; var reconnectEl = $('#reconnect'); + var reconnectAlert = $('#reconnect-alert'); if (!reconnectEl.hasClass('active')) { reconnectEl.html(''); + reconnectAlert.fadeIn(500).removeClass('hide'); } - reconnectEl.addClass('active').removeClass("hide").tooltip({ + reconnectEl.addClass('active').removeClass('hide').tooltip({ placement: 'bottom' }); } diff --git a/public/src/utils.js b/public/src/utils.js index 5d44bcd4fa..190d0ab3c6 100644 --- a/public/src/utils.js +++ b/public/src/utils.js @@ -431,6 +431,14 @@ } return utils.props(obj[prop], newProps, value); + }, + + isInternalURI: function(targetLocation, referenceLocation, relative_path) { + return targetLocation.host === '' || // Relative paths are always internal links + ( + targetLocation.host === referenceLocation.host && targetLocation.protocol === referenceLocation.protocol && // Otherwise need to check if protocol and host match + (relative_path.length > 0 ? targetLocation.pathname.indexOf(relative_path) === 0 : true) // Subfolder installs need this additional check + ); } }; diff --git a/public/src/variables.js b/public/src/variables.js deleted file mode 100644 index 487099ac3c..0000000000 --- a/public/src/variables.js +++ /dev/null @@ -1,15 +0,0 @@ -"use strict"; -/*global ajaxify*/ - -(function(ajaxify) { - - ajaxify.variables = {}; - - ajaxify.variables.parse = function() { - var dataEl = $('#ajaxify-data'); - if (dataEl.length) { - ajaxify.data = JSON.parse(dataEl.text()); - dataEl.remove(); - } - }; -}(ajaxify || {})); diff --git a/public/vendor/bootstrap/js/bootstrap.js b/public/vendor/bootstrap/js/bootstrap.js new file mode 100644 index 0000000000..8a2e99a535 --- /dev/null +++ b/public/vendor/bootstrap/js/bootstrap.js @@ -0,0 +1,2377 @@ +/*! + * Bootstrap v3.3.7 (http://getbootstrap.com) + * Copyright 2011-2016 Twitter, Inc. + * Licensed under the MIT license + */ + +if (typeof jQuery === 'undefined') { + throw new Error('Bootstrap\'s JavaScript requires jQuery') +} + ++function ($) { + 'use strict'; + var version = $.fn.jquery.split(' ')[0].split('.') + if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] > 3)) { + throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4') + } +}(jQuery); + +/* ======================================================================== + * Bootstrap: transition.js v3.3.7 + * http://getbootstrap.com/javascript/#transitions + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) + // ============================================================ + + function transitionEnd() { + var el = document.createElement('bootstrap') + + var transEndEventNames = { + WebkitTransition : 'webkitTransitionEnd', + MozTransition : 'transitionend', + OTransition : 'oTransitionEnd otransitionend', + transition : 'transitionend' + } + + for (var name in transEndEventNames) { + if (el.style[name] !== undefined) { + return { end: transEndEventNames[name] } + } + } + + return false // explicit for ie8 ( ._.) + } + + // http://blog.alexmaccaw.com/css-transitions + $.fn.emulateTransitionEnd = function (duration) { + var called = false + var $el = this + $(this).one('bsTransitionEnd', function () { called = true }) + var callback = function () { if (!called) $($el).trigger($.support.transition.end) } + setTimeout(callback, duration) + return this + } + + $(function () { + $.support.transition = transitionEnd() + + if (!$.support.transition) return + + $.event.special.bsTransitionEnd = { + bindType: $.support.transition.end, + delegateType: $.support.transition.end, + handle: function (e) { + if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments) + } + } + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: alert.js v3.3.7 + * http://getbootstrap.com/javascript/#alerts + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // ALERT CLASS DEFINITION + // ====================== + + var dismiss = '[data-dismiss="alert"]' + var Alert = function (el) { + $(el).on('click', dismiss, this.close) + } + + Alert.VERSION = '3.3.7' + + Alert.TRANSITION_DURATION = 150 + + Alert.prototype.close = function (e) { + var $this = $(this) + var selector = $this.attr('data-target') + + if (!selector) { + selector = $this.attr('href') + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 + } + + var $parent = $(selector === '#' ? [] : selector) + + if (e) e.preventDefault() + + if (!$parent.length) { + $parent = $this.closest('.alert') + } + + $parent.trigger(e = $.Event('close.bs.alert')) + + if (e.isDefaultPrevented()) return + + $parent.removeClass('in') + + function removeElement() { + // detach from parent, fire event then clean up data + $parent.detach().trigger('closed.bs.alert').remove() + } + + $.support.transition && $parent.hasClass('fade') ? + $parent + .one('bsTransitionEnd', removeElement) + .emulateTransitionEnd(Alert.TRANSITION_DURATION) : + removeElement() + } + + + // ALERT PLUGIN DEFINITION + // ======================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.alert') + + if (!data) $this.data('bs.alert', (data = new Alert(this))) + if (typeof option == 'string') data[option].call($this) + }) + } + + var old = $.fn.alert + + $.fn.alert = Plugin + $.fn.alert.Constructor = Alert + + + // ALERT NO CONFLICT + // ================= + + $.fn.alert.noConflict = function () { + $.fn.alert = old + return this + } + + + // ALERT DATA-API + // ============== + + $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: button.js v3.3.7 + * http://getbootstrap.com/javascript/#buttons + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // BUTTON PUBLIC CLASS DEFINITION + // ============================== + + var Button = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, Button.DEFAULTS, options) + this.isLoading = false + } + + Button.VERSION = '3.3.7' + + Button.DEFAULTS = { + loadingText: 'loading...' + } + + Button.prototype.setState = function (state) { + var d = 'disabled' + var $el = this.$element + var val = $el.is('input') ? 'val' : 'html' + var data = $el.data() + + state += 'Text' + + if (data.resetText == null) $el.data('resetText', $el[val]()) + + // push to event loop to allow forms to submit + setTimeout($.proxy(function () { + $el[val](data[state] == null ? this.options[state] : data[state]) + + if (state == 'loadingText') { + this.isLoading = true + $el.addClass(d).attr(d, d).prop(d, true) + } else if (this.isLoading) { + this.isLoading = false + $el.removeClass(d).removeAttr(d).prop(d, false) + } + }, this), 0) + } + + Button.prototype.toggle = function () { + var changed = true + var $parent = this.$element.closest('[data-toggle="buttons"]') + + if ($parent.length) { + var $input = this.$element.find('input') + if ($input.prop('type') == 'radio') { + if ($input.prop('checked')) changed = false + $parent.find('.active').removeClass('active') + this.$element.addClass('active') + } else if ($input.prop('type') == 'checkbox') { + if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false + this.$element.toggleClass('active') + } + $input.prop('checked', this.$element.hasClass('active')) + if (changed) $input.trigger('change') + } else { + this.$element.attr('aria-pressed', !this.$element.hasClass('active')) + this.$element.toggleClass('active') + } + } + + + // BUTTON PLUGIN DEFINITION + // ======================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.button') + var options = typeof option == 'object' && option + + if (!data) $this.data('bs.button', (data = new Button(this, options))) + + if (option == 'toggle') data.toggle() + else if (option) data.setState(option) + }) + } + + var old = $.fn.button + + $.fn.button = Plugin + $.fn.button.Constructor = Button + + + // BUTTON NO CONFLICT + // ================== + + $.fn.button.noConflict = function () { + $.fn.button = old + return this + } + + + // BUTTON DATA-API + // =============== + + $(document) + .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) { + var $btn = $(e.target).closest('.btn') + Plugin.call($btn, 'toggle') + if (!($(e.target).is('input[type="radio"], input[type="checkbox"]'))) { + // Prevent double click on radios, and the double selections (so cancellation) on checkboxes + e.preventDefault() + // The target component still receive the focus + if ($btn.is('input,button')) $btn.trigger('focus') + else $btn.find('input:visible,button:visible').first().trigger('focus') + } + }) + .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) { + $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type)) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: carousel.js v3.3.7 + * http://getbootstrap.com/javascript/#carousel + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // CAROUSEL CLASS DEFINITION + // ========================= + + var Carousel = function (element, options) { + this.$element = $(element) + this.$indicators = this.$element.find('.carousel-indicators') + this.options = options + this.paused = null + this.sliding = null + this.interval = null + this.$active = null + this.$items = null + + this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this)) + + this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element + .on('mouseenter.bs.carousel', $.proxy(this.pause, this)) + .on('mouseleave.bs.carousel', $.proxy(this.cycle, this)) + } + + Carousel.VERSION = '3.3.7' + + Carousel.TRANSITION_DURATION = 600 + + Carousel.DEFAULTS = { + interval: 5000, + pause: 'hover', + wrap: true, + keyboard: true + } + + Carousel.prototype.keydown = function (e) { + if (/input|textarea/i.test(e.target.tagName)) return + switch (e.which) { + case 37: this.prev(); break + case 39: this.next(); break + default: return + } + + e.preventDefault() + } + + Carousel.prototype.cycle = function (e) { + e || (this.paused = false) + + this.interval && clearInterval(this.interval) + + this.options.interval + && !this.paused + && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) + + return this + } + + Carousel.prototype.getItemIndex = function (item) { + this.$items = item.parent().children('.item') + return this.$items.index(item || this.$active) + } + + Carousel.prototype.getItemForDirection = function (direction, active) { + var activeIndex = this.getItemIndex(active) + var willWrap = (direction == 'prev' && activeIndex === 0) + || (direction == 'next' && activeIndex == (this.$items.length - 1)) + if (willWrap && !this.options.wrap) return active + var delta = direction == 'prev' ? -1 : 1 + var itemIndex = (activeIndex + delta) % this.$items.length + return this.$items.eq(itemIndex) + } + + Carousel.prototype.to = function (pos) { + var that = this + var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active')) + + if (pos > (this.$items.length - 1) || pos < 0) return + + if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid" + if (activeIndex == pos) return this.pause().cycle() + + return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos)) + } + + Carousel.prototype.pause = function (e) { + e || (this.paused = true) + + if (this.$element.find('.next, .prev').length && $.support.transition) { + this.$element.trigger($.support.transition.end) + this.cycle(true) + } + + this.interval = clearInterval(this.interval) + + return this + } + + Carousel.prototype.next = function () { + if (this.sliding) return + return this.slide('next') + } + + Carousel.prototype.prev = function () { + if (this.sliding) return + return this.slide('prev') + } + + Carousel.prototype.slide = function (type, next) { + var $active = this.$element.find('.item.active') + var $next = next || this.getItemForDirection(type, $active) + var isCycling = this.interval + var direction = type == 'next' ? 'left' : 'right' + var that = this + + if ($next.hasClass('active')) return (this.sliding = false) + + var relatedTarget = $next[0] + var slideEvent = $.Event('slide.bs.carousel', { + relatedTarget: relatedTarget, + direction: direction + }) + this.$element.trigger(slideEvent) + if (slideEvent.isDefaultPrevented()) return + + this.sliding = true + + isCycling && this.pause() + + if (this.$indicators.length) { + this.$indicators.find('.active').removeClass('active') + var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)]) + $nextIndicator && $nextIndicator.addClass('active') + } + + var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid" + if ($.support.transition && this.$element.hasClass('slide')) { + $next.addClass(type) + $next[0].offsetWidth // force reflow + $active.addClass(direction) + $next.addClass(direction) + $active + .one('bsTransitionEnd', function () { + $next.removeClass([type, direction].join(' ')).addClass('active') + $active.removeClass(['active', direction].join(' ')) + that.sliding = false + setTimeout(function () { + that.$element.trigger(slidEvent) + }, 0) + }) + .emulateTransitionEnd(Carousel.TRANSITION_DURATION) + } else { + $active.removeClass('active') + $next.addClass('active') + this.sliding = false + this.$element.trigger(slidEvent) + } + + isCycling && this.cycle() + + return this + } + + + // CAROUSEL PLUGIN DEFINITION + // ========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.carousel') + var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option) + var action = typeof option == 'string' ? option : options.slide + + if (!data) $this.data('bs.carousel', (data = new Carousel(this, options))) + if (typeof option == 'number') data.to(option) + else if (action) data[action]() + else if (options.interval) data.pause().cycle() + }) + } + + var old = $.fn.carousel + + $.fn.carousel = Plugin + $.fn.carousel.Constructor = Carousel + + + // CAROUSEL NO CONFLICT + // ==================== + + $.fn.carousel.noConflict = function () { + $.fn.carousel = old + return this + } + + + // CAROUSEL DATA-API + // ================= + + var clickHandler = function (e) { + var href + var $this = $(this) + var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7 + if (!$target.hasClass('carousel')) return + var options = $.extend({}, $target.data(), $this.data()) + var slideIndex = $this.attr('data-slide-to') + if (slideIndex) options.interval = false + + Plugin.call($target, options) + + if (slideIndex) { + $target.data('bs.carousel').to(slideIndex) + } + + e.preventDefault() + } + + $(document) + .on('click.bs.carousel.data-api', '[data-slide]', clickHandler) + .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler) + + $(window).on('load', function () { + $('[data-ride="carousel"]').each(function () { + var $carousel = $(this) + Plugin.call($carousel, $carousel.data()) + }) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: collapse.js v3.3.7 + * http://getbootstrap.com/javascript/#collapse + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + +/* jshint latedef: false */ + ++function ($) { + 'use strict'; + + // COLLAPSE PUBLIC CLASS DEFINITION + // ================================ + + var Collapse = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, Collapse.DEFAULTS, options) + this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' + + '[data-toggle="collapse"][data-target="#' + element.id + '"]') + this.transitioning = null + + if (this.options.parent) { + this.$parent = this.getParent() + } else { + this.addAriaAndCollapsedClass(this.$element, this.$trigger) + } + + if (this.options.toggle) this.toggle() + } + + Collapse.VERSION = '3.3.7' + + Collapse.TRANSITION_DURATION = 350 + + Collapse.DEFAULTS = { + toggle: true + } + + Collapse.prototype.dimension = function () { + var hasWidth = this.$element.hasClass('width') + return hasWidth ? 'width' : 'height' + } + + Collapse.prototype.show = function () { + if (this.transitioning || this.$element.hasClass('in')) return + + var activesData + var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing') + + if (actives && actives.length) { + activesData = actives.data('bs.collapse') + if (activesData && activesData.transitioning) return + } + + var startEvent = $.Event('show.bs.collapse') + this.$element.trigger(startEvent) + if (startEvent.isDefaultPrevented()) return + + if (actives && actives.length) { + Plugin.call(actives, 'hide') + activesData || actives.data('bs.collapse', null) + } + + var dimension = this.dimension() + + this.$element + .removeClass('collapse') + .addClass('collapsing')[dimension](0) + .attr('aria-expanded', true) + + this.$trigger + .removeClass('collapsed') + .attr('aria-expanded', true) + + this.transitioning = 1 + + var complete = function () { + this.$element + .removeClass('collapsing') + .addClass('collapse in')[dimension]('') + this.transitioning = 0 + this.$element + .trigger('shown.bs.collapse') + } + + if (!$.support.transition) return complete.call(this) + + var scrollSize = $.camelCase(['scroll', dimension].join('-')) + + this.$element + .one('bsTransitionEnd', $.proxy(complete, this)) + .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize]) + } + + Collapse.prototype.hide = function () { + if (this.transitioning || !this.$element.hasClass('in')) return + + var startEvent = $.Event('hide.bs.collapse') + this.$element.trigger(startEvent) + if (startEvent.isDefaultPrevented()) return + + var dimension = this.dimension() + + this.$element[dimension](this.$element[dimension]())[0].offsetHeight + + this.$element + .addClass('collapsing') + .removeClass('collapse in') + .attr('aria-expanded', false) + + this.$trigger + .addClass('collapsed') + .attr('aria-expanded', false) + + this.transitioning = 1 + + var complete = function () { + this.transitioning = 0 + this.$element + .removeClass('collapsing') + .addClass('collapse') + .trigger('hidden.bs.collapse') + } + + if (!$.support.transition) return complete.call(this) + + this.$element + [dimension](0) + .one('bsTransitionEnd', $.proxy(complete, this)) + .emulateTransitionEnd(Collapse.TRANSITION_DURATION) + } + + Collapse.prototype.toggle = function () { + this[this.$element.hasClass('in') ? 'hide' : 'show']() + } + + Collapse.prototype.getParent = function () { + return $(this.options.parent) + .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]') + .each($.proxy(function (i, element) { + var $element = $(element) + this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element) + }, this)) + .end() + } + + Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) { + var isOpen = $element.hasClass('in') + + $element.attr('aria-expanded', isOpen) + $trigger + .toggleClass('collapsed', !isOpen) + .attr('aria-expanded', isOpen) + } + + function getTargetFromTrigger($trigger) { + var href + var target = $trigger.attr('data-target') + || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7 + + return $(target) + } + + + // COLLAPSE PLUGIN DEFINITION + // ========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.collapse') + var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) + + if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false + if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.collapse + + $.fn.collapse = Plugin + $.fn.collapse.Constructor = Collapse + + + // COLLAPSE NO CONFLICT + // ==================== + + $.fn.collapse.noConflict = function () { + $.fn.collapse = old + return this + } + + + // COLLAPSE DATA-API + // ================= + + $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { + var $this = $(this) + + if (!$this.attr('data-target')) e.preventDefault() + + var $target = getTargetFromTrigger($this) + var data = $target.data('bs.collapse') + var option = data ? 'toggle' : $this.data() + + Plugin.call($target, option) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: dropdown.js v3.3.7 + * http://getbootstrap.com/javascript/#dropdowns + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // DROPDOWN CLASS DEFINITION + // ========================= + + var backdrop = '.dropdown-backdrop' + var toggle = '[data-toggle="dropdown"]' + var Dropdown = function (element) { + $(element).on('click.bs.dropdown', this.toggle) + } + + Dropdown.VERSION = '3.3.7' + + function getParent($this) { + var selector = $this.attr('data-target') + + if (!selector) { + selector = $this.attr('href') + selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 + } + + var $parent = selector && $(selector) + + return $parent && $parent.length ? $parent : $this.parent() + } + + function clearMenus(e) { + if (e && e.which === 3) return + $(backdrop).remove() + $(toggle).each(function () { + var $this = $(this) + var $parent = getParent($this) + var relatedTarget = { relatedTarget: this } + + if (!$parent.hasClass('open')) return + + if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return + + $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget)) + + if (e.isDefaultPrevented()) return + + $this.attr('aria-expanded', 'false') + $parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget)) + }) + } + + Dropdown.prototype.toggle = function (e) { + var $this = $(this) + + if ($this.is('.disabled, :disabled')) return + + var $parent = getParent($this) + var isActive = $parent.hasClass('open') + + clearMenus() + + if (!isActive) { + if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) { + // if mobile we use a backdrop because click events don't delegate + $(document.createElement('div')) + .addClass('dropdown-backdrop') + .insertAfter($(this)) + .on('click', clearMenus) + } + + var relatedTarget = { relatedTarget: this } + $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget)) + + if (e.isDefaultPrevented()) return + + $this + .trigger('focus') + .attr('aria-expanded', 'true') + + $parent + .toggleClass('open') + .trigger($.Event('shown.bs.dropdown', relatedTarget)) + } + + return false + } + + Dropdown.prototype.keydown = function (e) { + if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return + + var $this = $(this) + + e.preventDefault() + e.stopPropagation() + + if ($this.is('.disabled, :disabled')) return + + var $parent = getParent($this) + var isActive = $parent.hasClass('open') + + if (!isActive && e.which != 27 || isActive && e.which == 27) { + if (e.which == 27) $parent.find(toggle).trigger('focus') + return $this.trigger('click') + } + + var desc = ' li:not(.disabled):visible a' + var $items = $parent.find('.dropdown-menu' + desc) + + if (!$items.length) return + + var index = $items.index(e.target) + + if (e.which == 38 && index > 0) index-- // up + if (e.which == 40 && index < $items.length - 1) index++ // down + if (!~index) index = 0 + + $items.eq(index).trigger('focus') + } + + + // DROPDOWN PLUGIN DEFINITION + // ========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.dropdown') + + if (!data) $this.data('bs.dropdown', (data = new Dropdown(this))) + if (typeof option == 'string') data[option].call($this) + }) + } + + var old = $.fn.dropdown + + $.fn.dropdown = Plugin + $.fn.dropdown.Constructor = Dropdown + + + // DROPDOWN NO CONFLICT + // ==================== + + $.fn.dropdown.noConflict = function () { + $.fn.dropdown = old + return this + } + + + // APPLY TO STANDARD DROPDOWN ELEMENTS + // =================================== + + $(document) + .on('click.bs.dropdown.data-api', clearMenus) + .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() }) + .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle) + .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown) + .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: modal.js v3.3.7 + * http://getbootstrap.com/javascript/#modals + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // MODAL CLASS DEFINITION + // ====================== + + var Modal = function (element, options) { + this.options = options + this.$body = $(document.body) + this.$element = $(element) + this.$dialog = this.$element.find('.modal-dialog') + this.$backdrop = null + this.isShown = null + this.originalBodyPad = null + this.scrollbarWidth = 0 + this.ignoreBackdropClick = false + + if (this.options.remote) { + this.$element + .find('.modal-content') + .load(this.options.remote, $.proxy(function () { + this.$element.trigger('loaded.bs.modal') + }, this)) + } + } + + Modal.VERSION = '3.3.7' + + Modal.TRANSITION_DURATION = 300 + Modal.BACKDROP_TRANSITION_DURATION = 150 + + Modal.DEFAULTS = { + backdrop: true, + keyboard: true, + show: true + } + + Modal.prototype.toggle = function (_relatedTarget) { + return this.isShown ? this.hide() : this.show(_relatedTarget) + } + + Modal.prototype.show = function (_relatedTarget) { + var that = this + var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget }) + + this.$element.trigger(e) + + if (this.isShown || e.isDefaultPrevented()) return + + this.isShown = true + + this.checkScrollbar() + this.setScrollbar() + this.$body.addClass('modal-open') + + this.escape() + this.resize() + + this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this)) + + this.$dialog.on('mousedown.dismiss.bs.modal', function () { + that.$element.one('mouseup.dismiss.bs.modal', function (e) { + if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true + }) + }) + + this.backdrop(function () { + var transition = $.support.transition && that.$element.hasClass('fade') + + if (!that.$element.parent().length) { + that.$element.appendTo(that.$body) // don't move modals dom position + } + + that.$element + .show() + .scrollTop(0) + + that.adjustDialog() + + if (transition) { + that.$element[0].offsetWidth // force reflow + } + + that.$element.addClass('in') + + that.enforceFocus() + + var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget }) + + transition ? + that.$dialog // wait for modal to slide in + .one('bsTransitionEnd', function () { + that.$element.trigger('focus').trigger(e) + }) + .emulateTransitionEnd(Modal.TRANSITION_DURATION) : + that.$element.trigger('focus').trigger(e) + }) + } + + Modal.prototype.hide = function (e) { + if (e) e.preventDefault() + + e = $.Event('hide.bs.modal') + + this.$element.trigger(e) + + if (!this.isShown || e.isDefaultPrevented()) return + + this.isShown = false + + this.escape() + this.resize() + + $(document).off('focusin.bs.modal') + + this.$element + .removeClass('in') + .off('click.dismiss.bs.modal') + .off('mouseup.dismiss.bs.modal') + + this.$dialog.off('mousedown.dismiss.bs.modal') + + $.support.transition && this.$element.hasClass('fade') ? + this.$element + .one('bsTransitionEnd', $.proxy(this.hideModal, this)) + .emulateTransitionEnd(Modal.TRANSITION_DURATION) : + this.hideModal() + } + + Modal.prototype.enforceFocus = function () { + $(document) + .off('focusin.bs.modal') // guard against infinite focus loop + .on('focusin.bs.modal', $.proxy(function (e) { + if (document !== e.target && + this.$element[0] !== e.target && + !this.$element.has(e.target).length) { + this.$element.trigger('focus') + } + }, this)) + } + + Modal.prototype.escape = function () { + if (this.isShown && this.options.keyboard) { + this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) { + e.which == 27 && this.hide() + }, this)) + } else if (!this.isShown) { + this.$element.off('keydown.dismiss.bs.modal') + } + } + + Modal.prototype.resize = function () { + if (this.isShown) { + $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this)) + } else { + $(window).off('resize.bs.modal') + } + } + + Modal.prototype.hideModal = function () { + var that = this + this.$element.hide() + this.backdrop(function () { + that.$body.removeClass('modal-open') + that.resetAdjustments() + that.resetScrollbar() + that.$element.trigger('hidden.bs.modal') + }) + } + + Modal.prototype.removeBackdrop = function () { + this.$backdrop && this.$backdrop.remove() + this.$backdrop = null + } + + Modal.prototype.backdrop = function (callback) { + var that = this + var animate = this.$element.hasClass('fade') ? 'fade' : '' + + if (this.isShown && this.options.backdrop) { + var doAnimate = $.support.transition && animate + + this.$backdrop = $(document.createElement('div')) + .addClass('modal-backdrop ' + animate) + .appendTo(this.$body) + + this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) { + if (this.ignoreBackdropClick) { + this.ignoreBackdropClick = false + return + } + if (e.target !== e.currentTarget) return + this.options.backdrop == 'static' + ? this.$element[0].focus() + : this.hide() + }, this)) + + if (doAnimate) this.$backdrop[0].offsetWidth // force reflow + + this.$backdrop.addClass('in') + + if (!callback) return + + doAnimate ? + this.$backdrop + .one('bsTransitionEnd', callback) + .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : + callback() + + } else if (!this.isShown && this.$backdrop) { + this.$backdrop.removeClass('in') + + var callbackRemove = function () { + that.removeBackdrop() + callback && callback() + } + $.support.transition && this.$element.hasClass('fade') ? + this.$backdrop + .one('bsTransitionEnd', callbackRemove) + .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : + callbackRemove() + + } else if (callback) { + callback() + } + } + + // these following methods are used to handle overflowing modals + + Modal.prototype.handleUpdate = function () { + this.adjustDialog() + } + + Modal.prototype.adjustDialog = function () { + var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight + + this.$element.css({ + paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '', + paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : '' + }) + } + + Modal.prototype.resetAdjustments = function () { + this.$element.css({ + paddingLeft: '', + paddingRight: '' + }) + } + + Modal.prototype.checkScrollbar = function () { + var fullWindowWidth = window.innerWidth + if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8 + var documentElementRect = document.documentElement.getBoundingClientRect() + fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left) + } + this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth + this.scrollbarWidth = this.measureScrollbar() + } + + Modal.prototype.setScrollbar = function () { + var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10) + this.originalBodyPad = document.body.style.paddingRight || '' + if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth) + } + + Modal.prototype.resetScrollbar = function () { + this.$body.css('padding-right', this.originalBodyPad) + } + + Modal.prototype.measureScrollbar = function () { // thx walsh + var scrollDiv = document.createElement('div') + scrollDiv.className = 'modal-scrollbar-measure' + this.$body.append(scrollDiv) + var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth + this.$body[0].removeChild(scrollDiv) + return scrollbarWidth + } + + + // MODAL PLUGIN DEFINITION + // ======================= + + function Plugin(option, _relatedTarget) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.modal') + var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option) + + if (!data) $this.data('bs.modal', (data = new Modal(this, options))) + if (typeof option == 'string') data[option](_relatedTarget) + else if (options.show) data.show(_relatedTarget) + }) + } + + var old = $.fn.modal + + $.fn.modal = Plugin + $.fn.modal.Constructor = Modal + + + // MODAL NO CONFLICT + // ================= + + $.fn.modal.noConflict = function () { + $.fn.modal = old + return this + } + + + // MODAL DATA-API + // ============== + + $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) { + var $this = $(this) + var href = $this.attr('href') + var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7 + var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data()) + + if ($this.is('a')) e.preventDefault() + + $target.one('show.bs.modal', function (showEvent) { + if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown + $target.one('hidden.bs.modal', function () { + $this.is(':visible') && $this.trigger('focus') + }) + }) + Plugin.call($target, option, this) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: tooltip.js v3.3.7 + * http://getbootstrap.com/javascript/#tooltip + * Inspired by the original jQuery.tipsy by Jason Frame + * ======================================================================== + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // TOOLTIP PUBLIC CLASS DEFINITION + // =============================== + + var Tooltip = function (element, options) { + this.type = null + this.options = null + this.enabled = null + this.timeout = null + this.hoverState = null + this.$element = null + this.inState = null + + this.init('tooltip', element, options) + } + + Tooltip.VERSION = '3.3.7' + + Tooltip.TRANSITION_DURATION = 150 + + Tooltip.DEFAULTS = { + animation: true, + placement: 'top', + selector: false, + template: '| "+this._get(e,"weekHeader")+" | ":"",b=0;7>b;b++)T=(b+h)%7,N+="=5?" class='ui-datepicker-week-end'":"")+">"+""+p[T]+" | ";for(I+=N+"
|---|---|
| "+this._get(e,"calculateWeek")(F)+" | ":"",b=0;7>b;b++)j=f?f.apply(e.input?e.input[0]:null,[F]):[!0,""],K=F.getMonth()!==Z,R=K&&!v||!j[0]||$&&$>F||X&&F>X,O+=""+(K&&!_?" ":R?""+F.getDate()+"":""+F.getDate()+"")+" | ",F.setDate(F.getDate()+1),F=this._daylightSavingAdjust(F);I+=O+"
| "+this._get(t,"weekHeader")+" | ":"",w=0;7>w;w++)P=(w+c)%7,M+="=5?" class='ui-datepicker-week-end'":"")+">"+""+p[P]+" | ";for(I+=M+"
|---|---|
| "+this._get(t,"calculateWeek")(A)+" | ":"",w=0;7>w;w++)E=m?m.apply(t.input?t.input[0]:null,[A]):[!0,""],F=A.getMonth()!==Z,L=F&&!v||!E[0]||J&&J>A||Q&&A>Q,W+=""+(F&&!_?" ":L?""+A.getDate()+"":""+A.getDate()+"")+" | ",A.setDate(A.getDate()+1),A=this._daylightSavingAdjust(A);I+=W+"
Enter the full email address here, especially if you are using a Google Apps managed domain.
+ Please enter a number representing the hour to send scheduled email digests (e.g. 0 for midnight, 17 for 5:00pm).
+ Keep in mind that this is the hour according to the server itself, and may not exactly match your system clock.
+ The approximate server time is:
+ The next daily digest is scheduled to be sent
+