Merge remote-tracking branch 'origin' into 0.8

Conflicts:
	converse.js
	docs/CHANGES.rst
	index.html
This commit is contained in:
JC Brand 2014-02-23 02:54:35 +02:00
commit 1ce7620b88
36 changed files with 4183 additions and 883 deletions

View File

@ -29,7 +29,7 @@ It has the following features:
* Custom status messages
* Typing notifications
* Third person messages (/me )
* Translated into multiple languages (af, de, es, fr, it, hu, pt-BR, ru)
* Translated into multiple languages (af, de, en, es, fr, he, hu, id, it, ja, nl, pt_BR, ru)
* Off-the-record encryption support (via `OTR.js <http://arlolra.github.io/otr>`_)
-----------
@ -88,9 +88,16 @@ Licence
``Converse.js`` is released under both the MIT_ and GPL_ licenses.
------
Donate
------
-------
Support
-------
For support queries and discussions, please join the mailing list: conversejs@librelist.com
Issues can be logged on the `Github issue tracker <https://github.com/jcbrand/converse.js/issues>`_.
---------------------------------
Donations or tips are appreciated
---------------------------------
* Bitcoin: 16FsPqE9DhFTryxrUenpsGX4LJ1TPu8GqS
* Litecoin: LLvLH6qJch7HAamLguHkwobCrxmHLhiwZw

View File

@ -1,6 +1,6 @@
{
"name": "converse",
"version": "0.7.2",
"version": "0.7.3",
"devDependencies": {
"jasmine": "https://github.com/jcbrand/jasmine.git#1_3_x",
"otr": "0.2.7",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -333,22 +333,18 @@ you can use the generic selector below, but it's slower:
span.spinner {
background: url(images/spinner.gif) no-repeat center;
width: 22px;
height: 22px;
padding: 0 2px 0 2px;
display: block;
}
span.spinner.centered {
position: absolute;
top: 30%;
left: 50%;
margin: 0 0 0 -25%;
text-align: center;
padding-top: 5em;
}
span.spinner.hor_centered {
left: 40%;
position: absolute;
text-align: center;
}
#toggle-controlbox {
@ -1157,6 +1153,7 @@ ul.chat-toolbar li {
list-style: none;
padding: 0 3px 0 3px;
cursor: pointer;
margin-top: 1px;
}
ul.chat-toolbar li:hover {

View File

@ -141,9 +141,12 @@
this.allow_otr = true;
this.animate = true;
this.auto_list_rooms = false;
this.auto_reconnect = true;
this.auto_subscribe = false;
this.bosh_service_url = undefined; // The BOSH connection manager URL.
this.cache_otr_key = false;
this.debug = false;
this.expose_rid_and_sid = false;
this.hide_muc_server = false;
this.i18n = locales.en;
this.prebind = false;
@ -152,6 +155,7 @@
this.show_call_button = false;
this.show_emoticons = true;
this.show_toolbar = true;
this.use_otr_by_default = false;
this.use_vcards = true;
this.xhr_custom_status = false;
this.xhr_custom_status_url = '';
@ -166,22 +170,26 @@
'allow_otr',
'animate',
'auto_list_rooms',
'auto_reconnect',
'auto_subscribe',
'bosh_service_url',
'cache_otr_key',
'connection',
'debug',
'expose_rid_and_sid',
'fullname',
'hide_muc_server',
'i18n',
'jid',
'prebind',
'rid',
'show_call_button',
'show_controlbox_by_default',
'show_emoticons',
'show_only_online_users',
'show_toolbar',
'show_call_button',
'sid',
'use_otr_by_default',
'use_vcards',
'xhr_custom_status',
'xhr_custom_status_url',
@ -192,6 +200,9 @@
// Only allow OTR if we have the capability
this.allow_otr = this.allow_otr && HAS_CRYPTO;
// Only use OTR by default if allow OTR is enabled to begin with
this.use_otr_by_default = this.use_otr_by_default && this.allow_otr;
// Translation machinery
// ---------------------
var __ = $.proxy(function (str) {
@ -249,13 +260,6 @@
// Module-level functions
// ----------------------
// TODO: REMOVE
this.createLinks = function (text) {
// Convert URLs into hyperlinks
var re = /((http|https|ftp):\/\/[\w?=&.\/\-;#~%\-]+(?![\w\s?&.\/;#~%"=\-]*>))/g;
return text.replace(re, '<a target="_blank" href="$1">$1</a>');
};
this.giveFeedback = function (message, klass) {
$('.conn-feedback').text(message);
$('.conn-feedback').attr('class', 'conn-feedback');
@ -322,41 +326,63 @@
);
};
this.onConnect = function (status) {
var $button, $form;
if (status === Strophe.Status.CONNECTED) {
converse.log('Connected');
converse.onConnected();
} else if (status === Strophe.Status.DISCONNECTED) {
$form = $('#converse-login');
$button = $form.find('input[type=submit]');
if ($button) { $button.show().siblings('span').remove(); }
converse.giveFeedback(__('Disconnected'), 'error');
converse.connection.connect(
converse.connection.jid,
converse.connection.pass,
converse.onConnect
this.reconnect = function () {
converse.giveFeedback(__('Reconnecting'), 'error');
if (!converse.prebind) {
this.connection.connect(
this.connection.jid,
this.connection.pass,
function (status, condition) {
converse.onConnect(status, condition, true);
},
this.connection.wait,
this.connection.hold,
this.connection.route
);
}
};
this.showLoginButton = function () {
var view = converse.chatboxesview.views.controlbox;
if (typeof view.loginpanel !== 'undefined') {
view.loginpanel.showLoginButton();
}
};
this.onConnect = function (status, condition, reconnect) {
var $button, $form;
if ((status === Strophe.Status.CONNECTED) ||
(status === Strophe.Status.ATTACHED)) {
if ((typeof reconnect !== 'undefined') && (reconnect)) {
converse.log(status === Strophe.Status.CONNECTED ? 'Reconnected' : 'Reattached');
converse.onReconnected();
} else {
converse.log(status === Strophe.Status.CONNECTED ? 'Connected' : 'Attached');
converse.onConnected();
}
} else if (status === Strophe.Status.DISCONNECTED) {
// TODO: Handle case where user manually logs out...
converse.giveFeedback(__('Disconnected'), 'error');
if (converse.auto_reconnect) {
converse.reconnect();
} else {
converse.showLoginButton();
}
} else if (status === Strophe.Status.Error) {
$form = $('#converse-login');
$button = $form.find('input[type=submit]');
if ($button) { $button.show().siblings('span').remove(); }
converse.showLoginButton();
converse.giveFeedback(__('Error'), 'error');
} else if (status === Strophe.Status.CONNECTING) {
converse.giveFeedback(__('Connecting'));
} else if (status === Strophe.Status.CONNFAIL) {
converse.chatboxesview.views.controlbox.trigger('connection-fail');
converse.showLoginButton();
converse.giveFeedback(__('Connection Failed'), 'error');
} else if (status === Strophe.Status.AUTHENTICATING) {
converse.giveFeedback(__('Authenticating'));
} else if (status === Strophe.Status.AUTHFAIL) {
converse.chatboxesview.views.controlbox.trigger('auth-fail');
converse.showLoginButton();
converse.giveFeedback(__('Authentication Failed'), 'error');
} else if (status === Strophe.Status.DISCONNECTING) {
converse.giveFeedback(__('Disconnecting'), 'error');
} else if (status === Strophe.Status.ATTACHED) {
converse.log('Attached');
converse.onConnected();
}
};
@ -381,7 +407,7 @@
this.parseISO8601 = function (datestr) {
/* Parses string formatted as 2013-02-14T11:27:08.268Z to a Date obj.
*/
    var numericKeys = [1, 4, 5, 6, 7, 10, 11],
var numericKeys = [1, 4, 5, 6, 7, 10, 11],
struct = /^\s*(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}\.?\d*)Z\s*$/.exec(datestr),
minutesOffset = 0,
i, k;
@ -434,32 +460,81 @@
this.xmppstatus.fetch({success: callback, error: callback});
};
this.initRoster = function () {
// Set up the roster
this.roster = new this.RosterItems();
this.roster.localStorage = new Backbone.LocalStorage(
hex_sha1('converse.rosteritems-'+converse.bare_jid));
// Register callbacks that depend on the roster
this.registerRosterHandler = function () {
// Register handlers that depend on the roster
this.connection.roster.registerCallback(
$.proxy(this.roster.rosterHandler, this.roster),
null, 'presence', null);
};
this.registerRosterXHandler = function () {
this.connection.addHandler(
$.proxy(this.roster.subscribeToSuggestedItems, this.roster),
'http://jabber.org/protocol/rosterx', 'message', null);
};
this.registerPresenceHandler = function () {
this.connection.addHandler(
$.proxy(function (presence) {
this.presenceHandler(presence);
return true;
}, this.roster), null, 'presence', null);
};
this.initRoster = function () {
// Set up the roster
this.roster = new this.RosterItems();
this.roster.localStorage = new Backbone.LocalStorage(
hex_sha1('converse.rosteritems-'+converse.bare_jid));
this.registerRosterHandler();
this.registerRosterXHandler();
this.registerPresenceHandler();
// No create the view which will fetch roster items from
// localStorage
this.rosterview = new this.RosterView({'model':this.roster});
};
this.registerGlobalEventHandlers = function () {
$(document).click(function() {
if ($('.toggle-otr ul').is(':visible')) {
$('.toggle-otr ul', this).slideUp();
}
if ($('.toggle-smiley ul').is(':visible')) {
$('.toggle-smiley ul', this).slideUp();
}
});
$(document).on('mousemove', $.proxy(function (ev) {
if (!this.resized_chatbox || !this.allow_dragresize) { return true; }
ev.preventDefault();
this.resized_chatbox.resizeChatbox(ev);
}, this));
$(document).on('mouseup', $.proxy(function (ev) {
if (!this.resized_chatbox || !this.allow_dragresize) { return true; }
this.resized_chatbox = null;
}, this));
$(window).on("blur focus", $.proxy(function(e) {
if ((this.windowState != e.type) && (e.type == 'focus')) {
converse.clearMsgCounter();
}
this.windowState = e.type;
},this));
};
this.onReconnected = function () {
// We need to re-register all the event handlers on the newly
// created connection.
this.initStatus($.proxy(function () {
this.registerRosterXHandler();
this.registerPresenceHandler();
this.chatboxes.registerMessageHandler();
converse.xmppstatus.sendPresence();
this.giveFeedback(__('Online Contacts'));
}, this));
};
this.onConnected = function () {
if (this.debug) {
this.connection.xmlInput = function (body) { console.log(body); };
@ -474,32 +549,7 @@
this.initRoster();
this.chatboxes.onConnected();
this.connection.roster.get(function () {});
$(document).click(function() {
if ($('.toggle-otr ul').is(':visible')) {
$('.toggle-otr ul', this).slideUp();
}
if ($('.toggle-smiley ul').is(':visible')) {
$('.toggle-smiley ul', this).slideUp();
}
});
$(document).on('mousemove', $.proxy(function (ev) {
if (!this.resized_chatbox || !this.allow_dragresize) { return true; }
ev.preventDefault();
this.resized_chatbox.resizeChatbox(ev);
}, this));
$(document).on('mouseup', $.proxy(function (ev) {
if (!this.resized_chatbox || !this.allow_dragresize) { return true; }
this.resized_chatbox = null;
}, this));
$(window).on("blur focus", $.proxy(function (e) {
if ((this.windowState != e.type) && (e.type == 'focus')) {
converse.clearMsgCounter();
}
this.windowState = e.type;
},this));
this.registerGlobalEventHandlers();
this.giveFeedback(__('Online Contacts'));
if (this.callback) {
@ -524,6 +574,41 @@
// Backbone Models and Views
// -------------------------
this.OTR = Backbone.Model.extend({
// A model for managing OTR settings.
getSessionPassphrase: function () {
if (converse.prebind) {
var key = hex_sha1(converse.connection.jid),
pass = window.sessionStorage[key];
if (typeof pass === 'undefined') {
pass = Math.floor(Math.random()*4294967295).toString();
window.sessionStorage[key] = pass;
}
return pass;
} else {
return converse.connection.pass;
}
},
generatePrivateKey: function () {
var key = new DSA();
var jid = converse.connection.jid;
if (converse.cache_otr_key) {
var cipher = CryptoJS.lib.PasswordBasedCipher;
var pass = this.getSessionPassphrase();
if (typeof pass !== "undefined") {
// Encrypt the key and set in sessionStorage. Also store instance tag.
window.sessionStorage[hex_sha1(jid+'priv_key')] =
cipher.encrypt(CryptoJS.algo.AES, key.packPrivate(), pass).toString();
window.sessionStorage[hex_sha1(jid+'instance_tag')] = instance_tag;
window.sessionStorage[hex_sha1(jid+'pass_check')] =
cipher.encrypt(CryptoJS.algo.AES, 'match', pass).toString();
}
}
return key;
}
});
this.Message = Backbone.Model.extend();
this.Messages = Backbone.Collection.extend({
@ -533,9 +618,6 @@
this.ChatBox = Backbone.Model.extend({
initialize: function () {
if (this.get('box_id') !== 'controlbox') {
if (_.contains([UNVERIFIED, VERIFIED], this.get('otr_status'))) {
this.initiateOTR();
}
this.messages = new converse.Messages();
this.messages.localStorage = new Backbone.LocalStorage(
hex_sha1('converse.messages'+this.get('jid')+converse.bare_jid));
@ -547,43 +629,43 @@
}
},
getSession: function () {
// XXX: sessionStorage is not supported in IE < 8. Perhaps a
// user alert is required here...
var saved_key = window.sessionStorage[hex_sha1(this.id+'priv_key')];
var instance_tag = window.sessionStorage[hex_sha1(this.id+'instance_tag')];
getSession: function (callback) {
var cipher = CryptoJS.lib.PasswordBasedCipher;
var pass = converse.connection.pass;
var pass_check = this.get('pass_check');
var result, key;
if (saved_key && instance_tag && typeof pass_check !== 'undefined') {
var decrypted = cipher.decrypt(CryptoJS.algo.AES, saved_key, pass);
key = DSA.parsePrivate(decrypted.toString(CryptoJS.enc.Latin1));
if (cipher.decrypt(CryptoJS.algo.AES, pass_check, pass).toString(CryptoJS.enc.Latin1) === 'match') {
// Verified that the user's password is still the same
this.trigger('showHelpMessages', [__('Re-establishing encrypted session')]);
return {
'key': key,
'instance_tag': instance_tag
};
var result, pass, instance_tag, saved_key, pass_check;
if (converse.cache_otr_key) {
pass = converse.otr.getSessionPassphrase();
if (typeof pass !== "undefined") {
instance_tag = window.sessionStorage[hex_sha1(this.id+'instance_tag')];
saved_key = window.sessionStorage[hex_sha1(this.id+'priv_key')];
pass_check = window.sessionStorage[hex_sha1(this.connection.jid+'pass_check')];
if (saved_key && instance_tag && typeof pass_check !== 'undefined') {
var decrypted = cipher.decrypt(CryptoJS.algo.AES, saved_key, pass);
var key = DSA.parsePrivate(decrypted.toString(CryptoJS.enc.Latin1));
if (cipher.decrypt(CryptoJS.algo.AES, pass_check, pass).toString(CryptoJS.enc.Latin1) === 'match') {
// Verified that the passphrase is still the same
this.trigger('showHelpMessages', [__('Re-establishing encrypted session')]);
callback({
'key': key,
'instance_tag': instance_tag
});
return; // Our work is done here
}
}
}
}
// We need to generate a new key and instance tag
result = alert(__('Your browser needs to generate a private key, which will be used in your encrypted chat session. This can take up to 30 seconds during which your browser might freeze and become unresponsive.'));
instance_tag = OTR.makeInstanceTag();
key = new DSA();
// Encrypt the key and set in sessionStorage. Also store
// instance tag
window.sessionStorage[hex_sha1(this.id+'priv_key')] =
cipher.encrypt(CryptoJS.algo.AES, key.packPrivate(), pass).toString();
window.sessionStorage[hex_sha1(this.id+'instance_tag')] = instance_tag;
this.trigger('showHelpMessages', [__('Private key generated.')]);
this.save({'pass_check': cipher.encrypt(CryptoJS.algo.AES, 'match', pass).toString()});
return {
'key': key,
'instance_tag': instance_tag
};
this.trigger('showHelpMessages', [
__('Generating private key.'),
__('Your browser might become unresponsive.')],
null,
true // show spinner
);
setTimeout(function () {
callback({
'key': converse.otr.generatePrivateKey.apply(this),
'instance_tag': OTR.makeInstanceTag()
});
}, 500);
},
updateOTRStatus: function (state) {
@ -636,32 +718,34 @@
// query message from our buddy. Otherwise, it is us who will
// send the query message to them.
this.save({'otr_status': UNENCRYPTED});
var session = this.getSession();
this.otr = new OTR({
fragment_size: 140,
send_interval: 200,
priv: session.key,
instance_tag: session.instance_tag,
debug: this.debug
});
this.otr.on('status', $.proxy(this.updateOTRStatus, this));
this.otr.on('smp', $.proxy(this.onSMP, this));
var session = this.getSession($.proxy(function (session) {
this.otr = new OTR({
fragment_size: 140,
send_interval: 200,
priv: session.key,
instance_tag: session.instance_tag,
debug: this.debug
});
this.otr.on('status', $.proxy(this.updateOTRStatus, this));
this.otr.on('smp', $.proxy(this.onSMP, this));
this.otr.on('ui', $.proxy(function (msg) {
this.trigger('showReceivedOTRMessage', msg);
}, this));
this.otr.on('io', $.proxy(function (msg) {
this.trigger('sendMessageStanza', msg);
}, this));
this.otr.on('error', $.proxy(function (msg) {
this.trigger('showOTRError', msg);
}, this));
this.otr.on('ui', $.proxy(function (msg) {
this.trigger('showReceivedOTRMessage', msg);
}, this));
this.otr.on('io', $.proxy(function (msg) {
this.trigger('sendMessageStanza', msg);
}, this));
this.otr.on('error', $.proxy(function (msg) {
this.trigger('showOTRError', msg);
}, this));
if (query_msg) {
this.otr.receiveMsg(query_msg);
} else {
this.otr.sendQueryMsg();
}
this.trigger('showHelpMessages', [__('Exchanging private key with buddy.')]);
if (query_msg) {
this.otr.receiveMsg(query_msg);
} else {
this.otr.sendQueryMsg();
}
}, this));
},
endOTR: function () {
@ -719,19 +803,22 @@
if ((!text) || (!converse.allow_otr)) {
return this.createMessage(message);
}
if (_.contains([UNVERIFIED, VERIFIED], this.get('otr_status'))) {
this.otr.receiveMsg(text);
if (text.match(/^\?OTRv23?/)) {
this.initiateOTR(text);
} else {
if (text.match(/^\?OTR/)) {
// They want to initiate OTR
if (!this.otr) {
this.initiateOTR(text);
} else {
this.otr.receiveMsg(text);
}
if (_.contains([UNVERIFIED, VERIFIED], this.get('otr_status'))) {
this.otr.receiveMsg(text);
} else {
// Normal unencrypted message.
this.createMessage(message);
if (text.match(/^\?OTR/)) {
if (!this.otr) {
this.initiateOTR(text);
} else {
this.otr.receiveMsg(text);
}
} else {
// Normal unencrypted message.
this.createMessage(message);
}
}
}
}
@ -775,13 +862,19 @@
this.updateVCard();
this.$el.appendTo(converse.chatboxesview.$el);
this.render().show().model.messages.fetch({add: true});
if (this.model.get('status')) {
this.showStatusMessage(this.model.get('status'));
}
// Drag to resize values
this.chatboxMinHeight = 250;
this.chatboxHeight = this.$el.children('.box-flyout').height();
this.prevPageY = 0; // To store last known mouse position
if ((_.contains([UNVERIFIED, VERIFIED], this.model.get('otr_status'))) || converse.use_otr_by_default) {
this.model.initiateOTR();
}
},
render: function () {
@ -853,12 +946,17 @@
return this.scrollDown();
},
showHelpMessages: function (msgs, type) {
showHelpMessages: function (msgs, type, spinner) {
var $chat_content = this.$el.find('.chat-content'), i,
msgs_length = msgs.length;
for (i=0; i<msgs_length; i++) {
$chat_content.append($('<div class="chat-'+(type||'info')+'">'+msgs[i]+'</div>'));
}
if (spinner === true) {
$chat_content.append('<span class="spinner"/>');
} else if (spinner === false) {
$chat_content.find('span.spinner').remove();
}
return this.scrollDown();
},
@ -1094,7 +1192,7 @@
this.model.save({'otr_status': UNVERIFIED});
}
} else if (scheme === 'smp') {
alert(__('You will be prompted to provide a security question and then an answer to that question.\n\nYour buddy will then be prompted the same question and if they type the exact same answer (case sensitive), their identity will have been verified.'));
alert(__('You will be prompted to provide a security question and then an answer to that question.\n\nYour buddy will then be prompted the same question and if they type the exact same answer (case sensitive), their identity will be verified.'));
question = prompt(__('What is your security question?'));
if (question) {
answer = prompt(__('What is the answer to the security question?'));
@ -1218,7 +1316,7 @@
} else if (data.otr_status == FINISHED){
msgs.push(__("Your buddy has ended encryption on their end, you should do the same."));
}
return this.showHelpMessages(msgs);
return this.showHelpMessages(msgs, 'info', false);
},
renderToolbar: function () {
@ -2254,6 +2352,17 @@
this.ChatBoxes = Backbone.Collection.extend({
model: converse.ChatBox,
registerMessageHandler: function () {
// TODO: Make this method global to converse, trigger an event
// and let messageReceived be called via a handler for that
// event.
converse.connection.addHandler(
$.proxy(function (message) {
this.messageReceived(message);
return true;
}, this), null, 'message', 'chat');
},
onConnected: function () {
this.localStorage = new Backbone.LocalStorage(
hex_sha1('converse.chatboxes-'+converse.bare_jid));
@ -2265,16 +2374,9 @@
} else {
this.get('controlbox').save();
}
// This will make sure the Roster is set up
// This line below will make sure the Roster is set up
this.get('controlbox').set({connected:true});
// Register message handler
converse.connection.addHandler(
$.proxy(function (message) {
this.messageReceived(message);
return true;
}, this), null, 'message', 'chat');
this.registerMessageHandler();
// Get cached chatboxes from localstorage
this.fetch({
add: true,
@ -2728,8 +2830,7 @@
}, this),
$.proxy(function (jid, fullname, img, img_type, url) {
converse.log("Error while retrieving vcard");
// XXX: Should vcard_updated be set here as
// well?
// XXX: Should vcard_updated be set here as well?
this.add({
jid: bare_jid,
subscription: 'none',
@ -2752,8 +2853,6 @@
var $presence = $(presence),
presence_type = $presence.attr('type');
if (presence_type === 'error') {
// TODO
// error presence stanzas don't necessarily have a 'from' attr.
return true;
}
var jid = $presence.attr('from'),
@ -3089,7 +3188,7 @@
} else if (stat === 'away') {
pretty_status = __('away');
} else {
pretty_status = __(stat) || __('online'); // XXX: Is 'online' the right default choice here?
pretty_status = __(stat) || __('online');
}
return pretty_status;
},
@ -3208,7 +3307,7 @@
converse.connection.connect(jid, password, converse.onConnect);
},
showConnectButton: function () {
showLoginButton: function () {
var $form = this.$el.find('#converse-login');
var $button = $form.find('input[type=submit]');
if ($button.length) {
@ -3225,8 +3324,6 @@
})
));
this.$tabs = cfg.$parent.parent().find('#controlbox-tabs');
this.model.on('connection-fail', function () { this.showConnectButton(); }, this);
this.model.on('auth-fail', function () { this.showConnectButton(); }, this);
},
render: function () {
@ -3340,6 +3437,7 @@
this.chatboxes = new this.ChatBoxes();
this.chatboxesview = new this.ChatBoxesView({model: this.chatboxes});
this.controlboxtoggle = new this.ControlBoxToggle();
this.otr = new this.OTR();
if ((this.prebind) && (!this.connection)) {
if ((!this.jid) || (!this.sid) || (!this.rid) || (!this.bosh_service_url)) {
@ -3358,6 +3456,18 @@
'initialize': function (settings, callback) {
converse.initialize(settings, callback);
},
'getRID': function () {
if (converse.expose_rid_and_sid && typeof converse.connection !== "undefined") {
return converse.connection.rid;
}
return null;
},
'getSID': function () {
if (converse.expose_rid_and_sid && typeof converse.connection !== "undefined") {
return converse.connection.sid;
}
return null;
},
'once': function(evt, handler) {
converse.once(evt, handler);
},

2
converse.min.css vendored

File diff suppressed because one or more lines are too long

View File

@ -7,11 +7,16 @@ Changelog
* Chat boxes and rooms can now be resized vertically. [jcbrand]
* Chat boxes and rooms can be minimized. [jcbrand]
0.7.3 (Unreleased)
0.7.3 (2014-02-23)
------------------
* Option to display a call button in the chatbox toolbar, to allow third-party libraries to provide a calling feature. [Aupajo]
* #108 Japanese Translations. [mako09]
* #93 Add API methods exposing the RID and SID values. Can be disabled. [jcbrand]
* #102 Option to enable OTR by default. [Aupajo]
* #103 Option to display a call button in the chatbox toolbar, to allow third-party libraries to provide a calling feature. [Aupajo]
* #108 Japanese Translations [mako09]
* #111 OTR not working when using converse.js with prebinding. [jseidl, jcbrand]
* #114, #124 Hewbrew Translations [GreenLunar]
* #115 Indonesian Translations [priyadi]
0.7.2 (2013-12-18)
------------------

Binary file not shown.

View File

@ -1,4 +1,4 @@
# Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
config: 652c197d955de4d2c90bb99dc6534a15
config: 738ca7b60aed811ee1668ad08d26eabb
tags: fbb0d17656682115ca4d033fb2f83ba1

View File

@ -277,6 +277,17 @@ These values are then passed to converse.js's ``initialize`` method.
**bosh_service_url** values.
Example code for server-side prebinding
---------------------------------------
* PHP:
See `xmpp-prebind-php <https://github.com/candy-chat/xmpp-prebind-php>`_ by
Michael Weibel and the folks from Candy chat.
* Python:
See this `example Django application`_ by Jack Moffitt.
Setting up a BOSH server
------------------------
@ -295,7 +306,6 @@ Facebook integration
this myself. Feedback and patches from people who have succesfully done this
will be appreciated.
Converse.js uses `Strophe.js <http://strophe.im/strophejs>`_ to connect and
communicate with the XMPP server. One nice thing about Strophe.js is that it
can be extended via `plugins <http://github.com/strophe/strophejs-plugins>`_.
@ -339,6 +349,39 @@ The connection is already created inside Converse.js, so the
If someone submits a sane patch that does the above, I'll be happy to merge it.
Until then, people will have to do this themselves.
========
Features
========
Off-the-record encryption
=========================
Converse.js supports `Off-the-record (OTR) <https://otr.cypherpunks.ca/>`_
encrypted messaging.
The OTR protocol not only **encrypts your messages**, it provides ways to
**verify the identity** of the person you are talking to,
**plausible deniability** and **perfect forward secrecy** by generating
new encryption keys for each conversation.
In its current state, Javascript cryptography is fraught with dangers and
challenges that make it impossible to reach the same standard of security that
is available with native "desktop" software.
This is due to its runtime malleability, the way it is "installed" (e.g.
served) and the browser's lack of cryptographic primitives needed to implement
secure crypto.
For harsh but fairly valid criticism of Javascript cryptography, read:
`Javascript Cryptography Considered Harmful <http://www.matasano.com/articles/javascript-cryptography/>`_.
To get an idea on how this applies to OTR support in Converse.js, please read
`my thoughts on it <https://opkode.com/media/blog/2013/11/11/conversejs-otr-support>`_.
For now, suffice to say that although its useful to have OTR support in
Converse.js in order to avoid most eavesdroppers, if you need serious
communications privacy, then you're much better off using native software.
===========
Development
===========
@ -387,6 +430,7 @@ If you don't have grunt installed globally, you need to specify the relative
path:
::
./node_modules/.bin/grunt fetch
This will call Bower in the background to fetch all the front-end
@ -467,6 +511,137 @@ You can run both the tests and jshint in one go by calling:
grunt check
Minification
============
Minifying Javascript and CSS
----------------------------
Please make sure to read the section `Development`_ and that you have installed
all development dependencies (long story short, you can run ``npm install``
and then ``grunt fetch``).
We use `require.js`_ to keep track of *Converse.js* and its dependencies and to
to bundle them together in a single minified file fit for deployment to a
production site.
To minify the Javascript and CSS, run the following command:
::
grunt minify
Javascript will be bundled and minified with `require.js`_'s optimization tool,
using `almond <https://github.com/jrburke/almond>`_.
You can `read more about require.js's optimizer here`_.
CSS is minified via `cssmin <https://github.com/gruntjs/grunt-contrib-cssmin>`_.
Translations
============
.. Note ::
Translations take up a lot of space and will bloat your minified file.
At the time of writing, all the translations add about 50KB of extra data to
the minified javascript file. Therefore, make sure to only
include those languages that you intend to support and remove from
./locale/locales.js those which you don't need. Remember to rebuild the
minified file afterwards.
The gettext POT file located in ./locale/converse.pot is the template
containing all translations and from which for each language an individual PO
file is generated.
The POT file contains all translateable strings extracted from converse.js.
To make a user facing string translateable, wrap it in the double underscore helper
function like so:
::
__('This string will be translated at runtime');
After adding the string, you'll need to regenerate the POT file, like so:
::
make pot
You can then create or update the PO file for a specific language by doing the following:
::
msgmerge ./locale/de/LC_MESSAGES/converse.po ./locale/converse.pot -U
To do this for ALL languages, run:
::
make merge
The resulting PO file is then what gets translated.
If you've created a new PO file, please make sure to add the following
attributes at the top of the file (under *Content-Transfer-Encoding*). They are
required as configuration settings for Jed, the Javascript translations library
that we're using.
::
"domain: converse\n"
"lang: de\n"
"plural_forms: nplurals=2; plural=(n != 1);\n"
Unfortunately `Jed <http://slexaxton.github.io/Jed>`_ cannot use the PO files directly. We have to generate from it
a file in JSON format and then put that in a .js file for the specific
language.
To generate JSON from a PO file, you'll need po2json for node.js. Run the
following command to install it (npm being the node.js package manager):
::
npm install po2json
You can then convert the translations into JSON format:
::
po2json locale/de/LC_MESSAGES/converse.po locale/de/LC_MESSAGES/converse.json
Now from converse.json paste the data as a value for the "locale_data" key in the
object in the language's .js file.
So, if you are for example translating into German (language code 'de'), you'll
create or update the file ./locale/LC_MESSAGES/de.js with the following code:
::
(function (root, factory) {
define("de", ['jed'], function () {
return factory(new Jed({
"domain": "converse",
"locale_data": {
// Paste the JSON data from converse.json here
}
})
}
}(this, function (i18n) {
return i18n;
}));
making sure to also paste the JSON data as value to the "locale_data" key.
.. Note ::
If you are adding translations for a new language that is not already supported,
you'll have to make one more edit in ./locale/locales.js to make sure the
language is loaded by require.js.
Congratulations, you've now succesfully added your translations. Sorry for all
those hoops you had to jump through.
===============
Troubleshooting
@ -736,6 +911,14 @@ For each room on the server a query is made to fetch further details (e.g.
features, number of occupants etc.), so on servers with many rooms this
option will create lots of extra connection traffic.
auto_reconnect
--------------
Default = ``true``
Automatically reconnect to the XMPP server if the connection drops
unexpectedly.
auto_subscribe
--------------
@ -751,6 +934,30 @@ a middle man between HTTP and XMPP.
See `here <http://metajack.im/2008/09/08/which-bosh-server-do-you-need>`_ for more information.
cache_otr_key
-------------
Default = ``false``
Let the `OTR (Off-the-record encryption) <https://otr.cypherpunks.ca>`_ private
key be cached in your browser's session storage.
The browser's session storage persists across page loads but is deleted once
the tab or window is closed.
If this option is set to ``false``, a new OTR private key will be generated
for each page load. While more inconvenient, this is a much more secure option.
This setting can only be used together with ``allow_otr = true``.
.. Note ::
A browser window's session storage is accessible by all javascript that
is served from the same domain. So if there is malicious javascript served by
the same server (or somehow injected via an attacker), then they will be able
to retrieve your private key and read your all the chat messages in your
current session. Previous sessions however cannot be decrypted.
debug
-----
@ -758,6 +965,16 @@ Default = ``false``
If set to true, debugging output will be logged to the browser console.
expose_rid_and_sid
------------------
Allow the prebind tokens, RID (request ID) and SID (session ID), to be exposed
globally via the API. This allows other scripts served on the same page to use
these values.
*Beware*: a malicious script could use these tokens to assume your identity
and inject fake chat messages.
fullname
--------
@ -813,6 +1030,28 @@ the page with class *toggle-online-users*.
If this options is set to true, the controlbox will by default be shown upon
page load.
show_call_button
----------------
Default = ``false``
Enable to display a call button on the chatbox toolbar.
When the call button is pressed, it will emit an event that can be used by a third-party library to initiate a call.
::
converse.on('onCallButtonClicked', function(event, data) {
console.log('Call button was clicked.');
console.log('Strophe connection is', data.connection);
console.log('Bare buddy JID is', data.model.get('jid'));
// ... Third-party library code ...
});
show_only_online_users
----------------------
@ -821,6 +1060,14 @@ Default = ``false``
If set to ``true``, only online users will be shown in the contacts roster.
Users with any other status (e.g. away, busy etc.) will not be shown.
use_otr_by_default
------------------
Default = ``false``
If set to ``true``, Converse.js will automatically try to initiate an OTR (off-the-record)
encrypted chat session every time you open a chat box.
use_vcards
----------
@ -889,140 +1136,6 @@ Used only in conjunction with ``xhr_user_search``.
This is the URL to which an AJAX GET request will be made to fetch user data from your remote server.
The query string will be included in the request with ``q`` as its key.
============
Minification
============
Minifying Javascript and CSS
============================
Please make sure to read the section `Development`_ and that you have installed
all development dependencies (long story short, you can run ``npm install``
and then ``grunt fetch``).
We use `require.js`_ to keep track of *Converse.js* and its dependencies and to
to bundle them together in a single minified file fit for deployment to a
production site.
To minify the Javascript and CSS, run the following command:
::
grunt minify
Javascript will be bundled and minified with `require.js`_'s optimization tool,
using `almond <https://github.com/jrburke/almond>`_.
You can `read more about require.js's optimizer here`_.
CSS is minified via `cssmin <https://github.com/gruntjs/grunt-contrib-cssmin>`_.
============
Translations
============
.. Note ::
Translations take up a lot of space and will bloat your minified file.
At the time of writing, all the translations add about 50KB of extra data to
the minified javascript file. Therefore, make sure to only
include those languages that you intend to support and remove from
./locale/locales.js those which you don't need. Remember to rebuild the
minified file afterwards.
The gettext POT file located in ./locale/converse.pot is the template
containing all translations and from which for each language an individual PO
file is generated.
The POT file contains all translateable strings extracted from converse.js.
To make a user facing string translateable, wrap it in the double underscore helper
function like so:
::
__('This string will be translated at runtime');
After adding the string, you'll need to regenerate the POT file, like so:
::
make pot
You can then create or update the PO file for a specific language by doing the following:
::
msgmerge ./locale/de/LC_MESSAGES/converse.po ./locale/converse.pot -U
To do this for ALL languages, run:
::
make merge
The resulting PO file is then what gets translated.
If you've created a new PO file, please make sure to add the following
attributes at the top of the file (under *Content-Transfer-Encoding*). They are
required as configuration settings for Jed, the Javascript translations library
that we're using.
::
"domain: converse\n"
"lang: de\n"
"plural_forms: nplurals=2; plural=(n != 1);\n"
Unfortunately `Jed <http://slexaxton.github.io/Jed>`_ cannot use the PO files directly. We have to generate from it
a file in JSON format and then put that in a .js file for the specific
language.
To generate JSON from a PO file, you'll need po2json for node.js. Run the
following command to install it (npm being the node.js package manager):
::
npm install po2json
You can then convert the translations into JSON format:
::
po2json locale/de/LC_MESSAGES/converse.po locale/de/LC_MESSAGES/converse.json
Now from converse.json paste the data as a value for the "locale_data" key in the
object in the language's .js file.
So, if you are for example translating into German (language code 'de'), you'll
create or update the file ./locale/LC_MESSAGES/de.js with the following code:
::
(function (root, factory) {
define("de", ['jed'], function () {
return factory(new Jed({
"domain": "converse",
"locale_data": {
// Paste the JSON data from converse.json here
}
})
}
}(this, function (i18n) {
return i18n;
}));
making sure to also paste the JSON data as value to the "locale_data" key.
.. Note ::
If you are adding translations for a new language that is not already supported,
you'll have to make one more edit in ./locale/locales.js to make sure the
language is loaded by require.js.
Congratulations, you've now succesfully added your translations. Sorry for all
those hoops you had to jump through.
.. _`read more about require.js's optimizer here`: http://requirejs.org/docs/optimization.html
.. _`HTTP`: https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol
.. _`XMPP`: https://en.wikipedia.org/wiki/Xmpp

View File

@ -9,7 +9,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Index &mdash; Converse.js 0.7.1 documentation</title>
<title>Index &mdash; Converse.js 0.7.3 documentation</title>
<link rel="stylesheet" href="_static/stylesheet.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
@ -17,7 +17,7 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '0.7.1',
VERSION: '0.7.3',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
@ -26,7 +26,7 @@
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="Converse.js 0.7.1 documentation" href="index.html" />
<link rel="top" title="Converse.js 0.7.3 documentation" href="index.html" />
</head>
<body>
<div id="header_wrap" class="outer">
@ -51,7 +51,7 @@
<li class="right" style="margin-right: 10px">
<a href="#" title="General Index"
accesskey="I">index</a></li>
<li><a href="index.html">Converse.js 0.7.1 documentation</a> &raquo;</li>
<li><a href="index.html">Converse.js 0.7.3 documentation</a> &raquo;</li>
</ul>
</div>
<section id="main_content" class="inner">
@ -80,7 +80,7 @@
<li class="right" style="margin-right: 10px">
<a href="#" title="General Index"
>index</a></li>
<li><a href="index.html">Converse.js 0.7.1 documentation</a> &raquo;</li>
<li><a href="index.html">Converse.js 0.7.3 documentation</a> &raquo;</li>
</ul>
</div>
</div>

View File

@ -7,7 +7,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Quickstart (to get a demo up and running) &mdash; Converse.js 0.7.1 documentation</title>
<title>Quickstart (to get a demo up and running) &mdash; Converse.js 0.7.3 documentation</title>
<link rel="stylesheet" href="_static/stylesheet.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
@ -15,7 +15,7 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '0.7.1',
VERSION: '0.7.3',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
@ -24,7 +24,7 @@
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="Converse.js 0.7.1 documentation" href="#" />
<link rel="top" title="Converse.js 0.7.3 documentation" href="#" />
</head>
<body>
<div id="header_wrap" class="outer">
@ -49,7 +49,7 @@
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li><a href="#">Converse.js 0.7.1 documentation</a> &raquo;</li>
<li><a href="#">Converse.js 0.7.3 documentation</a> &raquo;</li>
</ul>
</div>
<section id="main_content" class="inner">
@ -75,67 +75,77 @@
</li>
<li><a class="reference internal" href="#server-side-authentication" id="id9">Server-side authentication</a><ul>
<li><a class="reference internal" href="#prebinding-and-single-session-support" id="id10">Prebinding and Single Session Support</a></li>
<li><a class="reference internal" href="#setting-up-a-bosh-server" id="id11">Setting up a BOSH server</a></li>
<li><a class="reference internal" href="#example-code-for-server-side-prebinding" id="id11">Example code for server-side prebinding</a></li>
<li><a class="reference internal" href="#setting-up-a-bosh-server" id="id12">Setting up a BOSH server</a></li>
</ul>
</li>
<li><a class="reference internal" href="#facebook-integration" id="id12">Facebook integration</a></li>
<li><a class="reference internal" href="#facebook-integration" id="id13">Facebook integration</a></li>
</ul>
</li>
<li><a class="reference internal" href="#development" id="id13">Development</a><ul>
<li><a class="reference internal" href="#install-node-js-and-development-dependencies" id="id14">Install Node.js and development dependencies</a></li>
<li><a class="reference internal" href="#install-3rd-party-dependencies" id="id15">Install 3rd party dependencies</a></li>
<li><a class="reference internal" href="#with-amd-and-require-js-recommended" id="id16">With AMD and require.js (recommended)</a></li>
<li><a class="reference internal" href="#without-amd-and-require-js" id="id17">Without AMD and require.js</a></li>
<li><a class="reference internal" href="#before-submitting-a-pull-request" id="id18">Before submitting a pull request</a><ul>
<li><a class="reference internal" href="#add-tests-for-your-bugfix-or-feature" id="id19">Add tests for your bugfix or feature</a></li>
<li><a class="reference internal" href="#check-that-the-tests-pass" id="id20">Check that the tests pass</a></li>
<li><a class="reference internal" href="#check-your-code-for-errors-or-bad-habits-by-running-jshint" id="id21">Check your code for errors or bad habits by running JSHint</a></li>
<li><a class="reference internal" href="#features" id="id14">Features</a><ul>
<li><a class="reference internal" href="#off-the-record-encryption" id="id15">Off-the-record encryption</a></li>
</ul>
</li>
<li><a class="reference internal" href="#development" id="id16">Development</a><ul>
<li><a class="reference internal" href="#install-node-js-and-development-dependencies" id="id17">Install Node.js and development dependencies</a></li>
<li><a class="reference internal" href="#install-3rd-party-dependencies" id="id18">Install 3rd party dependencies</a></li>
<li><a class="reference internal" href="#with-amd-and-require-js-recommended" id="id19">With AMD and require.js (recommended)</a></li>
<li><a class="reference internal" href="#without-amd-and-require-js" id="id20">Without AMD and require.js</a></li>
<li><a class="reference internal" href="#before-submitting-a-pull-request" id="id21">Before submitting a pull request</a><ul>
<li><a class="reference internal" href="#add-tests-for-your-bugfix-or-feature" id="id22">Add tests for your bugfix or feature</a></li>
<li><a class="reference internal" href="#check-that-the-tests-pass" id="id23">Check that the tests pass</a></li>
<li><a class="reference internal" href="#check-your-code-for-errors-or-bad-habits-by-running-jshint" id="id24">Check your code for errors or bad habits by running JSHint</a></li>
</ul>
</li>
<li><a class="reference internal" href="#minification" id="id25">Minification</a><ul>
<li><a class="reference internal" href="#minifying-javascript-and-css" id="id26">Minifying Javascript and CSS</a></li>
</ul>
</li>
<li><a class="reference internal" href="#translations" id="id27">Translations</a></li>
</ul>
</li>
<li><a class="reference internal" href="#troubleshooting" id="id28">Troubleshooting</a><ul>
<li><a class="reference internal" href="#conflicts-with-other-javascript-libraries" id="id29">Conflicts with other Javascript libraries</a><ul>
<li><a class="reference internal" href="#problem" id="id30">Problem:</a></li>
<li><a class="reference internal" href="#solution" id="id31">Solution:</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#troubleshooting" id="id22">Troubleshooting</a><ul>
<li><a class="reference internal" href="#conflicts-with-other-javascript-libraries" id="id23">Conflicts with other Javascript libraries</a><ul>
<li><a class="reference internal" href="#problem" id="id24">Problem:</a></li>
<li><a class="reference internal" href="#solution" id="id25">Solution:</a></li>
<li><a class="reference internal" href="#events" id="id32">Events</a><ul>
<li><a class="reference internal" href="#event-methods" id="id33">Event Methods</a></li>
<li><a class="reference internal" href="#event-types" id="id34">Event Types</a></li>
</ul>
</li>
<li><a class="reference internal" href="#configuration" id="id35">Configuration</a><ul>
<li><a class="reference internal" href="#configuration-variables" id="id36">Configuration variables</a><ul>
<li><a class="reference internal" href="#allow-contact-requests" id="id37">allow_contact_requests</a></li>
<li><a class="reference internal" href="#allow-muc" id="id38">allow_muc</a></li>
<li><a class="reference internal" href="#animate" id="id39">animate</a></li>
<li><a class="reference internal" href="#auto-list-rooms" id="id40">auto_list_rooms</a></li>
<li><a class="reference internal" href="#auto-reconnect" id="id41">auto_reconnect</a></li>
<li><a class="reference internal" href="#auto-subscribe" id="id42">auto_subscribe</a></li>
<li><a class="reference internal" href="#bosh-service-url" id="id43">bosh_service_url</a></li>
<li><a class="reference internal" href="#cache-otr-key" id="id44">cache_otr_key</a></li>
<li><a class="reference internal" href="#debug" id="id45">debug</a></li>
<li><a class="reference internal" href="#expose-rid-and-sid" id="id46">expose_rid_and_sid</a></li>
<li><a class="reference internal" href="#fullname" id="id47">fullname</a></li>
<li><a class="reference internal" href="#hide-muc-server" id="id48">hide_muc_server</a></li>
<li><a class="reference internal" href="#i18n" id="id49">i18n</a></li>
<li><a class="reference internal" href="#prebind" id="id50">prebind</a></li>
<li><a class="reference internal" href="#show-controlbox-by-default" id="id51">show_controlbox_by_default</a></li>
<li><a class="reference internal" href="#show-call-button" id="id52">show_call_button</a></li>
<li><a class="reference internal" href="#show-only-online-users" id="id53">show_only_online_users</a></li>
<li><a class="reference internal" href="#use-otr-by-default" id="id54">use_otr_by_default</a></li>
<li><a class="reference internal" href="#use-vcards" id="id55">use_vcards</a></li>
<li><a class="reference internal" href="#xhr-custom-status" id="id56">xhr_custom_status</a></li>
<li><a class="reference internal" href="#xhr-custom-status-url" id="id57">xhr_custom_status_url</a></li>
<li><a class="reference internal" href="#xhr-user-search" id="id58">xhr_user_search</a></li>
<li><a class="reference internal" href="#xhr-user-search-url" id="id59">xhr_user_search_url</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#events" id="id26">Events</a><ul>
<li><a class="reference internal" href="#event-methods" id="id27">Event Methods</a></li>
<li><a class="reference internal" href="#event-types" id="id28">Event Types</a></li>
</ul>
</li>
<li><a class="reference internal" href="#configuration" id="id29">Configuration</a><ul>
<li><a class="reference internal" href="#configuration-variables" id="id30">Configuration variables</a><ul>
<li><a class="reference internal" href="#allow-contact-requests" id="id31">allow_contact_requests</a></li>
<li><a class="reference internal" href="#allow-muc" id="id32">allow_muc</a></li>
<li><a class="reference internal" href="#animate" id="id33">animate</a></li>
<li><a class="reference internal" href="#auto-list-rooms" id="id34">auto_list_rooms</a></li>
<li><a class="reference internal" href="#auto-subscribe" id="id35">auto_subscribe</a></li>
<li><a class="reference internal" href="#bosh-service-url" id="id36">bosh_service_url</a></li>
<li><a class="reference internal" href="#debug" id="id37">debug</a></li>
<li><a class="reference internal" href="#fullname" id="id38">fullname</a></li>
<li><a class="reference internal" href="#hide-muc-server" id="id39">hide_muc_server</a></li>
<li><a class="reference internal" href="#i18n" id="id40">i18n</a></li>
<li><a class="reference internal" href="#prebind" id="id41">prebind</a></li>
<li><a class="reference internal" href="#show-controlbox-by-default" id="id42">show_controlbox_by_default</a></li>
<li><a class="reference internal" href="#show-only-online-users" id="id43">show_only_online_users</a></li>
<li><a class="reference internal" href="#use-vcards" id="id44">use_vcards</a></li>
<li><a class="reference internal" href="#xhr-custom-status" id="id45">xhr_custom_status</a></li>
<li><a class="reference internal" href="#xhr-custom-status-url" id="id46">xhr_custom_status_url</a></li>
<li><a class="reference internal" href="#xhr-user-search" id="id47">xhr_user_search</a></li>
<li><a class="reference internal" href="#xhr-user-search-url" id="id48">xhr_user_search_url</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#minification" id="id49">Minification</a><ul>
<li><a class="reference internal" href="#minifying-javascript-and-css" id="id50">Minifying Javascript and CSS</a></li>
</ul>
</li>
<li><a class="reference internal" href="#translations" id="id51">Translations</a></li>
</ul>
</div>
<div class="section" id="quickstart-to-get-a-demo-up-and-running">
@ -180,7 +190,7 @@ practical.</p>
<p>You&#8217;ll most likely want to implement some kind of single-signon solution for
your website, where users authenticate once in your website and then stay
logged into their XMPP session upon page reload.</p>
<p>For more info on this, read: <a href="#id52"><span class="problematic" id="id53">`Pre-binding and Single Session Support`_</span></a>.</p>
<p>For more info on this, read: <a href="#id60"><span class="problematic" id="id61">`Pre-binding and Single Session Support`_</span></a>.</p>
<p>You might also want to have more fine-grained control of what gets included in
the minified Javascript file. Read <a class="reference internal" href="#configuration">Configuration</a> and <a class="reference internal" href="#minification">Minification</a> for more info on how to do
that.</p>
@ -338,15 +348,33 @@ Additionally you need to pass in valid <strong>jid</strong>, <strong>sid</strong
<strong>bosh_service_url</strong> values.</p>
</div>
</div>
<div class="section" id="example-code-for-server-side-prebinding">
<h3><a class="toc-backref" href="#id11">Example code for server-side prebinding</a><a class="headerlink" href="#example-code-for-server-side-prebinding" title="Permalink to this headline"></a></h3>
<ul>
<li><dl class="first docutils">
<dt>PHP:</dt>
<dd><p class="first last">See <a class="reference external" href="https://github.com/candy-chat/xmpp-prebind-php">xmpp-prebind-php</a> by
Michael Weibel and the folks from Candy chat.</p>
</dd>
</dl>
</li>
<li><dl class="first docutils">
<dt>Python:</dt>
<dd><p class="first last">See this <a class="reference external" href="https://github.com/metajack/strophejs/tree/master/examples/attach">example Django application</a> by Jack Moffitt.</p>
</dd>
</dl>
</li>
</ul>
</div>
<div class="section" id="setting-up-a-bosh-server">
<h3><a class="toc-backref" href="#id11">Setting up a BOSH server</a><a class="headerlink" href="#setting-up-a-bosh-server" title="Permalink to this headline"></a></h3>
<h3><a class="toc-backref" href="#id12">Setting up a BOSH server</a><a class="headerlink" href="#setting-up-a-bosh-server" title="Permalink to this headline"></a></h3>
<p>The <a class="reference external" href="http://movim.eu/">Movim</a> project wiki has a very thorough page on setting up a BOSH server for
a wide variety of standalone or XMPP servers.</p>
<p><a class="reference external" href="http://wiki.movim.eu/manual:bosh_servers">http://wiki.movim.eu/manual:bosh_servers</a></p>
</div>
</div>
<div class="section" id="facebook-integration">
<h2><a class="toc-backref" href="#id12">Facebook integration</a><a class="headerlink" href="#facebook-integration" title="Permalink to this headline"></a></h2>
<h2><a class="toc-backref" href="#id13">Facebook integration</a><a class="headerlink" href="#facebook-integration" title="Permalink to this headline"></a></h2>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">It should be possible to integrate Converse.js with Facebook chat, and
@ -388,14 +416,39 @@ connection.facebookConnect(
Until then, people will have to do this themselves.</p>
</div>
</div>
<div class="section" id="features">
<h1><a class="toc-backref" href="#id14">Features</a><a class="headerlink" href="#features" title="Permalink to this headline"></a></h1>
<div class="section" id="off-the-record-encryption">
<h2><a class="toc-backref" href="#id15">Off-the-record encryption</a><a class="headerlink" href="#off-the-record-encryption" title="Permalink to this headline"></a></h2>
<p>Converse.js supports <a class="reference external" href="https://otr.cypherpunks.ca/">Off-the-record (OTR)</a>
encrypted messaging.</p>
<p>The OTR protocol not only <strong>encrypts your messages</strong>, it provides ways to
<strong>verify the identity</strong> of the person you are talking to,
<strong>plausible deniability</strong> and <strong>perfect forward secrecy</strong> by generating
new encryption keys for each conversation.</p>
<p>In its current state, Javascript cryptography is fraught with dangers and
challenges that make it impossible to reach the same standard of security that
is available with native &#8220;desktop&#8221; software.</p>
<p>This is due to its runtime malleability, the way it is &#8220;installed&#8221; (e.g.
served) and the browser&#8217;s lack of cryptographic primitives needed to implement
secure crypto.</p>
<p>For harsh but fairly valid criticism of Javascript cryptography, read:
<a class="reference external" href="http://www.matasano.com/articles/javascript-cryptography/">Javascript Cryptography Considered Harmful</a>.</p>
<p>To get an idea on how this applies to OTR support in Converse.js, please read
<a class="reference external" href="https://opkode.com/media/blog/2013/11/11/conversejs-otr-support">my thoughts on it</a>.</p>
<p>For now, suffice to say that although its useful to have OTR support in
Converse.js in order to avoid most eavesdroppers, if you need serious
communications privacy, then you&#8217;re much better off using native software.</p>
</div>
</div>
<div class="section" id="development">
<h1><a class="toc-backref" href="#id13">Development</a><a class="headerlink" href="#development" title="Permalink to this headline"></a></h1>
<h1><a class="toc-backref" href="#id16">Development</a><a class="headerlink" href="#development" title="Permalink to this headline"></a></h1>
<p>If you want to work with the non-minified Javascript and CSS files you&#8217;ll soon
notice that there are references to a missing <em>components</em> folder. Please
follow the instructions below to create this folder and fetch Converse&#8217;s
3rd-party dependencies.</p>
<div class="section" id="install-node-js-and-development-dependencies">
<h2><a class="toc-backref" href="#id14">Install Node.js and development dependencies</a><a class="headerlink" href="#install-node-js-and-development-dependencies" title="Permalink to this headline"></a></h2>
<h2><a class="toc-backref" href="#id17">Install Node.js and development dependencies</a><a class="headerlink" href="#install-node-js-and-development-dependencies" title="Permalink to this headline"></a></h2>
<p>We use development tools (<a class="reference external" href="http://gruntjs.com">Grunt</a> and <a class="reference external" href="http://bower.io">Bower</a>)
which depend on Node.js and npm (the Node package manager).</p>
<p>If you don&#8217;t have Node.js installed, you can download and install the latest
@ -409,7 +462,7 @@ curious to know what these are, take a look at whats under the <em>devDependenci
<cite>package.json &lt;https://github.com/jcbrand/converse.js/blob/master/package.json&gt;</cite>.</p>
</div>
<div class="section" id="install-3rd-party-dependencies">
<h2><a class="toc-backref" href="#id15">Install 3rd party dependencies</a><a class="headerlink" href="#install-3rd-party-dependencies" title="Permalink to this headline"></a></h2>
<h2><a class="toc-backref" href="#id18">Install 3rd party dependencies</a><a class="headerlink" href="#install-3rd-party-dependencies" title="Permalink to this headline"></a></h2>
<p>After running <tt class="docutils literal"><span class="pre">npm</span> <span class="pre">install</span></tt>, you will now have Grunt and Bower installed.</p>
<p>We use Bower to manage Converse&#8217;s front-end dependencies (e.g. Javascript that
should get loaded in the browser).</p>
@ -418,16 +471,14 @@ should get loaded in the browser).</p>
</div>
<p>If you don&#8217;t have grunt installed globally, you need to specify the relative
path:</p>
<dl class="docutils">
<dt>::</dt>
<dd>./node_modules/.bin/grunt fetch</dd>
</dl>
<div class="highlight-python"><pre>./node_modules/.bin/grunt fetch</pre>
</div>
<p>This will call Bower in the background to fetch all the front-end
dependencies (like backbone.js, strophe.js etc.) and then put them in the
<em>components</em> folder.</p>
</div>
<div class="section" id="with-amd-and-require-js-recommended">
<h2><a class="toc-backref" href="#id16">With AMD and require.js (recommended)</a><a class="headerlink" href="#with-amd-and-require-js-recommended" title="Permalink to this headline"></a></h2>
<h2><a class="toc-backref" href="#id19">With AMD and require.js (recommended)</a><a class="headerlink" href="#with-amd-and-require-js-recommended" title="Permalink to this headline"></a></h2>
<p>Converse.js uses <a class="reference external" href="http://requirejs.org">require.js</a> to asynchronously load dependencies.</p>
<p>If you want to develop or customize converse.js, you&#8217;ll want to load the
non-minified javascript files.</p>
@ -440,7 +491,7 @@ attribute on the <em>script</em> tag), which will in turn cause converse.js to b
parsed.</p>
</div>
<div class="section" id="without-amd-and-require-js">
<h2><a class="toc-backref" href="#id17">Without AMD and require.js</a><a class="headerlink" href="#without-amd-and-require-js" title="Permalink to this headline"></a></h2>
<h2><a class="toc-backref" href="#id20">Without AMD and require.js</a><a class="headerlink" href="#without-amd-and-require-js" title="Permalink to this headline"></a></h2>
<p>Converse.js can also be used without require.js. If you for some reason prefer
to use it this way, please refer to
<a class="reference external" href="https://github.com/jcbrand/converse.js/blob/master/non_amd.html">non_amd.html</a>
@ -448,9 +499,9 @@ for an example of how and in what order all the Javascript files that converse.j
depends on need to be loaded.</p>
</div>
<div class="section" id="before-submitting-a-pull-request">
<h2><a class="toc-backref" href="#id18">Before submitting a pull request</a><a class="headerlink" href="#before-submitting-a-pull-request" title="Permalink to this headline"></a></h2>
<h2><a class="toc-backref" href="#id21">Before submitting a pull request</a><a class="headerlink" href="#before-submitting-a-pull-request" title="Permalink to this headline"></a></h2>
<div class="section" id="add-tests-for-your-bugfix-or-feature">
<h3><a class="toc-backref" href="#id19">Add tests for your bugfix or feature</a><a class="headerlink" href="#add-tests-for-your-bugfix-or-feature" title="Permalink to this headline"></a></h3>
<h3><a class="toc-backref" href="#id22">Add tests for your bugfix or feature</a><a class="headerlink" href="#add-tests-for-your-bugfix-or-feature" title="Permalink to this headline"></a></h3>
<p>Add a test for any bug fixed or feature added. We use Jasmine
for testing.</p>
<p>Take a look at <tt class="docutils literal"><span class="pre">tests.html</span></tt> and <tt class="docutils literal"><span class="pre">spec/MainSpec.js</span></tt> to see how
@ -459,7 +510,7 @@ the tests are implemented.</p>
<a class="reference external" href="http://opkode.com/contact">contact me</a> and I&#8217;ll be happy to help.</p>
</div>
<div class="section" id="check-that-the-tests-pass">
<h3><a class="toc-backref" href="#id20">Check that the tests pass</a><a class="headerlink" href="#check-that-the-tests-pass" title="Permalink to this headline"></a></h3>
<h3><a class="toc-backref" href="#id23">Check that the tests pass</a><a class="headerlink" href="#check-that-the-tests-pass" title="Permalink to this headline"></a></h3>
<p>Check that the Jasmine tests complete sucessfully. Open
<a class="reference external" href="https://github.com/jcbrand/converse.js/blob/master/tests.html">tests.html</a>
in your browser, and the tests will run automatically.</p>
@ -468,7 +519,7 @@ in your browser, and the tests will run automatically.</p>
</div>
</div>
<div class="section" id="check-your-code-for-errors-or-bad-habits-by-running-jshint">
<h3><a class="toc-backref" href="#id21">Check your code for errors or bad habits by running JSHint</a><a class="headerlink" href="#check-your-code-for-errors-or-bad-habits-by-running-jshint" title="Permalink to this headline"></a></h3>
<h3><a class="toc-backref" href="#id24">Check your code for errors or bad habits by running JSHint</a><a class="headerlink" href="#check-your-code-for-errors-or-bad-habits-by-running-jshint" title="Permalink to this headline"></a></h3>
<p><a class="reference external" href="http://jshint.com">JSHint</a> will do a static analysis of your code and hightlight potential errors
and/or bad habits.</p>
<div class="highlight-python"><pre>grunt jshint</pre>
@ -478,20 +529,115 @@ and/or bad habits.</p>
</div>
</div>
</div>
<div class="section" id="minification">
<h2><a class="toc-backref" href="#id25">Minification</a><a class="headerlink" href="#minification" title="Permalink to this headline"></a></h2>
<div class="section" id="minifying-javascript-and-css">
<h3><a class="toc-backref" href="#id26">Minifying Javascript and CSS</a><a class="headerlink" href="#minifying-javascript-and-css" title="Permalink to this headline"></a></h3>
<p>Please make sure to read the section <a class="reference internal" href="#development">Development</a> and that you have installed
all development dependencies (long story short, you can run <tt class="docutils literal"><span class="pre">npm</span> <span class="pre">install</span></tt>
and then <tt class="docutils literal"><span class="pre">grunt</span> <span class="pre">fetch</span></tt>).</p>
<p>We use <a class="reference external" href="http://requirejs.org">require.js</a> to keep track of <em>Converse.js</em> and its dependencies and to
to bundle them together in a single minified file fit for deployment to a
production site.</p>
<p>To minify the Javascript and CSS, run the following command:</p>
<div class="highlight-python"><pre>grunt minify</pre>
</div>
<p>Javascript will be bundled and minified with <a class="reference external" href="http://requirejs.org">require.js</a>&#8216;s optimization tool,
using <a class="reference external" href="https://github.com/jrburke/almond">almond</a>.</p>
<p>You can <a class="reference external" href="http://requirejs.org/docs/optimization.html">read more about require.js&#8217;s optimizer here</a>.</p>
<p>CSS is minified via <a class="reference external" href="https://github.com/gruntjs/grunt-contrib-cssmin">cssmin</a>.</p>
</div>
</div>
<div class="section" id="translations">
<h2><a class="toc-backref" href="#id27">Translations</a><a class="headerlink" href="#translations" title="Permalink to this headline"></a></h2>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Translations take up a lot of space and will bloat your minified file.
At the time of writing, all the translations add about 50KB of extra data to
the minified javascript file. Therefore, make sure to only
include those languages that you intend to support and remove from
./locale/locales.js those which you don&#8217;t need. Remember to rebuild the
minified file afterwards.</p>
</div>
<p>The gettext POT file located in ./locale/converse.pot is the template
containing all translations and from which for each language an individual PO
file is generated.</p>
<p>The POT file contains all translateable strings extracted from converse.js.</p>
<p>To make a user facing string translateable, wrap it in the double underscore helper
function like so:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">__</span><span class="p">(</span><span class="s">&#39;This string will be translated at runtime&#39;</span><span class="p">);</span>
</pre></div>
</div>
<p>After adding the string, you&#8217;ll need to regenerate the POT file, like so:</p>
<div class="highlight-python"><pre>make pot</pre>
</div>
<p>You can then create or update the PO file for a specific language by doing the following:</p>
<div class="highlight-python"><pre>msgmerge ./locale/de/LC_MESSAGES/converse.po ./locale/converse.pot -U</pre>
</div>
<p>To do this for ALL languages, run:</p>
<div class="highlight-python"><pre>make merge</pre>
</div>
<p>The resulting PO file is then what gets translated.</p>
<p>If you&#8217;ve created a new PO file, please make sure to add the following
attributes at the top of the file (under <em>Content-Transfer-Encoding</em>). They are
required as configuration settings for Jed, the Javascript translations library
that we&#8217;re using.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="s">&quot;domain: converse</span><span class="se">\n</span><span class="s">&quot;</span>
<span class="s">&quot;lang: de</span><span class="se">\n</span><span class="s">&quot;</span>
<span class="s">&quot;plural_forms: nplurals=2; plural=(n != 1);</span><span class="se">\n</span><span class="s">&quot;</span>
</pre></div>
</div>
<p>Unfortunately <a class="reference external" href="http://slexaxton.github.io/Jed">Jed</a> cannot use the PO files directly. We have to generate from it
a file in JSON format and then put that in a .js file for the specific
language.</p>
<p>To generate JSON from a PO file, you&#8217;ll need po2json for node.js. Run the
following command to install it (npm being the node.js package manager):</p>
<div class="highlight-python"><pre>npm install po2json</pre>
</div>
<p>You can then convert the translations into JSON format:</p>
<div class="highlight-python"><pre>po2json locale/de/LC_MESSAGES/converse.po locale/de/LC_MESSAGES/converse.json</pre>
</div>
<p>Now from converse.json paste the data as a value for the &#8220;locale_data&#8221; key in the
object in the language&#8217;s .js file.</p>
<p>So, if you are for example translating into German (language code &#8216;de&#8217;), you&#8217;ll
create or update the file ./locale/LC_MESSAGES/de.js with the following code:</p>
<div class="highlight-python"><pre>(function (root, factory) {
define("de", ['jed'], function () {
return factory(new Jed({
"domain": "converse",
"locale_data": {
// Paste the JSON data from converse.json here
}
})
}
}(this, function (i18n) {
return i18n;
}));</pre>
</div>
<p>making sure to also paste the JSON data as value to the &#8220;locale_data&#8221; key.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">If you are adding translations for a new language that is not already supported,
you&#8217;ll have to make one more edit in ./locale/locales.js to make sure the
language is loaded by require.js.</p>
</div>
<p>Congratulations, you&#8217;ve now succesfully added your translations. Sorry for all
those hoops you had to jump through.</p>
</div>
</div>
<div class="section" id="troubleshooting">
<h1><a class="toc-backref" href="#id22">Troubleshooting</a><a class="headerlink" href="#troubleshooting" title="Permalink to this headline"></a></h1>
<h1><a class="toc-backref" href="#id28">Troubleshooting</a><a class="headerlink" href="#troubleshooting" title="Permalink to this headline"></a></h1>
<div class="section" id="conflicts-with-other-javascript-libraries">
<h2><a class="toc-backref" href="#id23">Conflicts with other Javascript libraries</a><a class="headerlink" href="#conflicts-with-other-javascript-libraries" title="Permalink to this headline"></a></h2>
<h2><a class="toc-backref" href="#id29">Conflicts with other Javascript libraries</a><a class="headerlink" href="#conflicts-with-other-javascript-libraries" title="Permalink to this headline"></a></h2>
<div class="section" id="problem">
<h3><a class="toc-backref" href="#id24">Problem:</a><a class="headerlink" href="#problem" title="Permalink to this headline"></a></h3>
<h3><a class="toc-backref" href="#id30">Problem:</a><a class="headerlink" href="#problem" title="Permalink to this headline"></a></h3>
<p>You are using other Javascript libraries (like JQuery plugins), and
get errors like these in your browser console:</p>
<div class="highlight-python"><pre>Uncaught TypeError: Object [object Object] has no method 'xxx' from example.js</pre>
</div>
</div>
<div class="section" id="solution">
<h3><a class="toc-backref" href="#id25">Solution:</a><a class="headerlink" href="#solution" title="Permalink to this headline"></a></h3>
<h3><a class="toc-backref" href="#id31">Solution:</a><a class="headerlink" href="#solution" title="Permalink to this headline"></a></h3>
<p>First, find out which object is referred to by <tt class="docutils literal"><span class="pre">Object</span> <span class="pre">[object</span> <span class="pre">Object]</span></tt>.</p>
<p>It will probably be the jQuery object <tt class="docutils literal"><span class="pre">$</span></tt> or perhaps the underscore.js object <tt class="docutils literal"><span class="pre">_</span></tt>.</p>
<p>For the purpose of demonstration, I&#8217;m going to assume its <tt class="docutils literal"><span class="pre">$</span></tt>, but the same
@ -533,11 +679,11 @@ jQuery plugins must load after jQuery).</p>
</div>
</div>
<div class="section" id="events">
<h1><a class="toc-backref" href="#id26">Events</a><a class="headerlink" href="#events" title="Permalink to this headline"></a></h1>
<h1><a class="toc-backref" href="#id32">Events</a><a class="headerlink" href="#events" title="Permalink to this headline"></a></h1>
<p>Converse.js emits events to which you can subscribe from your own Javascript.</p>
<p>Concerning events, the following methods are available:</p>
<div class="section" id="event-methods">
<h2><a class="toc-backref" href="#id27">Event Methods</a><a class="headerlink" href="#event-methods" title="Permalink to this headline"></a></h2>
<h2><a class="toc-backref" href="#id33">Event Methods</a><a class="headerlink" href="#event-methods" title="Permalink to this headline"></a></h2>
<ul>
<li><p class="first"><strong>on(eventName, callback)</strong>:</p>
<blockquote>
@ -581,7 +727,7 @@ exactly once.</p>
</ul>
</div>
<div class="section" id="event-types">
<h2><a class="toc-backref" href="#id28">Event Types</a><a class="headerlink" href="#event-types" title="Permalink to this headline"></a></h2>
<h2><a class="toc-backref" href="#id34">Event Types</a><a class="headerlink" href="#event-types" title="Permalink to this headline"></a></h2>
<p>Here are the different events that are emitted:</p>
<ul>
<li><p class="first"><strong>onInitialized</strong></p>
@ -667,7 +813,7 @@ got all its ducks in a row.</p>
</div>
</div>
<div class="section" id="configuration">
<h1><a class="toc-backref" href="#id29">Configuration</a><a class="headerlink" href="#configuration" title="Permalink to this headline"></a></h1>
<h1><a class="toc-backref" href="#id35">Configuration</a><a class="headerlink" href="#configuration" title="Permalink to this headline"></a></h1>
<p>The included minified JS and CSS files can be used for demoing or testing, but
you&#8217;ll want to configure <em>Converse.js</em> to suit your needs before you deploy it
on your website.</p>
@ -681,9 +827,9 @@ all the available configuration settings.</p>
JS file so that it will include the new settings. Please refer to the
<a class="reference internal" href="#minification">Minification</a> section for more info on how to do this.</p>
<div class="section" id="configuration-variables">
<h2><a class="toc-backref" href="#id30">Configuration variables</a><a class="headerlink" href="#configuration-variables" title="Permalink to this headline"></a></h2>
<h2><a class="toc-backref" href="#id36">Configuration variables</a><a class="headerlink" href="#configuration-variables" title="Permalink to this headline"></a></h2>
<div class="section" id="allow-contact-requests">
<h3><a class="toc-backref" href="#id31">allow_contact_requests</a><a class="headerlink" href="#allow-contact-requests" title="Permalink to this headline"></a></h3>
<h3><a class="toc-backref" href="#id37">allow_contact_requests</a><a class="headerlink" href="#allow-contact-requests" title="Permalink to this headline"></a></h3>
<p>Default = <tt class="docutils literal"><span class="pre">true</span></tt></p>
<p>Allow users to add one another as contacts. If this is set to false, the
<strong>Add a contact</strong> widget, <strong>Contact Requests</strong> and <strong>Pending Contacts</strong> roster
@ -691,18 +837,18 @@ sections will all not appear. Additionally, all incoming contact requests will b
ignored.</p>
</div>
<div class="section" id="allow-muc">
<h3><a class="toc-backref" href="#id32">allow_muc</a><a class="headerlink" href="#allow-muc" title="Permalink to this headline"></a></h3>
<h3><a class="toc-backref" href="#id38">allow_muc</a><a class="headerlink" href="#allow-muc" title="Permalink to this headline"></a></h3>
<p>Default = <tt class="docutils literal"><span class="pre">true</span></tt></p>
<p>Allow multi-user chat (muc) in chatrooms. Setting this to <tt class="docutils literal"><span class="pre">false</span></tt> will remove
the <tt class="docutils literal"><span class="pre">Chatrooms</span></tt> tab from the control box.</p>
</div>
<div class="section" id="animate">
<h3><a class="toc-backref" href="#id33">animate</a><a class="headerlink" href="#animate" title="Permalink to this headline"></a></h3>
<h3><a class="toc-backref" href="#id39">animate</a><a class="headerlink" href="#animate" title="Permalink to this headline"></a></h3>
<p>Default = <tt class="docutils literal"><span class="pre">true</span></tt></p>
<p>Show animations, for example when opening and closing chat boxes.</p>
</div>
<div class="section" id="auto-list-rooms">
<h3><a class="toc-backref" href="#id34">auto_list_rooms</a><a class="headerlink" href="#auto-list-rooms" title="Permalink to this headline"></a></h3>
<h3><a class="toc-backref" href="#id40">auto_list_rooms</a><a class="headerlink" href="#auto-list-rooms" title="Permalink to this headline"></a></h3>
<p>Default = <tt class="docutils literal"><span class="pre">false</span></tt></p>
<p>If true, and the XMPP server on which the current user is logged in supports
multi-user chat, then a list of rooms on that server will be fetched.</p>
@ -711,41 +857,74 @@ multi-user chat, then a list of rooms on that server will be fetched.</p>
features, number of occupants etc.), so on servers with many rooms this
option will create lots of extra connection traffic.</p>
</div>
<div class="section" id="auto-reconnect">
<h3><a class="toc-backref" href="#id41">auto_reconnect</a><a class="headerlink" href="#auto-reconnect" title="Permalink to this headline"></a></h3>
<p>Default = <tt class="docutils literal"><span class="pre">true</span></tt></p>
<p>Automatically reconnect to the XMPP server if the connection drops
unexpectedly.</p>
</div>
<div class="section" id="auto-subscribe">
<h3><a class="toc-backref" href="#id35">auto_subscribe</a><a class="headerlink" href="#auto-subscribe" title="Permalink to this headline"></a></h3>
<h3><a class="toc-backref" href="#id42">auto_subscribe</a><a class="headerlink" href="#auto-subscribe" title="Permalink to this headline"></a></h3>
<p>Default = <tt class="docutils literal"><span class="pre">false</span></tt></p>
<p>If true, the user will automatically subscribe back to any contact requests.</p>
</div>
<div class="section" id="bosh-service-url">
<h3><a class="toc-backref" href="#id36">bosh_service_url</a><a class="headerlink" href="#bosh-service-url" title="Permalink to this headline"></a></h3>
<h3><a class="toc-backref" href="#id43">bosh_service_url</a><a class="headerlink" href="#bosh-service-url" title="Permalink to this headline"></a></h3>
<p>Connections to an XMPP server depend on a BOSH connection manager which acts as
a middle man between HTTP and XMPP.</p>
<p>See <a class="reference external" href="http://metajack.im/2008/09/08/which-bosh-server-do-you-need">here</a> for more information.</p>
</div>
<div class="section" id="cache-otr-key">
<h3><a class="toc-backref" href="#id44">cache_otr_key</a><a class="headerlink" href="#cache-otr-key" title="Permalink to this headline"></a></h3>
<p>Default = <tt class="docutils literal"><span class="pre">false</span></tt></p>
<p>Let the <a class="reference external" href="https://otr.cypherpunks.ca">OTR (Off-the-record encryption)</a> private
key be cached in your browser&#8217;s session storage.</p>
<p>The browser&#8217;s session storage persists across page loads but is deleted once
the tab or window is closed.</p>
<p>If this option is set to <tt class="docutils literal"><span class="pre">false</span></tt>, a new OTR private key will be generated
for each page load. While more inconvenient, this is a much more secure option.</p>
<p>This setting can only be used together with <tt class="docutils literal"><span class="pre">allow_otr</span> <span class="pre">=</span> <span class="pre">true</span></tt>.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">A browser window&#8217;s session storage is accessible by all javascript that
is served from the same domain. So if there is malicious javascript served by
the same server (or somehow injected via an attacker), then they will be able
to retrieve your private key and read your all the chat messages in your
current session. Previous sessions however cannot be decrypted.</p>
</div>
</div>
<div class="section" id="debug">
<h3><a class="toc-backref" href="#id37">debug</a><a class="headerlink" href="#debug" title="Permalink to this headline"></a></h3>
<h3><a class="toc-backref" href="#id45">debug</a><a class="headerlink" href="#debug" title="Permalink to this headline"></a></h3>
<p>Default = <tt class="docutils literal"><span class="pre">false</span></tt></p>
<p>If set to true, debugging output will be logged to the browser console.</p>
</div>
<div class="section" id="expose-rid-and-sid">
<h3><a class="toc-backref" href="#id46">expose_rid_and_sid</a><a class="headerlink" href="#expose-rid-and-sid" title="Permalink to this headline"></a></h3>
<p>Allow the prebind tokens, RID (request ID) and SID (session ID), to be exposed
globally via the API. This allows other scripts served on the same page to use
these values.</p>
<p><em>Beware</em>: a malicious script could use these tokens to assume your identity
and inject fake chat messages.</p>
</div>
<div class="section" id="fullname">
<h3><a class="toc-backref" href="#id38">fullname</a><a class="headerlink" href="#fullname" title="Permalink to this headline"></a></h3>
<h3><a class="toc-backref" href="#id47">fullname</a><a class="headerlink" href="#fullname" title="Permalink to this headline"></a></h3>
<p>If you are using prebinding, can specify the fullname of the currently
logged in user, otherwise the user&#8217;s vCard will be fetched.</p>
</div>
<div class="section" id="hide-muc-server">
<h3><a class="toc-backref" href="#id39">hide_muc_server</a><a class="headerlink" href="#hide-muc-server" title="Permalink to this headline"></a></h3>
<h3><a class="toc-backref" href="#id48">hide_muc_server</a><a class="headerlink" href="#hide-muc-server" title="Permalink to this headline"></a></h3>
<p>Default = <tt class="docutils literal"><span class="pre">false</span></tt></p>
<p>Hide the <tt class="docutils literal"><span class="pre">server</span></tt> input field of the form inside the <tt class="docutils literal"><span class="pre">Room</span></tt> panel of the
controlbox. Useful if you want to restrict users to a specific XMPP server of
your choosing.</p>
</div>
<div class="section" id="i18n">
<h3><a class="toc-backref" href="#id40">i18n</a><a class="headerlink" href="#i18n" title="Permalink to this headline"></a></h3>
<h3><a class="toc-backref" href="#id49">i18n</a><a class="headerlink" href="#i18n" title="Permalink to this headline"></a></h3>
<p>Specify the locale/language. The language must be in the <tt class="docutils literal"><span class="pre">locales</span></tt> object. Refer to
<tt class="docutils literal"><span class="pre">./locale/locales.js</span></tt> to see which locales are supported.</p>
</div>
<div class="section" id="prebind">
<h3><a class="toc-backref" href="#id41">prebind</a><a class="headerlink" href="#prebind" title="Permalink to this headline"></a></h3>
<h3><a class="toc-backref" href="#id50">prebind</a><a class="headerlink" href="#prebind" title="Permalink to this headline"></a></h3>
<p>Default = <tt class="docutils literal"><span class="pre">false</span></tt></p>
<p>Use this option when you want to attach to an existing XMPP connection that was
already authenticated (usually on the backend before page load).</p>
@ -758,7 +937,7 @@ values as <tt class="docutils literal"><span class="pre">jid</span></tt>, <tt cl
<p>Additionally, you have to specify <tt class="docutils literal"><span class="pre">bosh_service_url</span></tt>.</p>
</div>
<div class="section" id="show-controlbox-by-default">
<h3><a class="toc-backref" href="#id42">show_controlbox_by_default</a><a class="headerlink" href="#show-controlbox-by-default" title="Permalink to this headline"></a></h3>
<h3><a class="toc-backref" href="#id51">show_controlbox_by_default</a><a class="headerlink" href="#show-controlbox-by-default" title="Permalink to this headline"></a></h3>
<p>Default = <tt class="docutils literal"><span class="pre">false</span></tt></p>
<p>The &#8220;controlbox&#8221; refers to the special chatbox containing your contacts roster,
status widget, chatrooms and other controls.</p>
@ -767,21 +946,41 @@ the page with class <em>toggle-online-users</em>.</p>
<p>If this options is set to true, the controlbox will by default be shown upon
page load.</p>
</div>
<div class="section" id="show-call-button">
<h3><a class="toc-backref" href="#id52">show_call_button</a><a class="headerlink" href="#show-call-button" title="Permalink to this headline"></a></h3>
<p>Default = <tt class="docutils literal"><span class="pre">false</span></tt></p>
<p>Enable to display a call button on the chatbox toolbar.</p>
<p>When the call button is pressed, it will emit an event that can be used by a third-party library to initiate a call.</p>
<div class="highlight-python"><pre>converse.on('onCallButtonClicked', function(event, data) {
console.log('Call button was clicked.');
console.log('Strophe connection is', data.connection);
console.log('Bare buddy JID is', data.model.get('jid'));
// ... Third-party library code ...
});</pre>
</div>
</div>
<div class="section" id="show-only-online-users">
<h3><a class="toc-backref" href="#id43">show_only_online_users</a><a class="headerlink" href="#show-only-online-users" title="Permalink to this headline"></a></h3>
<h3><a class="toc-backref" href="#id53">show_only_online_users</a><a class="headerlink" href="#show-only-online-users" title="Permalink to this headline"></a></h3>
<p>Default = <tt class="docutils literal"><span class="pre">false</span></tt></p>
<p>If set to <tt class="docutils literal"><span class="pre">true</span></tt>, only online users will be shown in the contacts roster.
Users with any other status (e.g. away, busy etc.) will not be shown.</p>
</div>
<div class="section" id="use-otr-by-default">
<h3><a class="toc-backref" href="#id54">use_otr_by_default</a><a class="headerlink" href="#use-otr-by-default" title="Permalink to this headline"></a></h3>
<p>Default = <tt class="docutils literal"><span class="pre">false</span></tt></p>
<p>If set to <tt class="docutils literal"><span class="pre">true</span></tt>, Converse.js will automatically try to initiate an OTR (off-the-record)
encrypted chat session every time you open a chat box.</p>
</div>
<div class="section" id="use-vcards">
<h3><a class="toc-backref" href="#id44">use_vcards</a><a class="headerlink" href="#use-vcards" title="Permalink to this headline"></a></h3>
<h3><a class="toc-backref" href="#id55">use_vcards</a><a class="headerlink" href="#use-vcards" title="Permalink to this headline"></a></h3>
<p>Default = <tt class="docutils literal"><span class="pre">true</span></tt></p>
<p>Determines whether the XMPP server will be queried for roster contacts&#8217; VCards
or not. VCards contain extra personal information such as your fullname and
avatar image.</p>
</div>
<div class="section" id="xhr-custom-status">
<h3><a class="toc-backref" href="#id45">xhr_custom_status</a><a class="headerlink" href="#xhr-custom-status" title="Permalink to this headline"></a></h3>
<h3><a class="toc-backref" href="#id56">xhr_custom_status</a><a class="headerlink" href="#xhr-custom-status" title="Permalink to this headline"></a></h3>
<p>Default = <tt class="docutils literal"><span class="pre">false</span></tt></p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
@ -791,7 +990,7 @@ avatar image.</p>
remote server.</p>
</div>
<div class="section" id="xhr-custom-status-url">
<h3><a class="toc-backref" href="#id46">xhr_custom_status_url</a><a class="headerlink" href="#xhr-custom-status-url" title="Permalink to this headline"></a></h3>
<h3><a class="toc-backref" href="#id57">xhr_custom_status_url</a><a class="headerlink" href="#xhr-custom-status-url" title="Permalink to this headline"></a></h3>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">XHR stands for XMLHTTPRequest, and is meant here in the AJAX sense (Asynchronous Javascript and XML).</p>
@ -803,7 +1002,7 @@ message will be made.</p>
<p>The message itself is sent in the request under the key <tt class="docutils literal"><span class="pre">msg</span></tt>.</p>
</div>
<div class="section" id="xhr-user-search">
<h3><a class="toc-backref" href="#id47">xhr_user_search</a><a class="headerlink" href="#xhr-user-search" title="Permalink to this headline"></a></h3>
<h3><a class="toc-backref" href="#id58">xhr_user_search</a><a class="headerlink" href="#xhr-user-search" title="Permalink to this headline"></a></h3>
<p>Default = <tt class="docutils literal"><span class="pre">false</span></tt></p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
@ -820,7 +1019,7 @@ message will be made.</p>
corresponds to a matched user and needs the keys <tt class="docutils literal"><span class="pre">id</span></tt> and <tt class="docutils literal"><span class="pre">fullname</span></tt>.</p>
</div>
<div class="section" id="xhr-user-search-url">
<h3><a class="toc-backref" href="#id48">xhr_user_search_url</a><a class="headerlink" href="#xhr-user-search-url" title="Permalink to this headline"></a></h3>
<h3><a class="toc-backref" href="#id59">xhr_user_search_url</a><a class="headerlink" href="#xhr-user-search-url" title="Permalink to this headline"></a></h3>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">XHR stands for XMLHTTPRequest, and is meant here in the AJAX sense (Asynchronous Javascript and XML).</p>
@ -831,101 +1030,6 @@ corresponds to a matched user and needs the keys <tt class="docutils literal"><s
The query string will be included in the request with <tt class="docutils literal"><span class="pre">q</span></tt> as its key.</p>
</div>
</div>
</div>
<div class="section" id="minification">
<h1><a class="toc-backref" href="#id49">Minification</a><a class="headerlink" href="#minification" title="Permalink to this headline"></a></h1>
<div class="section" id="minifying-javascript-and-css">
<h2><a class="toc-backref" href="#id50">Minifying Javascript and CSS</a><a class="headerlink" href="#minifying-javascript-and-css" title="Permalink to this headline"></a></h2>
<p>Please make sure to read the section <a class="reference internal" href="#development">Development</a> and that you have installed
all development dependencies (long story short, you can run <tt class="docutils literal"><span class="pre">npm</span> <span class="pre">install</span></tt>
and then <tt class="docutils literal"><span class="pre">grunt</span> <span class="pre">fetch</span></tt>).</p>
<p>We use <a class="reference external" href="http://requirejs.org">require.js</a> to keep track of <em>Converse.js</em> and its dependencies and to
to bundle them together in a single minified file fit for deployment to a
production site.</p>
<p>To minify the Javascript and CSS, run the following command:</p>
<div class="highlight-python"><pre>grunt minify</pre>
</div>
<p>Javascript will be bundled and minified with <a class="reference external" href="http://requirejs.org">require.js</a>&#8216;s optimization tool,
using <a class="reference external" href="https://github.com/jrburke/almond">almond</a>.</p>
<p>You can <a class="reference external" href="http://requirejs.org/docs/optimization.html">read more about require.js&#8217;s optimizer here</a>.</p>
<p>CSS is minified via <a class="reference external" href="https://github.com/gruntjs/grunt-contrib-cssmin">cssmin</a>.</p>
</div>
</div>
<div class="section" id="translations">
<h1><a class="toc-backref" href="#id51">Translations</a><a class="headerlink" href="#translations" title="Permalink to this headline"></a></h1>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Translations take up a lot of space and will bloat your minified file.
At the time of writing, all the translations add about 50KB of extra data to
the minified javascript file. Therefore, make sure to only
include those languages that you intend to support and remove from
./locale/locales.js those which you don&#8217;t need. Remember to rebuild the
minified file afterwards.</p>
</div>
<p>The gettext POT file located in ./locale/converse.pot is the template
containing all translations and from which for each language an individual PO
file is generated.</p>
<p>The POT file contains all translateable strings extracted from converse.js.</p>
<p>To make a user facing string translateable, wrap it in the double underscore helper
function like so:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">__</span><span class="p">(</span><span class="s">&#39;This string will be translated at runtime&#39;</span><span class="p">);</span>
</pre></div>
</div>
<p>After adding the string, you&#8217;ll need to regenerate the POT file, like so:</p>
<div class="highlight-python"><pre>make pot</pre>
</div>
<p>You can then create or update the PO file for a specific language by doing the following:</p>
<div class="highlight-python"><pre>msgmerge ./locale/de/LC_MESSAGES/converse.po ./locale/converse.pot -U</pre>
</div>
<p>To do this for ALL languages, run:</p>
<div class="highlight-python"><pre>make merge</pre>
</div>
<p>The resulting PO file is then what gets translated.</p>
<p>If you&#8217;ve created a new PO file, please make sure to add the following
attributes at the top of the file (under <em>Content-Transfer-Encoding</em>). They are
required as configuration settings for Jed, the Javascript translations library
that we&#8217;re using.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="s">&quot;domain: converse</span><span class="se">\n</span><span class="s">&quot;</span>
<span class="s">&quot;lang: de</span><span class="se">\n</span><span class="s">&quot;</span>
<span class="s">&quot;plural_forms: nplurals=2; plural=(n != 1);</span><span class="se">\n</span><span class="s">&quot;</span>
</pre></div>
</div>
<p>Unfortunately <a class="reference external" href="http://slexaxton.github.io/Jed">Jed</a> cannot use the PO files directly. We have to generate from it
a file in JSON format and then put that in a .js file for the specific
language.</p>
<p>To generate JSON from a PO file, you&#8217;ll need po2json for node.js. Run the
following command to install it (npm being the node.js package manager):</p>
<div class="highlight-python"><pre>npm install po2json</pre>
</div>
<p>You can then convert the translations into JSON format:</p>
<div class="highlight-python"><pre>po2json locale/de/LC_MESSAGES/converse.po locale/de/LC_MESSAGES/converse.json</pre>
</div>
<p>Now from converse.json paste the data as a value for the &#8220;locale_data&#8221; key in the
object in the language&#8217;s .js file.</p>
<p>So, if you are for example translating into German (language code &#8216;de&#8217;), you&#8217;ll
create or update the file ./locale/LC_MESSAGES/de.js with the following code:</p>
<div class="highlight-python"><pre>(function (root, factory) {
define("de", ['jed'], function () {
return factory(new Jed({
"domain": "converse",
"locale_data": {
// Paste the JSON data from converse.json here
}
})
}
}(this, function (i18n) {
return i18n;
}));</pre>
</div>
<p>making sure to also paste the JSON data as value to the &#8220;locale_data&#8221; key.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">If you are adding translations for a new language that is not already supported,
you&#8217;ll have to make one more edit in ./locale/locales.js to make sure the
language is loaded by require.js.</p>
</div>
<p>Congratulations, you&#8217;ve now succesfully added your translations. Sorry for all
those hoops you had to jump through.</p>
</div>
@ -941,7 +1045,7 @@ those hoops you had to jump through.</p>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li><a href="#">Converse.js 0.7.1 documentation</a> &raquo;</li>
<li><a href="#">Converse.js 0.7.3 documentation</a> &raquo;</li>
</ul>
</div>
</div>

View File

@ -1,6 +1,6 @@
# Sphinx inventory version 2
# Project: Converse.js
# Version: 0.7.1
# Version: 0.7.3
# The remainder of this file is compressed using zlib.
xÚmÎÁ
à à{Ÿ"°³ƒ]÷;

View File

@ -7,7 +7,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Search &mdash; Converse.js 0.7.1 documentation</title>
<title>Search &mdash; Converse.js 0.7.3 documentation</title>
<link rel="stylesheet" href="_static/stylesheet.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
@ -15,7 +15,7 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '0.7.1',
VERSION: '0.7.3',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
@ -25,7 +25,7 @@
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/searchtools.js"></script>
<link rel="top" title="Converse.js 0.7.1 documentation" href="index.html" />
<link rel="top" title="Converse.js 0.7.3 documentation" href="index.html" />
<script type="text/javascript">
jQuery(function() { Search.loadIndex("searchindex.js"); });
</script>
@ -55,7 +55,7 @@
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li><a href="index.html">Converse.js 0.7.1 documentation</a> &raquo;</li>
<li><a href="index.html">Converse.js 0.7.3 documentation</a> &raquo;</li>
</ul>
</div>
<section id="main_content" class="inner">
@ -100,7 +100,7 @@
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li><a href="index.html">Converse.js 0.7.1 documentation</a> &raquo;</li>
<li><a href="index.html">Converse.js 0.7.3 documentation</a> &raquo;</li>
</ul>
</div>
</div>

File diff suppressed because one or more lines are too long

View File

@ -48,9 +48,9 @@ copyright = u'2013, JC Brand'
# built documents.
#
# The short X.Y version.
version = '0.7.2'
version = '0.7.3'
# The full version, including alpha/beta/rc tags.
release = '0.7.2'
release = '0.7.3'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.

View File

@ -277,6 +277,17 @@ These values are then passed to converse.js's ``initialize`` method.
**bosh_service_url** values.
Example code for server-side prebinding
---------------------------------------
* PHP:
See `xmpp-prebind-php <https://github.com/candy-chat/xmpp-prebind-php>`_ by
Michael Weibel and the folks from Candy chat.
* Python:
See this `example Django application`_ by Jack Moffitt.
Setting up a BOSH server
------------------------
@ -295,7 +306,6 @@ Facebook integration
this myself. Feedback and patches from people who have succesfully done this
will be appreciated.
Converse.js uses `Strophe.js <http://strophe.im/strophejs>`_ to connect and
communicate with the XMPP server. One nice thing about Strophe.js is that it
can be extended via `plugins <http://github.com/strophe/strophejs-plugins>`_.
@ -339,6 +349,39 @@ The connection is already created inside Converse.js, so the
If someone submits a sane patch that does the above, I'll be happy to merge it.
Until then, people will have to do this themselves.
========
Features
========
Off-the-record encryption
=========================
Converse.js supports `Off-the-record (OTR) <https://otr.cypherpunks.ca/>`_
encrypted messaging.
The OTR protocol not only **encrypts your messages**, it provides ways to
**verify the identity** of the person you are talking to,
**plausible deniability** and **perfect forward secrecy** by generating
new encryption keys for each conversation.
In its current state, Javascript cryptography is fraught with dangers and
challenges that make it impossible to reach the same standard of security that
is available with native "desktop" software.
This is due to its runtime malleability, the way it is "installed" (e.g.
served) and the browser's lack of cryptographic primitives needed to implement
secure crypto.
For harsh but fairly valid criticism of Javascript cryptography, read:
`Javascript Cryptography Considered Harmful <http://www.matasano.com/articles/javascript-cryptography/>`_.
To get an idea on how this applies to OTR support in Converse.js, please read
`my thoughts on it <https://opkode.com/media/blog/2013/11/11/conversejs-otr-support>`_.
For now, suffice to say that although its useful to have OTR support in
Converse.js in order to avoid most eavesdroppers, if you need serious
communications privacy, then you're much better off using native software.
===========
Development
===========
@ -387,6 +430,7 @@ If you don't have grunt installed globally, you need to specify the relative
path:
::
./node_modules/.bin/grunt fetch
This will call Bower in the background to fetch all the front-end
@ -467,6 +511,137 @@ You can run both the tests and jshint in one go by calling:
grunt check
Minification
============
Minifying Javascript and CSS
----------------------------
Please make sure to read the section `Development`_ and that you have installed
all development dependencies (long story short, you can run ``npm install``
and then ``grunt fetch``).
We use `require.js`_ to keep track of *Converse.js* and its dependencies and to
to bundle them together in a single minified file fit for deployment to a
production site.
To minify the Javascript and CSS, run the following command:
::
grunt minify
Javascript will be bundled and minified with `require.js`_'s optimization tool,
using `almond <https://github.com/jrburke/almond>`_.
You can `read more about require.js's optimizer here`_.
CSS is minified via `cssmin <https://github.com/gruntjs/grunt-contrib-cssmin>`_.
Translations
============
.. Note ::
Translations take up a lot of space and will bloat your minified file.
At the time of writing, all the translations add about 50KB of extra data to
the minified javascript file. Therefore, make sure to only
include those languages that you intend to support and remove from
./locale/locales.js those which you don't need. Remember to rebuild the
minified file afterwards.
The gettext POT file located in ./locale/converse.pot is the template
containing all translations and from which for each language an individual PO
file is generated.
The POT file contains all translateable strings extracted from converse.js.
To make a user facing string translateable, wrap it in the double underscore helper
function like so:
::
__('This string will be translated at runtime');
After adding the string, you'll need to regenerate the POT file, like so:
::
make pot
You can then create or update the PO file for a specific language by doing the following:
::
msgmerge ./locale/de/LC_MESSAGES/converse.po ./locale/converse.pot -U
To do this for ALL languages, run:
::
make merge
The resulting PO file is then what gets translated.
If you've created a new PO file, please make sure to add the following
attributes at the top of the file (under *Content-Transfer-Encoding*). They are
required as configuration settings for Jed, the Javascript translations library
that we're using.
::
"domain: converse\n"
"lang: de\n"
"plural_forms: nplurals=2; plural=(n != 1);\n"
Unfortunately `Jed <http://slexaxton.github.io/Jed>`_ cannot use the PO files directly. We have to generate from it
a file in JSON format and then put that in a .js file for the specific
language.
To generate JSON from a PO file, you'll need po2json for node.js. Run the
following command to install it (npm being the node.js package manager):
::
npm install po2json
You can then convert the translations into JSON format:
::
po2json locale/de/LC_MESSAGES/converse.po locale/de/LC_MESSAGES/converse.json
Now from converse.json paste the data as a value for the "locale_data" key in the
object in the language's .js file.
So, if you are for example translating into German (language code 'de'), you'll
create or update the file ./locale/LC_MESSAGES/de.js with the following code:
::
(function (root, factory) {
define("de", ['jed'], function () {
return factory(new Jed({
"domain": "converse",
"locale_data": {
// Paste the JSON data from converse.json here
}
})
}
}(this, function (i18n) {
return i18n;
}));
making sure to also paste the JSON data as value to the "locale_data" key.
.. Note ::
If you are adding translations for a new language that is not already supported,
you'll have to make one more edit in ./locale/locales.js to make sure the
language is loaded by require.js.
Congratulations, you've now succesfully added your translations. Sorry for all
those hoops you had to jump through.
===============
Troubleshooting
@ -736,6 +911,14 @@ For each room on the server a query is made to fetch further details (e.g.
features, number of occupants etc.), so on servers with many rooms this
option will create lots of extra connection traffic.
auto_reconnect
--------------
Default = ``true``
Automatically reconnect to the XMPP server if the connection drops
unexpectedly.
auto_subscribe
--------------
@ -751,6 +934,30 @@ a middle man between HTTP and XMPP.
See `here <http://metajack.im/2008/09/08/which-bosh-server-do-you-need>`_ for more information.
cache_otr_key
-------------
Default = ``false``
Let the `OTR (Off-the-record encryption) <https://otr.cypherpunks.ca>`_ private
key be cached in your browser's session storage.
The browser's session storage persists across page loads but is deleted once
the tab or window is closed.
If this option is set to ``false``, a new OTR private key will be generated
for each page load. While more inconvenient, this is a much more secure option.
This setting can only be used together with ``allow_otr = true``.
.. Note ::
A browser window's session storage is accessible by all javascript that
is served from the same domain. So if there is malicious javascript served by
the same server (or somehow injected via an attacker), then they will be able
to retrieve your private key and read your all the chat messages in your
current session. Previous sessions however cannot be decrypted.
debug
-----
@ -758,6 +965,16 @@ Default = ``false``
If set to true, debugging output will be logged to the browser console.
expose_rid_and_sid
------------------
Allow the prebind tokens, RID (request ID) and SID (session ID), to be exposed
globally via the API. This allows other scripts served on the same page to use
these values.
*Beware*: a malicious script could use these tokens to assume your identity
and inject fake chat messages.
fullname
--------
@ -843,6 +1060,14 @@ Default = ``false``
If set to ``true``, only online users will be shown in the contacts roster.
Users with any other status (e.g. away, busy etc.) will not be shown.
use_otr_by_default
------------------
Default = ``false``
If set to ``true``, Converse.js will automatically try to initiate an OTR (off-the-record)
encrypted chat session every time you open a chat box.
use_vcards
----------
@ -911,140 +1136,6 @@ Used only in conjunction with ``xhr_user_search``.
This is the URL to which an AJAX GET request will be made to fetch user data from your remote server.
The query string will be included in the request with ``q`` as its key.
============
Minification
============
Minifying Javascript and CSS
============================
Please make sure to read the section `Development`_ and that you have installed
all development dependencies (long story short, you can run ``npm install``
and then ``grunt fetch``).
We use `require.js`_ to keep track of *Converse.js* and its dependencies and to
to bundle them together in a single minified file fit for deployment to a
production site.
To minify the Javascript and CSS, run the following command:
::
grunt minify
Javascript will be bundled and minified with `require.js`_'s optimization tool,
using `almond <https://github.com/jrburke/almond>`_.
You can `read more about require.js's optimizer here`_.
CSS is minified via `cssmin <https://github.com/gruntjs/grunt-contrib-cssmin>`_.
============
Translations
============
.. Note ::
Translations take up a lot of space and will bloat your minified file.
At the time of writing, all the translations add about 50KB of extra data to
the minified javascript file. Therefore, make sure to only
include those languages that you intend to support and remove from
./locale/locales.js those which you don't need. Remember to rebuild the
minified file afterwards.
The gettext POT file located in ./locale/converse.pot is the template
containing all translations and from which for each language an individual PO
file is generated.
The POT file contains all translateable strings extracted from converse.js.
To make a user facing string translateable, wrap it in the double underscore helper
function like so:
::
__('This string will be translated at runtime');
After adding the string, you'll need to regenerate the POT file, like so:
::
make pot
You can then create or update the PO file for a specific language by doing the following:
::
msgmerge ./locale/de/LC_MESSAGES/converse.po ./locale/converse.pot -U
To do this for ALL languages, run:
::
make merge
The resulting PO file is then what gets translated.
If you've created a new PO file, please make sure to add the following
attributes at the top of the file (under *Content-Transfer-Encoding*). They are
required as configuration settings for Jed, the Javascript translations library
that we're using.
::
"domain: converse\n"
"lang: de\n"
"plural_forms: nplurals=2; plural=(n != 1);\n"
Unfortunately `Jed <http://slexaxton.github.io/Jed>`_ cannot use the PO files directly. We have to generate from it
a file in JSON format and then put that in a .js file for the specific
language.
To generate JSON from a PO file, you'll need po2json for node.js. Run the
following command to install it (npm being the node.js package manager):
::
npm install po2json
You can then convert the translations into JSON format:
::
po2json locale/de/LC_MESSAGES/converse.po locale/de/LC_MESSAGES/converse.json
Now from converse.json paste the data as a value for the "locale_data" key in the
object in the language's .js file.
So, if you are for example translating into German (language code 'de'), you'll
create or update the file ./locale/LC_MESSAGES/de.js with the following code:
::
(function (root, factory) {
define("de", ['jed'], function () {
return factory(new Jed({
"domain": "converse",
"locale_data": {
// Paste the JSON data from converse.json here
}
})
}
}(this, function (i18n) {
return i18n;
}));
making sure to also paste the JSON data as value to the "locale_data" key.
.. Note ::
If you are adding translations for a new language that is not already supported,
you'll have to make one more edit in ./locale/locales.js to make sure the
language is loaded by require.js.
Congratulations, you've now succesfully added your translations. Sorry for all
those hoops you had to jump through.
.. _`read more about require.js's optimizer here`: http://requirejs.org/docs/optimization.html
.. _`HTTP`: https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol
.. _`XMPP`: https://en.wikipedia.org/wiki/Xmpp

View File

@ -7,8 +7,8 @@
<meta name="description" content="Converse.js: Open Source Browser-Based Instant Messaging" />
<link rel="stylesheet" type="text/css" media="screen" href="stylesheets/stylesheet.css">
<link rel="stylesheet" type="text/css" media="screen" href="converse.css">
<script data-main="main" src="components/requirejs/require.js"></script>
<!--<script src="builds/converse.min.js"></script>-->
<!--<script data-main="main" src="components/requirejs/require.js"></script>-->
<script src="builds/converse.min.js"></script>
<title>Converse.js</title>
</head>
@ -54,7 +54,7 @@
<li>Custom status messages</li>
<li>Typing notifications</li>
<li>Third person messages (/me )</li>
<li>Translated into multiple languages (af, de, es, fr, hu, it, nl, pt-BR, ru)</li>
<li>Translated into multiple languages (af, de, en, es, fr, he, hu, id, it, ja, nl, pt_BR, ru)</li>
<li>Off-the-record encryption (via <a href="http://arlolra.github.io/otr/" target="_blank">OTR.js</a>)</li>
</ul>
@ -159,9 +159,17 @@
You can:
<ul>
<li>Follow me on <a href="http://twitter.com/jcopkode" target="_blank">Twitter</a></li>
<li>Chat via <a href="xmpp:jc@opkode.com" class="xmpp JSnocheck" title="XMPP/Jabber">XMPP/Jabber</a></li>
<li>Send me an email via this <a href="http://opkode.com/contact" target="_blank">contact form</a>.</li>
<li>Chat with me via XMPP: <a href="xmpp:jc@opkode.com" class="xmpp JSnocheck" title="XMPP/Jabber">jc@opkode.com</a></li>
<ul>
<p>
For <strong>support queries</strong>, please write to the mailing list: <a href="mailto:conversejs@librelist.com">conversejs@librelist.com</a>
</p>
<p>
Please <a target="_blank" href="https://github.com/jcbrand/converse.js/issues">file <strong>bugs</strong> on Github</a>.
</p>
<p>
I'm available for special features and consulting work. Please <a href="http://opkode.com/contact" target="_blank">contact me here</a>.
</p>
</section>
</div>
@ -186,7 +194,7 @@
allow_otr: true,
auto_list_rooms: false,
auto_subscribe: false,
bosh_service_url: 'http://devbox:8890/http-bind', // Please use this connection manager only for testing purposes
bosh_service_url: 'https://bind.opkode.im', // Please use this connection manager only for testing purposes
debug: true ,
hide_muc_server: false,
i18n: locales['en'], // Refer to ./locale/locales.js to see which locales are supported

View File

@ -6,9 +6,9 @@
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: Converse.js 0.4\n"
"Project-Id-Version: Converse.js 0.7.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-09-15 22:06+0200\n"
"POT-Creation-Date: 2014-01-28 03:50+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -17,66 +17,94 @@ msgstr ""
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#: converse.js:125
#: converse.js:217
msgid "unencrypted"
msgstr ""
#: converse.js:126
#: converse.js:218
msgid "unverified"
msgstr ""
#: converse.js:127
#: converse.js:219
msgid "verified"
msgstr ""
#: converse.js:128
#: converse.js:220
msgid "finished"
msgstr ""
#: converse.js:161
#: converse.js:223
msgid "This contact is busy"
msgstr ""
#: converse.js:224
msgid "This contact is online"
msgstr ""
#: converse.js:225
msgid "This contact is offline"
msgstr ""
#: converse.js:226
msgid "This contact is unavailable"
msgstr ""
#: converse.js:227
msgid "This contact is away for an extended period"
msgstr ""
#: converse.js:228
msgid "This contact is away"
msgstr ""
#: converse.js:321
msgid "Disconnected"
msgstr ""
#: converse.js:165
#: converse.js:331
msgid "Error"
msgstr ""
#: converse.js:167
#: converse.js:333
msgid "Connecting"
msgstr ""
#: converse.js:170
#: converse.js:336
msgid "Connection Failed"
msgstr ""
#: converse.js:172
#: converse.js:338
msgid "Authenticating"
msgstr ""
#: converse.js:175
#: converse.js:341
msgid "Authentication Failed"
msgstr ""
#: converse.js:177
#: converse.js:343
msgid "Disconnecting"
msgstr ""
#: converse.js:332
#: converse.js:479
msgid "Online Contacts"
msgstr ""
#: converse.js:540
msgid "Re-establishing encrypted session"
msgstr ""
#: converse.js:340
#: converse.js:548
msgid ""
"Your browser needs to generate a private key, which will be used in your "
"encrypted chat session. This can take up to 30 seconds during which your "
"browser might freeze and become unresponsive."
msgstr ""
#: converse.js:349
#: converse.js:557
msgid "Private key generated."
msgstr ""
#: converse.js:380
#: converse.js:588
msgid ""
"Authentication request from %1$s\n"
"\n"
@ -86,71 +114,71 @@ msgid ""
"%2$s"
msgstr ""
#: converse.js:389
#: converse.js:597
msgid "Could not verify this user's identify."
msgstr ""
#: converse.js:537
#: converse.js:750
msgid "Personal message"
msgstr ""
#: converse.js:559
#: converse.js:795
msgid "Start encrypted conversation"
msgstr ""
#: converse.js:562
#: converse.js:798
msgid "Refresh encrypted conversation"
msgstr ""
#: converse.js:563
#: converse.js:799
msgid "End encrypted conversation"
msgstr ""
#: converse.js:564
#: converse.js:800
msgid "Verify with SMP"
msgstr ""
#: converse.js:567
#: converse.js:803
msgid "Verify with fingerprints"
msgstr ""
#: converse.js:569
#: converse.js:805
msgid "What's this?"
msgstr ""
#: converse.js:641
#: converse.js:906
msgid "me"
msgstr ""
#: converse.js:757 converse.js:1552
#: converse.js:1022 converse.js:1864
msgid "Show this menu"
msgstr ""
#: converse.js:758 converse.js:1553
#: converse.js:1023 converse.js:1865
msgid "Write in the third person"
msgstr ""
#: converse.js:759 converse.js:1557
#: converse.js:1024 converse.js:1869
msgid "Remove messages"
msgstr ""
#: converse.js:830
#: converse.js:1110
msgid "Your message could not be sent"
msgstr ""
#: converse.js:833
#: converse.js:1113
msgid "We received an unencrypted message"
msgstr ""
#: converse.js:836
#: converse.js:1116
msgid "We received an unreadable encrypted message"
msgstr ""
#: converse.js:845
#: converse.js:1125
msgid "This user has requested an encrypted session."
msgstr ""
#: converse.js:863
#: converse.js:1147
msgid ""
"Here are the fingerprints, please confirm them with %1$s, outside of this "
"chat.\n"
@ -163,480 +191,452 @@ msgid ""
"Cancel."
msgstr ""
#: converse.js:876
#: converse.js:1160
msgid ""
"You will be prompted to provide a security question and then an answer to "
"that question.\n"
"\n"
"Your buddy will then be prompted the same question and if they type the "
"exact same answer (case sensitive), their identity will have been verified."
"exact same answer (case sensitive), their identity will be verified."
msgstr ""
#: converse.js:877
#: converse.js:1161
msgid "What is your security question?"
msgstr ""
#: converse.js:879
#: converse.js:1163
msgid "What is the answer to the security question?"
msgstr ""
#: converse.js:883
#: converse.js:1167
msgid "Invalid authentication scheme provided"
msgstr ""
#: converse.js:953
#: converse.js:1248
msgid "Your messages are not encrypted anymore"
msgstr ""
#: converse.js:955
#: converse.js:1250
msgid ""
"Your messages are now encrypted but your buddy's identity has not been "
"verified."
msgstr ""
#: converse.js:957
#: converse.js:1252
msgid "Your buddy's identify has been verified."
msgstr ""
#: converse.js:959
#: converse.js:1254
msgid "Your buddy has ended encryption on their end, you should do the same."
msgstr ""
#: converse.js:968
#: converse.js:1263
msgid "Your messages are not encrypted. Click here to enable OTR encryption."
msgstr ""
#: converse.js:970
#: converse.js:1265
msgid "Your messages are encrypted, but your buddy has not been verified."
msgstr ""
#: converse.js:972
#: converse.js:1267
msgid "Your messages are encrypted and your buddy verified."
msgstr ""
#: converse.js:974
#: converse.js:1269
msgid ""
"Your buddy has closed their end of the private session, you should do the "
"same"
msgstr ""
#: converse.js:1049
#: converse.js:1354
msgid "Contacts"
msgstr ""
#: converse.js:1054
#: converse.js:1359
msgid "Online"
msgstr ""
#: converse.js:1055
#: converse.js:1360
msgid "Busy"
msgstr ""
#: converse.js:1056
#: converse.js:1361
msgid "Away"
msgstr ""
#: converse.js:1057
#: converse.js:1362
msgid "Offline"
msgstr ""
#: converse.js:1064
#: converse.js:1372
msgid "Click to add new chat contacts"
msgstr ""
#: converse.js:1065
#: converse.js:1373
msgid "Add a contact"
msgstr ""
#: converse.js:1074
#: converse.js:1382
msgid "Contact username"
msgstr ""
#: converse.js:1075
#: converse.js:1383
msgid "Add"
msgstr ""
#: converse.js:1083
#: converse.js:1391
msgid "Contact name"
msgstr ""
#: converse.js:1084
#: converse.js:1392
msgid "Search"
msgstr ""
#: converse.js:1124
#: converse.js:1439
msgid "No users found"
msgstr ""
#: converse.js:1131
#: converse.js:1446
msgid "Click to add as a chat contact"
msgstr ""
#: converse.js:1191
#: converse.js:1498
msgid "Click to open this room"
msgstr ""
#: converse.js:1193
#: converse.js:1500
msgid "Show more information on this room"
msgstr ""
#: converse.js:1199
#: converse.js:1506
msgid "Description:"
msgstr ""
#: converse.js:1200
#: converse.js:1507
msgid "Occupants:"
msgstr ""
#: converse.js:1201
#: converse.js:1508
msgid "Features:"
msgstr ""
#: converse.js:1203
#: converse.js:1510
msgid "Requires authentication"
msgstr ""
#: converse.js:1206
#: converse.js:1513
msgid "Hidden"
msgstr ""
#: converse.js:1209
#: converse.js:1516
msgid "Requires an invitation"
msgstr ""
#: converse.js:1212
#: converse.js:1519
msgid "Moderated"
msgstr ""
#: converse.js:1215
#: converse.js:1522
msgid "Non-anonymous"
msgstr ""
#: converse.js:1218
#: converse.js:1525
msgid "Open room"
msgstr ""
#: converse.js:1221
#: converse.js:1528
msgid "Permanent room"
msgstr ""
#: converse.js:1224
#: converse.js:1531
msgid "Public"
msgstr ""
#: converse.js:1227
#: converse.js:1534
msgid "Semi-anonymous"
msgstr ""
#: converse.js:1230
#: converse.js:1537
msgid "Temporary room"
msgstr ""
#: converse.js:1233
#: converse.js:1540
msgid "Unmoderated"
msgstr ""
#: converse.js:1239
#: converse.js:1546
msgid "Rooms"
msgstr ""
#: converse.js:1243
#: converse.js:1550
msgid "Room name"
msgstr ""
#: converse.js:1244
#: converse.js:1551
msgid "Nickname"
msgstr ""
#: converse.js:1245
#: converse.js:1552
msgid "Server"
msgstr ""
#: converse.js:1246
#: converse.js:1553
msgid "Join"
msgstr ""
#: converse.js:1247
#: converse.js:1554
msgid "Show rooms"
msgstr ""
#. For translators: %1$s is a variable and will be replaced with the XMPP server name
#: converse.js:1282
#: converse.js:1589
msgid "No rooms on %1$s"
msgstr ""
#. For translators: %1$s is a variable and will be
#. replaced with the XMPP server name
#: converse.js:1297
#: converse.js:1604
msgid "Rooms on %1$s"
msgstr ""
#: converse.js:1554
#: converse.js:1866
msgid "Set chatroom topic"
msgstr ""
#: converse.js:1555
#: converse.js:1867
msgid "Kick user from chatroom"
msgstr ""
#: converse.js:1556
#: converse.js:1868
msgid "Ban user from chatroom"
msgstr ""
#: converse.js:1583
#: converse.js:1898
msgid "Message"
msgstr ""
#: converse.js:1697 converse.js:2783
#: converse.js:2013 converse.js:3168
msgid "Save"
msgstr ""
#: converse.js:1698
#: converse.js:2014
msgid "Cancel"
msgstr ""
#: converse.js:1745
#: converse.js:2061
msgid "An error occurred while trying to save the form."
msgstr ""
#: converse.js:1791
#: converse.js:2107
msgid "This chatroom requires a password"
msgstr ""
#: converse.js:1792
#: converse.js:2108
msgid "Password: "
msgstr ""
#: converse.js:1793
#: converse.js:2109
msgid "Submit"
msgstr ""
#: converse.js:1807
#: converse.js:2123
msgid "This room is not anonymous"
msgstr ""
#: converse.js:1808
#: converse.js:2124
msgid "This room now shows unavailable members"
msgstr ""
#: converse.js:1809
#: converse.js:2125
msgid "This room does not show unavailable members"
msgstr ""
#: converse.js:1810
#: converse.js:2126
msgid "Non-privacy-related room configuration has changed"
msgstr ""
#: converse.js:1811
#: converse.js:2127
msgid "Room logging is now enabled"
msgstr ""
#: converse.js:1812
#: converse.js:2128
msgid "Room logging is now disabled"
msgstr ""
#: converse.js:1813
#: converse.js:2129
msgid "This room is now non-anonymous"
msgstr ""
#: converse.js:1814
#: converse.js:2130
msgid "This room is now semi-anonymous"
msgstr ""
#: converse.js:1815
#: converse.js:2131
msgid "This room is now fully-anonymous"
msgstr ""
#: converse.js:1816
#: converse.js:2132
msgid "A new room has been created"
msgstr ""
#: converse.js:1817
#: converse.js:2133
msgid "Your nickname has been changed"
msgstr ""
#: converse.js:1831
#: converse.js:2147
msgid "<strong>%1$s</strong> has been banned"
msgstr ""
#: converse.js:1832
#: converse.js:2148
msgid "<strong>%1$s</strong> has been kicked out"
msgstr ""
#: converse.js:1833
#: converse.js:2149
msgid "<strong>%1$s</strong> has been removed because of an affiliation change"
msgstr ""
#: converse.js:1834
#: converse.js:2150
msgid "<strong>%1$s</strong> has been removed for not being a member"
msgstr ""
#: converse.js:1838 converse.js:1898
#: converse.js:2154 converse.js:2214
msgid "You have been banned from this room"
msgstr ""
#: converse.js:1839
#: converse.js:2155
msgid "You have been kicked from this room"
msgstr ""
#: converse.js:1840
#: converse.js:2156
msgid "You have been removed from this room because of an affiliation change"
msgstr ""
#: converse.js:1841
#: converse.js:2157
msgid ""
"You have been removed from this room because the room has changed to members-"
"only and you're not a member"
msgstr ""
#: converse.js:1842
#: converse.js:2158
msgid ""
"You have been removed from this room because the MUC (Multi-user chat) "
"service is being shut down."
msgstr ""
#: converse.js:1896
#: converse.js:2212
msgid "You are not on the member list of this room"
msgstr ""
#: converse.js:1902
#: converse.js:2218
msgid "No nickname was specified"
msgstr ""
#: converse.js:1906
#: converse.js:2222
msgid "You are not allowed to create new rooms"
msgstr ""
#: converse.js:1908
#: converse.js:2224
msgid "Your nickname doesn't conform to this room's policies"
msgstr ""
#: converse.js:1910
#: converse.js:2226
msgid "Your nickname is already taken"
msgstr ""
#: converse.js:1912
#: converse.js:2228
msgid "This room does not (yet) exist"
msgstr ""
#: converse.js:1914
#: converse.js:2230
msgid "This room has reached it's maximum number of occupants"
msgstr ""
#: converse.js:1993
#: converse.js:2309
msgid "Topic set by %1$s to: %2$s"
msgstr ""
#: converse.js:2009
#: converse.js:2330
msgid "This user is a moderator"
msgstr ""
#: converse.js:2012
#: converse.js:2333
msgid "This user can send messages in this room"
msgstr ""
#: converse.js:2015
#: converse.js:2336
msgid "This user can NOT send messages in this room"
msgstr ""
#: converse.js:2225
#: converse.js:2562
msgid "Click to chat with this contact"
msgstr ""
#: converse.js:2228 converse.js:2232
#: converse.js:2565 converse.js:2569
msgid "Click to remove this contact"
msgstr ""
#: converse.js:2263
msgid "This contact is busy"
msgstr ""
#: converse.js:2264
msgid "This contact is online"
msgstr ""
#: converse.js:2265
msgid "This contact is offline"
msgstr ""
#: converse.js:2266
msgid "This contact is unavailable"
msgstr ""
#: converse.js:2267
msgid "This contact is away for an extended period"
msgstr ""
#: converse.js:2268
msgid "This contact is away"
msgstr ""
#: converse.js:2622
#: converse.js:2919
msgid "Contact requests"
msgstr ""
#: converse.js:2623
#: converse.js:2922
msgid "My contacts"
msgstr ""
#: converse.js:2624
#: converse.js:2925
msgid "Pending contacts"
msgstr ""
#: converse.js:2782
#: converse.js:3167
msgid "Custom status"
msgstr ""
#: converse.js:2788
#: converse.js:3173
msgid "Click to change your chat status"
msgstr ""
#: converse.js:2792
#: converse.js:3177
msgid "Click here to write a custom status message"
msgstr ""
#: converse.js:2821 converse.js:2829
#: converse.js:3206 converse.js:3214
msgid "online"
msgstr ""
#: converse.js:2823
#: converse.js:3208
msgid "busy"
msgstr ""
#: converse.js:2825
#: converse.js:3210
msgid "away for long"
msgstr ""
#: converse.js:2827
#: converse.js:3212
msgid "away"
msgstr ""
#. For translators: the %1$s part gets replaced with the status
#. Example, I am online
#: converse.js:2841 converse.js:2878
#: converse.js:3226 converse.js:3263
msgid "I am %1$s"
msgstr ""
#: converse.js:2949
#: converse.js:3334
msgid "Sign in"
msgstr ""
#: converse.js:2952
#: converse.js:3338
msgid "XMPP/Jabber Username:"
msgstr ""
#: converse.js:2954
#: converse.js:3340
msgid "Password:"
msgstr ""
#: converse.js:2956
#: converse.js:3342
msgid "Log In"
msgstr ""
#: converse.js:2960
#: converse.js:3346
msgid "BOSH Service URL:"
msgstr ""
#: converse.js:3113
msgid "Online Contacts"
msgstr ""

View File

@ -0,0 +1,605 @@
{
"converse": {
"": {
"Project-Id-Version": "Converse.js 0.7.0",
"Report-Msgid-Bugs-To": "",
"POT-Creation-Date": "2014-01-28 03:50+0200",
"PO-Revision-Date": "2014-02-21 06:07+0200",
"Last-Translator": "GreenLunar <GreenLunar@github.com>",
"Language-Team": "Rahut <http://sourceforge.net/projects/rahut/>",
"Language": "he",
"MIME-Version": "1.0",
"Content-Type": "text/plain; charset=UTF-8",
"Content-Transfer-Encoding": "8bit",
"X-Generator": "Poedit 1.5.1"
},
"unencrypted": [
null,
"לא מוצפנת"
],
"unverified": [
null,
"לא מאומתת"
],
"verified": [
null,
"מאומתת"
],
"finished": [
null,
"מוגמרת"
],
"This contact is busy": [
null,
"איש קשר זה עסוק"
],
"This contact is online": [
null,
"איש קשר זה מקוון"
],
"This contact is offline": [
null,
"איש קשר זה לא מקוון"
],
"This contact is unavailable": [
null,
"איש קשר זה לא זמין"
],
"This contact is away for an extended period": [
null,
"איש קשר זה נעדר למשך זמן ממושך"
],
"This contact is away": [
null,
"איש קשר זה הינו נעדר"
],
"Disconnected": [
null,
"מנותק"
],
"Error": [
null,
"שגיאה"
],
"Connecting": [
null,
"כעת מתחבר"
],
"Connection Failed": [
null,
"חיבור נכשל"
],
"Authenticating": [
null,
"כעת מאמת"
],
"Authentication Failed": [
null,
"אימות נכשל"
],
"Disconnecting": [
null,
"כעת מתנתק"
],
"Online Contacts": [
null,
"אנשי קשר מקוונים"
],
"Re-establishing encrypted session": [
null,
"בסס מחדש ישיבה מוצפנת"
],
"Your browser needs to generate a private key, which will be used in your encrypted chat session. This can take up to 30 seconds during which your browser might freeze and become unresponsive.": [
null,
"על הדפדפן שלך להפיק מפתח פרטי, אשר ישמש אותך בישיבות שיחה מוצפנות. פעולה זו יכולה לקחת למעלה מן 30 שניות אשר במהלכה הדפדפן שלך עשוי לקפוא ולהפוך לחסר תגובה."
],
"Private key generated.": [
null,
"מפתח פרטי הופק."
],
"Authentication request from %1$s\n\nYour buddy is attempting to verify your identity, by asking you the question below.\n\n%2$s": [
null,
"בקשת אימות מאת %1$s\n\nהאישיות שכנגד מנסה לאמת את הזהות שלך, בעזרת שאילת שאלה להלן.\n\n%2$s"
],
"Could not verify this user's identify.": [
null,
"לא היתה אפשרות לאמת את זהות משתמש זה."
],
"Personal message": [
null,
"הודעה אישית"
],
"Start encrypted conversation": [
null,
"התחל ישיבה מוצפנת"
],
"Refresh encrypted conversation": [
null,
"רענן ישיבה מוצפנת"
],
"End encrypted conversation": [
null,
"סיים ישיבה מוצפנת"
],
"Verify with SMP": [
null,
"אמת בעזרת SMP"
],
"Verify with fingerprints": [
null,
"אמת בעזרת טביעות אצבע"
],
"What's this?": [
null,
"מה זה?"
],
"me": [
null,
"אני"
],
"Show this menu": [
null,
"הצג את תפריט זה"
],
"Write in the third person": [
null,
"כתוב בגוף השלישי"
],
"Remove messages": [
null,
"הסר הודעות"
],
"Your message could not be sent": [
null,
"ההודעה שלך לא היתה יכולה להישלח"
],
"We received an unencrypted message": [
null,
"אנחנו קיבלנו הודעה לא מוצפנת"
],
"We received an unreadable encrypted message": [
null,
"אנחנו קיבלנו הודעה מוצפנת לא קריאה"
],
"This user has requested an encrypted session.": [
null,
"משתמש זה ביקש ישיבה מוצפנת."
],
"Here are the fingerprints, please confirm them with %1$s, outside of this chat.\n\nFingerprint for you, %2$s: %3$s\n\nFingerprint for %1$s: %4$s\n\nIf you have confirmed that the fingerprints match, click OK, otherwise click Cancel.": [
null,
"הרי טביעות האצבע, אנא אמת אותן עם %1$s, מחוץ לשיחה זו.\n\nטביעת אצבע עבורך, %2$s: %3$s\n\nטביעת אצבע עבור %1$s: %4$s\n\nהיה ואימתת כי טביעות האצבע תואמות, לחץ אישור (OK), אחרת לחץ ביטול (Cancel)."
],
"You will be prompted to provide a security question and then an answer to that question.\n\nYour buddy will then be prompted the same question and if they type the exact same answer (case sensitive), their identity will be verified.": [
null,
"אתה תתבקש לספק שאלת אבטחה ולאחריה תשובה לשאלה הזו.\n\nהאישיות שכנגד תתבקש עובר זאת לאותה שאלת אבטחה ואם זו תקלידו את את אותה התשובה במדויק (case sensitive), זהותה תאומת."
],
"What is your security question?": [
null,
"מהי שאלת האבטחה שלך?"
],
"What is the answer to the security question?": [
null,
"מהי התשובה לשאלת האבטחה?"
],
"Invalid authentication scheme provided": [
null,
"סופקה סכימת אימות שגויה"
],
"Your messages are not encrypted anymore": [
null,
"ההודעות שלך אינן מוצפנות עוד"
],
"Your messages are now encrypted but your buddy's identity has not been verified.": [
null,
"ההודעות שלך מוצפנות כעת אך זהות האישיות שכנגד טרם אומתה."
],
"Your buddy's identify has been verified.": [
null,
"זהות האישיות שכנגד אומתה."
],
"Your buddy has ended encryption on their end, you should do the same.": [
null,
"האישיות שכנגד סיימה הצפנה בקצה שלה, עליך לעשות את אותו הדבר."
],
"Your messages are not encrypted. Click here to enable OTR encryption.": [
null,
"ההודעות שלך אינן וצפנות. לחץ כאן כדי לאפשר OTR."
],
"Your messages are encrypted, but your buddy has not been verified.": [
null,
"ההודעות שלך מוצפנות כעת, אך האישיות שכנגד טרם אומתה."
],
"Your messages are encrypted and your buddy verified.": [
null,
"ההודעות שלך מוצפנות כעת והאישיות שכנגד אומתה."
],
"Your buddy has closed their end of the private session, you should do the same": [
null,
"האישיות שכנגד סגרה את קצה הישיבה הפרטית שלה, עליך לעשות את אותו הדבר."
],
"Contacts": [
null,
"אנשי קשר"
],
"Online": [
null,
"מקוון"
],
"Busy": [
null,
"עסוק"
],
"Away": [
null,
"נעדר"
],
"Offline": [
null,
"בלתי מקוון"
],
"Click to add new chat contacts": [
null,
"לחץ כדי להוסיף אנשי קשר שיחה חדשים"
],
"Add a contact": [
null,
"הוסף איש קשר"
],
"Contact username": [
null,
"שם משתמש איש קשר"
],
"Add": [
null,
"הוסף"
],
"Contact name": [
null,
"שם איש קשר"
],
"Search": [
null,
"חיפוש"
],
"No users found": [
null,
"לא נמצאו משתמשים"
],
"Click to add as a chat contact": [
null,
"לחץ כדי להוסיף בתור איש קשר שיחה"
],
"Click to open this room": [
null,
"לחץ כדי לפתוח את חדר זה"
],
"Show more information on this room": [
null,
"הצג עוד מידע אודות חדר זה"
],
"Description:": [
null,
"תיאור:"
],
"Occupants:": [
null,
"נוכחים:"
],
"Features:": [
null,
"תכונות:"
],
"Requires authentication": [
null,
"מצריך אישור"
],
"Hidden": [
null,
"נסתר"
],
"Requires an invitation": [
null,
"מצריך הזמנה"
],
"Moderated": [
null,
"מבוקר"
],
"Non-anonymous": [
null,
"לא אנונימי"
],
"Open room": [
null,
"חדר פתוח"
],
"Permanent room": [
null,
"חדר צמיתה"
],
"Public": [
null,
"פומבי"
],
"Semi-anonymous": [
null,
"אנונימי למחצה"
],
"Temporary room": [
null,
"חדר זמני"
],
"Unmoderated": [
null,
"לא מבוקר"
],
"Rooms": [
null,
"חדרים"
],
"Room name": [
null,
"שם חדר"
],
"Nickname": [
null,
"שם כינוי"
],
"Server": [
null,
"שרת"
],
"Join": [
null,
"הצטרף"
],
"Show rooms": [
null,
"הצג חדרים"
],
"No rooms on %1$s": [
null,
"אין חדרים על %1$s"
],
"Rooms on %1$s": [
null,
"חדרים על %1$s"
],
"Set chatroom topic": [
null,
"קבע נושא חדר שיחה"
],
"Kick user from chatroom": [
null,
"בעט משתמש מתוך חדר שיחה"
],
"Ban user from chatroom": [
null,
"אסור משתמש מתוך חדר שיחה"
],
"Message": [
null,
"הודעה"
],
"Save": [
null,
"שמור"
],
"Cancel": [
null,
"ביטול"
],
"An error occurred while trying to save the form.": [
null,
"אירעה שגיאה במהלך ניסיון שמירת הטופס."
],
"This chatroom requires a password": [
null,
"חדר שיחה זה מצריך סיסמה"
],
"Password: ": [
null,
"סיסמה: "
],
"Submit": [
null,
"שלח"
],
"This room is not anonymous": [
null,
"חדר זה אינו אנונימי"
],
"This room now shows unavailable members": [
null,
"חדר זה כעת מציג חברים לא זמינים"
],
"This room does not show unavailable members": [
null,
"חדר זה לא מציג חברים לא זמינים"
],
"Non-privacy-related room configuration has changed": [
null,
"תצורת חדר אשר לא-קשורה-בפרטיות שונתה"
],
"Room logging is now enabled": [
null,
"יומן חדר הינו מופעל כעת"
],
"Room logging is now disabled": [
null,
"יומן חדר הינו מנוטרל כעת"
],
"This room is now non-anonymous": [
null,
"חדר זה אינו אנונימי כעת"
],
"This room is now semi-anonymous": [
null,
"חדר זה הינו אנונימי למחצה כעת"
],
"This room is now fully-anonymous": [
null,
"חדר זה הינו אנונימי לחלוטין כעת"
],
"A new room has been created": [
null,
"חדר חדש נוצר"
],
"Your nickname has been changed": [
null,
"שם הכינוי שלך שונה"
],
"<strong>%1$s</strong> has been banned": [
null,
"<strong>%1$s</strong> נאסר(ה)"
],
"<strong>%1$s</strong> has been kicked out": [
null,
"<strong>%1$s</strong> נבעט(ה)"
],
"<strong>%1$s</strong> has been removed because of an affiliation change": [
null,
"<strong>%1$s</strong> הוסרה(ה) משום שינוי שיוך"
],
"<strong>%1$s</strong> has been removed for not being a member": [
null,
"<strong>%1$s</strong> הוסר(ה) משום אי הימצאות במסגרת מעמד של חבר"
],
"You have been banned from this room": [
null,
"נאסרת מתוך חדר זה"
],
"You have been kicked from this room": [
null,
"נבעטת מתוך חדר זה"
],
"You have been removed from this room because of an affiliation change": [
null,
"הוסרת מתוך חדר זה משום שינוי שיוך"
],
"You have been removed from this room because the room has changed to members-only and you're not a member": [
null,
"הוסרת מתוך חדר זה משום שהחדר שונה לחברים-בלבד ואינך במעמד של חבר"
],
"You have been removed from this room because the MUC (Multi-user chat) service is being shut down.": [
null,
"הוסרת מתוך חדר זה משום ששירות שמ״מ (שיחה מרובת משתמשים) זה כעת מצוי בהליכי סגירה."
],
"You are not on the member list of this room": [
null,
"אינך ברשימת החברים של חדר זה"
],
"No nickname was specified": [
null,
"לא צוין שום שם כינוי"
],
"You are not allowed to create new rooms": [
null,
"אין לך רשות ליצור חדרים חדשים"
],
"Your nickname doesn't conform to this room's policies": [
null,
"שם הכינוי שלך לא תואם את המדינויות של חדר זה"
],
"Your nickname is already taken": [
null,
"שם הכינוי שלך הינו תפוס"
],
"This room does not (yet) exist": [
null,
"חדר זה (עדיין) לא קיים"
],
"This room has reached it's maximum number of occupants": [
null,
"חדר זה הגיע לסף הנוכחים המרבי שלו"
],
"Topic set by %1$s to: %2$s": [
null,
"נושא חדר זה נקבע על ידי %1$s אל: %2$s"
],
"This user is a moderator": [
null,
"משתמש זה הינו אחראי"
],
"This user can send messages in this room": [
null,
"משתמש זה מסוגל לשלוח הודעות בתוך חדר זה"
],
"This user can NOT send messages in this room": [
null,
"משתמש זה ﬥﬡ מסוגל לשלוח הודעות בתוך חדר זה"
],
"Click to chat with this contact": [
null,
"לחץ כדי לשוחח עם איש קשר זה"
],
"Click to remove this contact": [
null,
"לחץ כדי להסיר את איש קשר זה"
],
"Contact requests": [
null,
"בקשות איש קשר"
],
"My contacts": [
null,
"אנשי הקשר שלי"
],
"Pending contacts": [
null,
"אנשי קשר ממתינים"
],
"Custom status": [
null,
"מצב מותאם"
],
"Click to change your chat status": [
null,
"לחץ כדי לשנות את הודעת השיחה שלך"
],
"Click here to write a custom status message": [
null,
"לחץ כאן כדי לכתוב הודעת מצב מותאמת"
],
"online": [
null,
"מקוון"
],
"busy": [
null,
"עסוק"
],
"away for long": [
null,
"נעדר לזמן מה"
],
"away": [
null,
"נעדר"
],
"I am %1$s": [
null,
"מצבי כעת הינו %1$s"
],
"Sign in": [
null,
"התחברות"
],
"XMPP/Jabber Username:": [
null,
"שם משתמש XMPP/Jabber:"
],
"Password:": [
null,
"סיסמה:"
],
"Log In": [
null,
"כניסה"
],
"BOSH Service URL:": [
null,
"כתובת שירות BOSH:"
]
}
}

View File

@ -0,0 +1,672 @@
# Language HE translations for Converse.js package.
# Copyright (C) 2013 Jan-Carel Brand
# This file is distributed under the same license as the Converse.js package.
# GreenLunar <GreenLunar@github.com>, 2014.
#
msgid ""
msgstr ""
"Project-Id-Version: Converse.js 0.7.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-01-28 03:50+0200\n"
"PO-Revision-Date: 2014-02-21 06:07+0200\n"
"Last-Translator: GreenLunar <GreenLunar@github.com>\n"
"Language-Team: Rahut <http://sourceforge.net/projects/rahut/>\n"
"Language: he\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 1.5.1\n"
#: converse.js:217
msgid "unencrypted"
msgstr "לא מוצפנת"
#: converse.js:218
msgid "unverified"
msgstr "לא מאומתת"
#: converse.js:219
msgid "verified"
msgstr "מאומתת"
#: converse.js:220
msgid "finished"
msgstr "מוגמרת"
# איש קשר זה הינו
#: converse.js:223
msgid "This contact is busy"
msgstr "איש קשר זה עסוק"
#: converse.js:224
msgid "This contact is online"
msgstr "איש קשר זה מקוון"
# איש קשר זה אינו
#: converse.js:225
msgid "This contact is offline"
msgstr "איש קשר זה לא מקוון"
#: converse.js:226
msgid "This contact is unavailable"
msgstr "איש קשר זה לא זמין"
#: converse.js:227
msgid "This contact is away for an extended period"
msgstr "איש קשר זה נעדר למשך זמן ממושך"
#: converse.js:228
msgid "This contact is away"
msgstr "איש קשר זה הינו נעדר"
#: converse.js:321
msgid "Disconnected"
msgstr "מנותק"
#: converse.js:331
msgid "Error"
msgstr "שגיאה"
#: converse.js:333
msgid "Connecting"
msgstr "כעת מתחבר"
#: converse.js:336
msgid "Connection Failed"
msgstr "חיבור נכשל"
#: converse.js:338
msgid "Authenticating"
msgstr "כעת מאמת"
#: converse.js:341
msgid "Authentication Failed"
msgstr "אימות נכשל"
#: converse.js:343
msgid "Disconnecting"
msgstr "כעת מתנתק"
#: converse.js:479
msgid "Online Contacts"
msgstr "אנשי קשר מקוונים"
#: converse.js:540
msgid "Re-establishing encrypted session"
msgstr "בסס מחדש ישיבה מוצפנת"
#: converse.js:548
msgid ""
"Your browser needs to generate a private key, which will be used in your "
"encrypted chat session. This can take up to 30 seconds during which your "
"browser might freeze and become unresponsive."
msgstr ""
"על הדפדפן שלך להפיק מפתח פרטי, אשר ישמש אותך בישיבות שיחה מוצפנות. פעולה זו "
"יכולה לקחת למעלה מן 30 שניות אשר במהלכה הדפדפן שלך עשוי לקפוא ולהפוך לחסר "
"תגובה."
#: converse.js:557
msgid "Private key generated."
msgstr "מפתח פרטי הופק."
#: converse.js:588
msgid ""
"Authentication request from %1$s\n"
"\n"
"Your buddy is attempting to verify your identity, by asking you the question "
"below.\n"
"\n"
"%2$s"
msgstr ""
"בקשת אימות מאת %1$s\n"
"\n"
"האישיות שכנגד מנסה לאמת את הזהות שלך, בעזרת שאילת שאלה להלן.\n"
"\n"
"%2$s"
#: converse.js:597
msgid "Could not verify this user's identify."
msgstr "לא היתה אפשרות לאמת את זהות משתמש זה."
#: converse.js:750
msgid "Personal message"
msgstr "הודעה אישית"
#: converse.js:795
msgid "Start encrypted conversation"
msgstr "התחל ישיבה מוצפנת"
#: converse.js:798
msgid "Refresh encrypted conversation"
msgstr "רענן ישיבה מוצפנת"
#: converse.js:799
msgid "End encrypted conversation"
msgstr "סיים ישיבה מוצפנת"
#: converse.js:800
msgid "Verify with SMP"
msgstr "אמת בעזרת SMP"
#: converse.js:803
msgid "Verify with fingerprints"
msgstr "אמת בעזרת טביעות אצבע"
#: converse.js:805
msgid "What's this?"
msgstr "מה זה?"
#: converse.js:906
msgid "me"
msgstr "אני"
#: converse.js:1022 converse.js:1864
msgid "Show this menu"
msgstr "הצג את תפריט זה"
#: converse.js:1023 converse.js:1865
msgid "Write in the third person"
msgstr "כתוב בגוף השלישי"
#: converse.js:1024 converse.js:1869
msgid "Remove messages"
msgstr "הסר הודעות"
#: converse.js:1110
msgid "Your message could not be sent"
msgstr "ההודעה שלך לא היתה יכולה להישלח"
#: converse.js:1113
msgid "We received an unencrypted message"
msgstr "אנחנו קיבלנו הודעה לא מוצפנת"
#: converse.js:1116
msgid "We received an unreadable encrypted message"
msgstr "אנחנו קיבלנו הודעה מוצפנת לא קריאה"
#: converse.js:1125
msgid "This user has requested an encrypted session."
msgstr "משתמש זה ביקש ישיבה מוצפנת."
#: converse.js:1147
msgid ""
"Here are the fingerprints, please confirm them with %1$s, outside of this "
"chat.\n"
"\n"
"Fingerprint for you, %2$s: %3$s\n"
"\n"
"Fingerprint for %1$s: %4$s\n"
"\n"
"If you have confirmed that the fingerprints match, click OK, otherwise click "
"Cancel."
msgstr ""
"הרי טביעות האצבע, אנא אמת אותן עם %1$s, מחוץ לשיחה זו.\n"
"\n"
"טביעת אצבע עבורך, %2$s: %3$s\n"
"\n"
"טביעת אצבע עבור %1$s: %4$s\n"
"\n"
"היה ואימתת כי טביעות האצבע תואמות, לחץ אישור (OK), אחרת לחץ ביטול (Cancel)."
# הקצה השני
#: converse.js:1160
msgid ""
"You will be prompted to provide a security question and then an answer to "
"that question.\n"
"\n"
"Your buddy will then be prompted the same question and if they type the "
"exact same answer (case sensitive), their identity will be verified."
msgstr ""
"אתה תתבקש לספק שאלת אבטחה ולאחריה תשובה לשאלה הזו.\n"
"\n"
"האישיות שכנגד תתבקש עובר זאת לאותה שאלת אבטחה ואם זו תקלידו את את אותה "
"התשובה במדויק (case sensitive), זהותה תאומת."
#: converse.js:1161
msgid "What is your security question?"
msgstr "מהי שאלת האבטחה שלך?"
#: converse.js:1163
msgid "What is the answer to the security question?"
msgstr "מהי התשובה לשאלת האבטחה?"
# תרשים
#: converse.js:1167
msgid "Invalid authentication scheme provided"
msgstr "סופקה סכימת אימות שגויה"
#: converse.js:1248
msgid "Your messages are not encrypted anymore"
msgstr "ההודעות שלך אינן מוצפנות עוד"
#: converse.js:1250
msgid ""
"Your messages are now encrypted but your buddy's identity has not been "
"verified."
msgstr "ההודעות שלך מוצפנות כעת אך זהות האישיות שכנגד טרם אומתה."
#: converse.js:1252
msgid "Your buddy's identify has been verified."
msgstr "זהות האישיות שכנגד אומתה."
#: converse.js:1254
msgid "Your buddy has ended encryption on their end, you should do the same."
msgstr "האישיות שכנגד סיימה הצפנה בקצה שלה, עליך לעשות את אותו הדבר."
#: converse.js:1263
msgid "Your messages are not encrypted. Click here to enable OTR encryption."
msgstr "ההודעות שלך אינן וצפנות. לחץ כאן כדי לאפשר OTR."
#: converse.js:1265
msgid "Your messages are encrypted, but your buddy has not been verified."
msgstr "ההודעות שלך מוצפנות כעת, אך האישיות שכנגד טרם אומתה."
#: converse.js:1267
msgid "Your messages are encrypted and your buddy verified."
msgstr "ההודעות שלך מוצפנות כעת והאישיות שכנגד אומתה."
#: converse.js:1269
msgid ""
"Your buddy has closed their end of the private session, you should do the "
"same"
msgstr "האישיות שכנגד סגרה את קצה הישיבה הפרטית שלה, עליך לעשות את אותו הדבר."
#: converse.js:1354
msgid "Contacts"
msgstr "אנשי קשר"
#: converse.js:1359
msgid "Online"
msgstr "מקוון"
#: converse.js:1360
msgid "Busy"
msgstr "עסוק"
#: converse.js:1361
msgid "Away"
msgstr "נעדר"
#: converse.js:1362
msgid "Offline"
msgstr "בלתי מקוון"
#: converse.js:1372
msgid "Click to add new chat contacts"
msgstr "לחץ כדי להוסיף אנשי קשר שיחה חדשים"
#: converse.js:1373
msgid "Add a contact"
msgstr "הוסף איש קשר"
#: converse.js:1382
msgid "Contact username"
msgstr "שם משתמש איש קשר"
#: converse.js:1383
msgid "Add"
msgstr "הוסף"
#: converse.js:1391
msgid "Contact name"
msgstr "שם איש קשר"
#: converse.js:1392
msgid "Search"
msgstr "חיפוש"
#: converse.js:1439
msgid "No users found"
msgstr "לא נמצאו משתמשים"
#: converse.js:1446
msgid "Click to add as a chat contact"
msgstr "לחץ כדי להוסיף בתור איש קשר שיחה"
#: converse.js:1498
msgid "Click to open this room"
msgstr "לחץ כדי לפתוח את חדר זה"
#: converse.js:1500
msgid "Show more information on this room"
msgstr "הצג עוד מידע אודות חדר זה"
#: converse.js:1506
msgid "Description:"
msgstr "תיאור:"
#: converse.js:1507
msgid "Occupants:"
msgstr "נוכחים:"
#: converse.js:1508
msgid "Features:"
msgstr "תכונות:"
#: converse.js:1510
msgid "Requires authentication"
msgstr "מצריך אישור"
#: converse.js:1513
msgid "Hidden"
msgstr "נסתר"
#: converse.js:1516
msgid "Requires an invitation"
msgstr "מצריך הזמנה"
#: converse.js:1519
msgid "Moderated"
msgstr "מבוקר"
#: converse.js:1522
msgid "Non-anonymous"
msgstr "לא אנונימי"
#: converse.js:1525
msgid "Open room"
msgstr "חדר פתוח"
#: converse.js:1528
msgid "Permanent room"
msgstr "חדר צמיתה"
#: converse.js:1531
msgid "Public"
msgstr "פומבי"
#: converse.js:1534
msgid "Semi-anonymous"
msgstr "אנונימי למחצה"
#: converse.js:1537
msgid "Temporary room"
msgstr "חדר זמני"
#: converse.js:1540
msgid "Unmoderated"
msgstr "לא מבוקר"
#: converse.js:1546
msgid "Rooms"
msgstr "חדרים"
#: converse.js:1550
msgid "Room name"
msgstr "שם חדר"
#: converse.js:1551
msgid "Nickname"
msgstr "שם כינוי"
#: converse.js:1552
msgid "Server"
msgstr "שרת"
#: converse.js:1553
msgid "Join"
msgstr "הצטרף"
#: converse.js:1554
msgid "Show rooms"
msgstr "הצג חדרים"
#. For translators: %1$s is a variable and will be replaced with the XMPP server name
#: converse.js:1589
msgid "No rooms on %1$s"
msgstr "אין חדרים על %1$s"
#. For translators: %1$s is a variable and will be
#. replaced with the XMPP server name
#: converse.js:1604
msgid "Rooms on %1$s"
msgstr "חדרים על %1$s"
#: converse.js:1866
msgid "Set chatroom topic"
msgstr "קבע נושא חדר שיחה"
#: converse.js:1867
msgid "Kick user from chatroom"
msgstr "בעט משתמש מתוך חדר שיחה"
#: converse.js:1868
msgid "Ban user from chatroom"
msgstr "אסור משתמש מתוך חדר שיחה"
#: converse.js:1898
msgid "Message"
msgstr "הודעה"
#: converse.js:2013 converse.js:3168
msgid "Save"
msgstr "שמור"
#: converse.js:2014
msgid "Cancel"
msgstr "ביטול"
#: converse.js:2061
msgid "An error occurred while trying to save the form."
msgstr "אירעה שגיאה במהלך ניסיון שמירת הטופס."
#: converse.js:2107
msgid "This chatroom requires a password"
msgstr "חדר שיחה זה מצריך סיסמה"
#: converse.js:2108
msgid "Password: "
msgstr "סיסמה: "
#: converse.js:2109
msgid "Submit"
msgstr "שלח"
#: converse.js:2123
msgid "This room is not anonymous"
msgstr "חדר זה אינו אנונימי"
#: converse.js:2124
msgid "This room now shows unavailable members"
msgstr "חדר זה כעת מציג חברים לא זמינים"
#: converse.js:2125
msgid "This room does not show unavailable members"
msgstr "חדר זה לא מציג חברים לא זמינים"
#: converse.js:2126
msgid "Non-privacy-related room configuration has changed"
msgstr "תצורת חדר אשר לא-קשורה-בפרטיות שונתה"
#: converse.js:2127
msgid "Room logging is now enabled"
msgstr "יומן חדר הינו מופעל כעת"
#: converse.js:2128
msgid "Room logging is now disabled"
msgstr "יומן חדר הינו מנוטרל כעת"
#: converse.js:2129
msgid "This room is now non-anonymous"
msgstr "חדר זה אינו אנונימי כעת"
#: converse.js:2130
msgid "This room is now semi-anonymous"
msgstr "חדר זה הינו אנונימי למחצה כעת"
#: converse.js:2131
msgid "This room is now fully-anonymous"
msgstr "חדר זה הינו אנונימי לחלוטין כעת"
#: converse.js:2132
msgid "A new room has been created"
msgstr "חדר חדש נוצר"
#: converse.js:2133
msgid "Your nickname has been changed"
msgstr "שם הכינוי שלך שונה"
#: converse.js:2147
msgid "<strong>%1$s</strong> has been banned"
msgstr "<strong>%1$s</strong> נאסר(ה)"
#: converse.js:2148
msgid "<strong>%1$s</strong> has been kicked out"
msgstr "<strong>%1$s</strong> נבעט(ה)"
#: converse.js:2149
msgid "<strong>%1$s</strong> has been removed because of an affiliation change"
msgstr "<strong>%1$s</strong> הוסרה(ה) משום שינוי שיוך"
# היותו(ה)
#: converse.js:2150
msgid "<strong>%1$s</strong> has been removed for not being a member"
msgstr "<strong>%1$s</strong> הוסר(ה) משום אי הימצאות במסגרת מעמד של חבר"
#: converse.js:2154 converse.js:2214
msgid "You have been banned from this room"
msgstr "נאסרת מתוך חדר זה"
#: converse.js:2155
msgid "You have been kicked from this room"
msgstr "נבעטת מתוך חדר זה"
#: converse.js:2156
msgid "You have been removed from this room because of an affiliation change"
msgstr "הוסרת מתוך חדר זה משום שינוי שיוך"
#: converse.js:2157
msgid ""
"You have been removed from this room because the room has changed to members-"
"only and you're not a member"
msgstr "הוסרת מתוך חדר זה משום שהחדר שונה לחברים-בלבד ואינך במעמד של חבר"
#: converse.js:2158
msgid ""
"You have been removed from this room because the MUC (Multi-user chat) "
"service is being shut down."
msgstr ""
"הוסרת מתוך חדר זה משום ששירות שמ״מ (שיחה מרובת משתמשים) זה כעת מצוי בהליכי "
"סגירה."
#: converse.js:2212
msgid "You are not on the member list of this room"
msgstr "אינך ברשימת החברים של חדר זה"
# אף שם כינוי לא צוין
#: converse.js:2218
msgid "No nickname was specified"
msgstr "לא צוין שום שם כינוי"
# אינך מורשה
#: converse.js:2222
msgid "You are not allowed to create new rooms"
msgstr "אין לך רשות ליצור חדרים חדשים"
#: converse.js:2224
msgid "Your nickname doesn't conform to this room's policies"
msgstr "שם הכינוי שלך לא תואם את המדינויות של חדר זה"
# נלקח כבר
#: converse.js:2226
msgid "Your nickname is already taken"
msgstr "שם הכינוי שלך הינו תפוס"
#: converse.js:2228
msgid "This room does not (yet) exist"
msgstr "חדר זה (עדיין) לא קיים"
#: converse.js:2230
msgid "This room has reached it's maximum number of occupants"
msgstr "חדר זה הגיע לסף הנוכחים המרבי שלו"
#: converse.js:2309
msgid "Topic set by %1$s to: %2$s"
msgstr "נושא חדר זה נקבע על ידי %1$s אל: %2$s"
#: converse.js:2330
msgid "This user is a moderator"
msgstr "משתמש זה הינו אחראי"
#: converse.js:2333
msgid "This user can send messages in this room"
msgstr "משתמש זה מסוגל לשלוח הודעות בתוך חדר זה"
#: converse.js:2336
msgid "This user can NOT send messages in this room"
msgstr "משתמש זה ﬥﬡ מסוגל לשלוח הודעות בתוך חדר זה"
#: converse.js:2562
msgid "Click to chat with this contact"
msgstr "לחץ כדי לשוחח עם איש קשר זה"
#: converse.js:2565 converse.js:2569
msgid "Click to remove this contact"
msgstr "לחץ כדי להסיר את איש קשר זה"
#: converse.js:2919
msgid "Contact requests"
msgstr "בקשות איש קשר"
#: converse.js:2922
msgid "My contacts"
msgstr "אנשי הקשר שלי"
#: converse.js:2925
msgid "Pending contacts"
msgstr "אנשי קשר ממתינים"
#: converse.js:3167
msgid "Custom status"
msgstr "מצב מותאם"
#: converse.js:3173
msgid "Click to change your chat status"
msgstr "לחץ כדי לשנות את הודעת השיחה שלך"
#: converse.js:3177
msgid "Click here to write a custom status message"
msgstr "לחץ כאן כדי לכתוב הודעת מצב מותאמת"
#: converse.js:3206 converse.js:3214
msgid "online"
msgstr "מקוון"
#: converse.js:3208
msgid "busy"
msgstr "עסוק"
#: converse.js:3210
msgid "away for long"
msgstr "נעדר לזמן מה"
#: converse.js:3212
msgid "away"
msgstr "נעדר"
# אני במצב
#. For translators: the %1$s part gets replaced with the status
#. Example, I am online
#: converse.js:3226 converse.js:3263
msgid "I am %1$s"
msgstr "מצבי כעת הינו %1$s"
#: converse.js:3334
msgid "Sign in"
msgstr "התחברות"
#: converse.js:3338
msgid "XMPP/Jabber Username:"
msgstr "שם משתמש XMPP/Jabber:"
#: converse.js:3340
msgid "Password:"
msgstr "סיסמה:"
#: converse.js:3342
msgid "Log In"
msgstr "כניסה"
#: converse.js:3346
msgid "BOSH Service URL:"
msgstr "כתובת שירות BOSH:"

622
locale/he/LC_MESSAGES/he.js Normal file
View File

@ -0,0 +1,622 @@
(function (root, factory) {
var translations = {
"domain": "converse",
"locale_data": {
"converse": {
"": {
"Project-Id-Version": "Converse.js 0.7.0",
"Report-Msgid-Bugs-To": "",
"POT-Creation-Date": "2014-01-28 03:50+0200",
"PO-Revision-Date": "2014-02-21 06:07+0200",
"Last-Translator": "GreenLunar <GreenLunar@github.com>",
"Language-Team": "Rahut <http://sourceforge.net/projects/rahut/>",
"Language": "he",
"MIME-Version": "1.0",
"Content-Type": "text/plain; charset=UTF-8",
"Content-Transfer-Encoding": "8bit",
"X-Generator": "Poedit 1.5.1"
},
"unencrypted": [
null,
"לא מוצפנת"
],
"unverified": [
null,
"לא מאומתת"
],
"verified": [
null,
"מאומתת"
],
"finished": [
null,
"מוגמרת"
],
"This contact is busy": [
null,
"איש קשר זה עסוק"
],
"This contact is online": [
null,
"איש קשר זה מקוון"
],
"This contact is offline": [
null,
"איש קשר זה לא מקוון"
],
"This contact is unavailable": [
null,
"איש קשר זה לא זמין"
],
"This contact is away for an extended period": [
null,
"איש קשר זה נעדר למשך זמן ממושך"
],
"This contact is away": [
null,
"איש קשר זה הינו נעדר"
],
"Disconnected": [
null,
"מנותק"
],
"Error": [
null,
"שגיאה"
],
"Connecting": [
null,
"כעת מתחבר"
],
"Connection Failed": [
null,
"חיבור נכשל"
],
"Authenticating": [
null,
"כעת מאמת"
],
"Authentication Failed": [
null,
"אימות נכשל"
],
"Disconnecting": [
null,
"כעת מתנתק"
],
"Online Contacts": [
null,
"אנשי קשר מקוונים"
],
"Re-establishing encrypted session": [
null,
"בסס מחדש ישיבה מוצפנת"
],
"Your browser needs to generate a private key, which will be used in your encrypted chat session. This can take up to 30 seconds during which your browser might freeze and become unresponsive.": [
null,
"על הדפדפן שלך להפיק מפתח פרטי, אשר ישמש אותך בישיבות שיחה מוצפנות. פעולה זו יכולה לקחת למעלה מן 30 שניות אשר במהלכה הדפדפן שלך עשוי לקפוא ולהפוך לחסר תגובה."
],
"Private key generated.": [
null,
"מפתח פרטי הופק."
],
"Authentication request from %1$s\n\nYour buddy is attempting to verify your identity, by asking you the question below.\n\n%2$s": [
null,
"בקשת אימות מאת %1$s\n\nהאישיות שכנגד מנסה לאמת את הזהות שלך, בעזרת שאילת שאלה להלן.\n\n%2$s"
],
"Could not verify this user's identify.": [
null,
"לא היתה אפשרות לאמת את זהות משתמש זה."
],
"Personal message": [
null,
"הודעה אישית"
],
"Start encrypted conversation": [
null,
"התחל ישיבה מוצפנת"
],
"Refresh encrypted conversation": [
null,
"רענן ישיבה מוצפנת"
],
"End encrypted conversation": [
null,
"סיים ישיבה מוצפנת"
],
"Verify with SMP": [
null,
"אמת בעזרת SMP"
],
"Verify with fingerprints": [
null,
"אמת בעזרת טביעות אצבע"
],
"What's this?": [
null,
"מה זה?"
],
"me": [
null,
"אני"
],
"Show this menu": [
null,
"הצג את תפריט זה"
],
"Write in the third person": [
null,
"כתוב בגוף השלישי"
],
"Remove messages": [
null,
"הסר הודעות"
],
"Your message could not be sent": [
null,
"ההודעה שלך לא היתה יכולה להישלח"
],
"We received an unencrypted message": [
null,
"אנחנו קיבלנו הודעה לא מוצפנת"
],
"We received an unreadable encrypted message": [
null,
"אנחנו קיבלנו הודעה מוצפנת לא קריאה"
],
"This user has requested an encrypted session.": [
null,
"משתמש זה ביקש ישיבה מוצפנת."
],
"Here are the fingerprints, please confirm them with %1$s, outside of this chat.\n\nFingerprint for you, %2$s: %3$s\n\nFingerprint for %1$s: %4$s\n\nIf you have confirmed that the fingerprints match, click OK, otherwise click Cancel.": [
null,
"הרי טביעות האצבע, אנא אמת אותן עם %1$s, מחוץ לשיחה זו.\n\nטביעת אצבע עבורך, %2$s: %3$s\n\nטביעת אצבע עבור %1$s: %4$s\n\nהיה ואימתת כי טביעות האצבע תואמות, לחץ אישור (OK), אחרת לחץ ביטול (Cancel)."
],
"You will be prompted to provide a security question and then an answer to that question.\n\nYour buddy will then be prompted the same question and if they type the exact same answer (case sensitive), their identity will be verified.": [
null,
"אתה תתבקש לספק שאלת אבטחה ולאחריה תשובה לשאלה הזו.\n\nהאישיות שכנגד תתבקש עובר זאת לאותה שאלת אבטחה ואם זו תקלידו את את אותה התשובה במדויק (case sensitive), זהותה תאומת."
],
"What is your security question?": [
null,
"מהי שאלת האבטחה שלך?"
],
"What is the answer to the security question?": [
null,
"מהי התשובה לשאלת האבטחה?"
],
"Invalid authentication scheme provided": [
null,
"סופקה סכימת אימות שגויה"
],
"Your messages are not encrypted anymore": [
null,
"ההודעות שלך אינן מוצפנות עוד"
],
"Your messages are now encrypted but your buddy's identity has not been verified.": [
null,
"ההודעות שלך מוצפנות כעת אך זהות האישיות שכנגד טרם אומתה."
],
"Your buddy's identify has been verified.": [
null,
"זהות האישיות שכנגד אומתה."
],
"Your buddy has ended encryption on their end, you should do the same.": [
null,
"האישיות שכנגד סיימה הצפנה בקצה שלה, עליך לעשות את אותו הדבר."
],
"Your messages are not encrypted. Click here to enable OTR encryption.": [
null,
"ההודעות שלך אינן וצפנות. לחץ כאן כדי לאפשר OTR."
],
"Your messages are encrypted, but your buddy has not been verified.": [
null,
"ההודעות שלך מוצפנות כעת, אך האישיות שכנגד טרם אומתה."
],
"Your messages are encrypted and your buddy verified.": [
null,
"ההודעות שלך מוצפנות כעת והאישיות שכנגד אומתה."
],
"Your buddy has closed their end of the private session, you should do the same": [
null,
"האישיות שכנגד סגרה את קצה הישיבה הפרטית שלה, עליך לעשות את אותו הדבר."
],
"Contacts": [
null,
"אנשי קשר"
],
"Online": [
null,
"מקוון"
],
"Busy": [
null,
"עסוק"
],
"Away": [
null,
"נעדר"
],
"Offline": [
null,
"בלתי מקוון"
],
"Click to add new chat contacts": [
null,
"לחץ כדי להוסיף אנשי קשר שיחה חדשים"
],
"Add a contact": [
null,
"הוסף איש קשר"
],
"Contact username": [
null,
"שם משתמש איש קשר"
],
"Add": [
null,
"הוסף"
],
"Contact name": [
null,
"שם איש קשר"
],
"Search": [
null,
"חיפוש"
],
"No users found": [
null,
"לא נמצאו משתמשים"
],
"Click to add as a chat contact": [
null,
"לחץ כדי להוסיף בתור איש קשר שיחה"
],
"Click to open this room": [
null,
"לחץ כדי לפתוח את חדר זה"
],
"Show more information on this room": [
null,
"הצג עוד מידע אודות חדר זה"
],
"Description:": [
null,
"תיאור:"
],
"Occupants:": [
null,
"נוכחים:"
],
"Features:": [
null,
"תכונות:"
],
"Requires authentication": [
null,
"מצריך אישור"
],
"Hidden": [
null,
"נסתר"
],
"Requires an invitation": [
null,
"מצריך הזמנה"
],
"Moderated": [
null,
"מבוקר"
],
"Non-anonymous": [
null,
"לא אנונימי"
],
"Open room": [
null,
"חדר פתוח"
],
"Permanent room": [
null,
"חדר צמיתה"
],
"Public": [
null,
"פומבי"
],
"Semi-anonymous": [
null,
"אנונימי למחצה"
],
"Temporary room": [
null,
"חדר זמני"
],
"Unmoderated": [
null,
"לא מבוקר"
],
"Rooms": [
null,
"חדרים"
],
"Room name": [
null,
"שם חדר"
],
"Nickname": [
null,
"שם כינוי"
],
"Server": [
null,
"שרת"
],
"Join": [
null,
"הצטרף"
],
"Show rooms": [
null,
"הצג חדרים"
],
"No rooms on %1$s": [
null,
"אין חדרים על %1$s"
],
"Rooms on %1$s": [
null,
"חדרים על %1$s"
],
"Set chatroom topic": [
null,
"קבע נושא חדר שיחה"
],
"Kick user from chatroom": [
null,
"בעט משתמש מתוך חדר שיחה"
],
"Ban user from chatroom": [
null,
"אסור משתמש מתוך חדר שיחה"
],
"Message": [
null,
"הודעה"
],
"Save": [
null,
"שמור"
],
"Cancel": [
null,
"ביטול"
],
"An error occurred while trying to save the form.": [
null,
"אירעה שגיאה במהלך ניסיון שמירת הטופס."
],
"This chatroom requires a password": [
null,
"חדר שיחה זה מצריך סיסמה"
],
"Password: ": [
null,
"סיסמה: "
],
"Submit": [
null,
"שלח"
],
"This room is not anonymous": [
null,
"חדר זה אינו אנונימי"
],
"This room now shows unavailable members": [
null,
"חדר זה כעת מציג חברים לא זמינים"
],
"This room does not show unavailable members": [
null,
"חדר זה לא מציג חברים לא זמינים"
],
"Non-privacy-related room configuration has changed": [
null,
"תצורת חדר אשר לא-קשורה-בפרטיות שונתה"
],
"Room logging is now enabled": [
null,
"יומן חדר הינו מופעל כעת"
],
"Room logging is now disabled": [
null,
"יומן חדר הינו מנוטרל כעת"
],
"This room is now non-anonymous": [
null,
"חדר זה אינו אנונימי כעת"
],
"This room is now semi-anonymous": [
null,
"חדר זה הינו אנונימי למחצה כעת"
],
"This room is now fully-anonymous": [
null,
"חדר זה הינו אנונימי לחלוטין כעת"
],
"A new room has been created": [
null,
"חדר חדש נוצר"
],
"Your nickname has been changed": [
null,
"שם הכינוי שלך שונה"
],
"<strong>%1$s</strong> has been banned": [
null,
"<strong>%1$s</strong> נאסר(ה)"
],
"<strong>%1$s</strong> has been kicked out": [
null,
"<strong>%1$s</strong> נבעט(ה)"
],
"<strong>%1$s</strong> has been removed because of an affiliation change": [
null,
"<strong>%1$s</strong> הוסרה(ה) משום שינוי שיוך"
],
"<strong>%1$s</strong> has been removed for not being a member": [
null,
"<strong>%1$s</strong> הוסר(ה) משום אי הימצאות במסגרת מעמד של חבר"
],
"You have been banned from this room": [
null,
"נאסרת מתוך חדר זה"
],
"You have been kicked from this room": [
null,
"נבעטת מתוך חדר זה"
],
"You have been removed from this room because of an affiliation change": [
null,
"הוסרת מתוך חדר זה משום שינוי שיוך"
],
"You have been removed from this room because the room has changed to members-only and you're not a member": [
null,
"הוסרת מתוך חדר זה משום שהחדר שונה לחברים-בלבד ואינך במעמד של חבר"
],
"You have been removed from this room because the MUC (Multi-user chat) service is being shut down.": [
null,
"הוסרת מתוך חדר זה משום ששירות שמ״מ (שיחה מרובת משתמשים) זה כעת מצוי בהליכי סגירה."
],
"You are not on the member list of this room": [
null,
"אינך ברשימת החברים של חדר זה"
],
"No nickname was specified": [
null,
"לא צוין שום שם כינוי"
],
"You are not allowed to create new rooms": [
null,
"אין לך רשות ליצור חדרים חדשים"
],
"Your nickname doesn't conform to this room's policies": [
null,
"שם הכינוי שלך לא תואם את המדינויות של חדר זה"
],
"Your nickname is already taken": [
null,
"שם הכינוי שלך הינו תפוס"
],
"This room does not (yet) exist": [
null,
"חדר זה (עדיין) לא קיים"
],
"This room has reached it's maximum number of occupants": [
null,
"חדר זה הגיע לסף הנוכחים המרבי שלו"
],
"Topic set by %1$s to: %2$s": [
null,
"נושא חדר זה נקבע על ידי %1$s אל: %2$s"
],
"This user is a moderator": [
null,
"משתמש זה הינו אחראי"
],
"This user can send messages in this room": [
null,
"משתמש זה מסוגל לשלוח הודעות בתוך חדר זה"
],
"This user can NOT send messages in this room": [
null,
"משתמש זה ﬥﬡ מסוגל לשלוח הודעות בתוך חדר זה"
],
"Click to chat with this contact": [
null,
"לחץ כדי לשוחח עם איש קשר זה"
],
"Click to remove this contact": [
null,
"לחץ כדי להסיר את איש קשר זה"
],
"Contact requests": [
null,
"בקשות איש קשר"
],
"My contacts": [
null,
"אנשי הקשר שלי"
],
"Pending contacts": [
null,
"אנשי קשר ממתינים"
],
"Custom status": [
null,
"מצב מותאם"
],
"Click to change your chat status": [
null,
"לחץ כדי לשנות את הודעת השיחה שלך"
],
"Click here to write a custom status message": [
null,
"לחץ כאן כדי לכתוב הודעת מצב מותאמת"
],
"online": [
null,
"מקוון"
],
"busy": [
null,
"עסוק"
],
"away for long": [
null,
"נעדר לזמן מה"
],
"away": [
null,
"נעדר"
],
"I am %1$s": [
null,
"מצבי כעת הינו %1$s"
],
"Sign in": [
null,
"התחברות"
],
"XMPP/Jabber Username:": [
null,
"שם משתמש XMPP/Jabber:"
],
"Password:": [
null,
"סיסמה:"
],
"Log In": [
null,
"כניסה"
],
"BOSH Service URL:": [
null,
"כתובת שירות BOSH:"
]
}
}
};
if (typeof define === 'function' && define.amd) {
define("he", ['jed'], function () {
return factory(new Jed(translations));
});
} else {
if (!window.locales) {
window.locales = {};
}
window.locales.he = factory(new Jed(translations));
}
}(this, function (he) {
return he;
}));

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,677 @@
# Bahasa Indonesia translations for Converse.js package.
# Copyright (C) 2014 Jan-Carel Brand
# Copyright (C) 2014 Priyadi Iman Nurcahyo
# This file is distributed under the same license as the Converse.js package.
# Priyadi Iman Nurcahyo <priyadi@priyadi.net>, 2014.
#
msgid ""
msgstr ""
"Project-Id-Version: Converse.js 0.7.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-01-22 17:07+0200\n"
"PO-Revision-Date: 2014-01-25 21:30+0700\n"
"Last-Translator: Priyadi Iman Nurcahyo <priyadi@priyadi.net>\n"
"Language-Team: Bahasa Indonesia\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: id\n"
#: converse.js:217
msgid "unencrypted"
msgstr "tak dienkripsi"
#: converse.js:218
msgid "unverified"
msgstr "tak diverifikasi"
#: converse.js:219
msgid "verified"
msgstr "diverifikasi"
#: converse.js:220
msgid "finished"
msgstr "selesai"
#: converse.js:223
msgid "This contact is busy"
msgstr "Teman ini sedang sibuk"
#: converse.js:224
msgid "This contact is online"
msgstr "Teman ini terhubung"
#: converse.js:225
msgid "This contact is offline"
msgstr "Teman ini tidak terhubung"
#: converse.js:226
msgid "This contact is unavailable"
msgstr "Teman ini tidak tersedia"
#: converse.js:227
msgid "This contact is away for an extended period"
msgstr "Teman ini tidak di tempat untuk waktu yang lama"
#: converse.js:228
msgid "This contact is away"
msgstr "Teman ini tidak di tempat"
#: converse.js:321
msgid "Disconnected"
msgstr "Terputus"
#: converse.js:331
msgid "Error"
msgstr "Kesalahan"
#: converse.js:333
msgid "Connecting"
msgstr "Menyambung"
#: converse.js:336
msgid "Connection Failed"
msgstr "Gagal Menyambung"
#: converse.js:338
msgid "Authenticating"
msgstr "Melakukan otentikasi"
#: converse.js:341
msgid "Authentication Failed"
msgstr "Otentikasi gagal"
#: converse.js:343
msgid "Disconnecting"
msgstr "Memutuskan hubungan"
#: converse.js:479
msgid "Online Contacts"
msgstr "Teman yang Terhubung"
#: converse.js:540
msgid "Re-establishing encrypted session"
msgstr "Menyambung kembali sesi terenkripsi"
#: converse.js:548
msgid ""
"Your browser needs to generate a private key, which will be used in your "
"encrypted chat session. This can take up to 30 seconds during which your "
"browser might freeze and become unresponsive."
msgstr ""
"Perambah anda perlu membuat kunci privat, yang akan digunakan pada sesi "
"perbincangan anda. Ini akan membutuhkan waktu sampai 30 detik, dan selama "
"itu perambah mungkin akan tidak responsif."
#: converse.js:557
msgid "Private key generated."
msgstr "Kunci privat berhasil dibuat."
#: converse.js:588
msgid ""
"Authentication request from %1$s\n"
"\n"
"Your buddy is attempting to verify your identity, by asking you the question "
"below.\n"
"\n"
"%2$s"
msgstr ""
"Permintaan otentikasi dari %1$s\n"
"\n"
"Teman anda mencoba untuk melakukan verifikasi identitas anda dengan cara "
"menanyakan pertanyaan di bawah ini.\n"
"\n"
"%2$s"
#: converse.js:597
msgid "Could not verify this user's identify."
msgstr "Tak dapat melakukan verifikasi identitas pengguna ini."
#: converse.js:750
msgid "Personal message"
msgstr "Pesan pribadi"
#: converse.js:795
msgid "Start encrypted conversation"
msgstr "Mulai sesi terenkripsi"
#: converse.js:798
msgid "Refresh encrypted conversation"
msgstr "Setel ulang percakapan terenkripsi"
#: converse.js:799
msgid "End encrypted conversation"
msgstr "Sudahi percakapan terenkripsi"
#: converse.js:800
msgid "Verify with SMP"
msgstr "Verifikasi menggunakan SMP"
#: converse.js:803
msgid "Verify with fingerprints"
msgstr "Verifikasi menggunakan sidik jari"
#: converse.js:805
msgid "What's this?"
msgstr "Apakah ini?"
#: converse.js:906
msgid "me"
msgstr "saya"
#: converse.js:1022 converse.js:1864
msgid "Show this menu"
msgstr "Tampilkan menu ini"
#: converse.js:1023 converse.js:1865
msgid "Write in the third person"
msgstr "Tulis ini menggunakan bahasa pihak ketiga"
#: converse.js:1024 converse.js:1869
msgid "Remove messages"
msgstr "Hapus pesan"
#: converse.js:1110
msgid "Your message could not be sent"
msgstr "Pesan anda tak dapat dikirim"
#: converse.js:1113
msgid "We received an unencrypted message"
msgstr "Kami menerima pesan terenkripsi"
#: converse.js:1116
msgid "We received an unreadable encrypted message"
msgstr "Kami menerima pesan terenkripsi yang gagal dibaca"
#: converse.js:1125
msgid "This user has requested an encrypted session."
msgstr "Pengguna ini meminta sesi terenkripsi"
#: converse.js:1147
msgid ""
"Here are the fingerprints, please confirm them with %1$s, outside of this "
"chat.\n"
"\n"
"Fingerprint for you, %2$s: %3$s\n"
"\n"
"Fingerprint for %1$s: %4$s\n"
"\n"
"If you have confirmed that the fingerprints match, click OK, otherwise click "
"Cancel."
msgstr ""
"Ini adalah sidik jari anda, konfirmasikan bersama mereka dengan %1$s, di "
"luar percakapan ini.\n"
"\n"
"Sidik jari untuk anda, %2$s: %3$s\n"
"\n"
"Sidik jari untuk %1$s: %4$s\n"
"\n"
"Jika anda bisa mengkonfirmasi sidik jadi cocok, klik Lanjutkan, jika tidak "
"klik Batal."
#: converse.js:1160
msgid ""
"You will be prompted to provide a security question and then an answer to "
"that question.\n"
"\n"
"Your buddy will then be prompted the same question and if they type the "
"exact same answer (case sensitive), their identity will have been verified."
msgstr ""
"Anda akan ditanyakan pertanyaan untuk keamanan beserta jawaban untuk "
"pertanyaan tersebut.\n"
"\n"
"Teman anda akan ditanyakan pertanyaan yang sama dan jika dia memberikan "
"jawaban yang sama (huruf kapital diperhatikan), identitas mereka "
"diverifikasi."
#: converse.js:1161
msgid "What is your security question?"
msgstr "Apakah pertanyaan keamanan anda?"
#: converse.js:1163
msgid "What is the answer to the security question?"
msgstr "Apa jawaban dari pertanyaan keamanan tersebut?"
#: converse.js:1167
msgid "Invalid authentication scheme provided"
msgstr "Skema otentikasi salah"
#: converse.js:1248
msgid "Your messages are not encrypted anymore"
msgstr "Pesan anda tidak lagi terenkripsi"
#: converse.js:1250
msgid ""
"Your messages are now encrypted but your buddy's identity has not been "
"verified."
msgstr ""
"Pesan anda sekarang terenkripsi, namun identitas teman anda belum dapat "
"diverifikasi."
#: converse.js:1252
msgid "Your buddy's identify has been verified."
msgstr "Identitas teman anda telah diverifikasi."
#: converse.js:1254
msgid "Your buddy has ended encryption on their end, you should do the same."
msgstr ""
"Teman anda menghentikan percakapan terenkripsi, anda sebaiknya melakukan hal "
"yang sama."
#: converse.js:1263
msgid "Your messages are not encrypted. Click here to enable OTR encryption."
msgstr ""
"Pesan anda tak terenkripsi. Klik di sini untuk menyalakan enkripsi OTR."
#: converse.js:1265
msgid "Your messages are encrypted, but your buddy has not been verified."
msgstr "Pesan anda terenkripsi, tetapi teman anda belum diverifikasi."
#: converse.js:1267
msgid "Your messages are encrypted and your buddy verified."
msgstr "Pesan anda terenkripsi dan teman anda telah diverifikasi."
#: converse.js:1269
msgid ""
"Your buddy has closed their end of the private session, you should do the "
"same"
msgstr ""
"Teman anda telah mematikan sesi terenkripsi, dan anda juga sebaiknya "
"melakukan hal yang sama"
#: converse.js:1354
msgid "Contacts"
msgstr "Teman"
#: converse.js:1359
msgid "Online"
msgstr "Terhubung"
#: converse.js:1360
msgid "Busy"
msgstr "Sibuk"
#: converse.js:1361
msgid "Away"
msgstr "Pergi"
#: converse.js:1362
msgid "Offline"
msgstr "Tak Terhubung"
#: converse.js:1372
msgid "Click to add new chat contacts"
msgstr "Klik untuk menambahkan teman baru"
#: converse.js:1373
msgid "Add a contact"
msgstr "Tambah teman"
#: converse.js:1382
msgid "Contact username"
msgstr "Username teman"
#: converse.js:1383
msgid "Add"
msgstr "Tambah"
#: converse.js:1391
msgid "Contact name"
msgstr "Nama teman"
#: converse.js:1392
msgid "Search"
msgstr "Cari"
#: converse.js:1439
msgid "No users found"
msgstr "Pengguna tak ditemukan"
#: converse.js:1446
msgid "Click to add as a chat contact"
msgstr "Klik untuk menambahkan sebagai teman"
#: converse.js:1498
msgid "Click to open this room"
msgstr "Klik untuk membuka ruangan ini"
#: converse.js:1500
msgid "Show more information on this room"
msgstr "Tampilkan informasi ruangan ini"
#: converse.js:1506
msgid "Description:"
msgstr "Keterangan:"
#: converse.js:1507
msgid "Occupants:"
msgstr "Penghuni:"
#: converse.js:1508
msgid "Features:"
msgstr "Fitur:"
#: converse.js:1510
msgid "Requires authentication"
msgstr "Membutuhkan otentikasi"
#: converse.js:1513
msgid "Hidden"
msgstr "Tersembunyi"
#: converse.js:1516
msgid "Requires an invitation"
msgstr "Membutuhkan undangan"
#: converse.js:1519
msgid "Moderated"
msgstr "Dimoderasi"
#: converse.js:1522
msgid "Non-anonymous"
msgstr "Tidak anonim"
#: converse.js:1525
msgid "Open room"
msgstr "Ruangan terbuka"
#: converse.js:1528
msgid "Permanent room"
msgstr "Ruangan permanen"
#: converse.js:1531
msgid "Public"
msgstr "Umum"
#: converse.js:1534
msgid "Semi-anonymous"
msgstr "Semi-anonim"
#: converse.js:1537
msgid "Temporary room"
msgstr "Ruangan sementara"
#: converse.js:1540
msgid "Unmoderated"
msgstr "Tak dimoderasi"
#: converse.js:1546
msgid "Rooms"
msgstr "Ruangan"
#: converse.js:1550
msgid "Room name"
msgstr "Nama ruangan"
#: converse.js:1551
msgid "Nickname"
msgstr "Nama panggilan"
#: converse.js:1552
msgid "Server"
msgstr "Server"
#: converse.js:1553
msgid "Join"
msgstr "Ikuti"
#: converse.js:1554
msgid "Show rooms"
msgstr "Perlihatkan ruangan"
#. For translators: %1$s is a variable and will be replaced with the XMPP server name
#: converse.js:1589
msgid "No rooms on %1$s"
msgstr "Tak ada ruangan di %1$s"
#. For translators: %1$s is a variable and will be
#. replaced with the XMPP server name
#: converse.js:1604
msgid "Rooms on %1$s"
msgstr "Ruangan di %1$s"
#: converse.js:1866
msgid "Set chatroom topic"
msgstr "Setel topik ruangan"
#: converse.js:1867
msgid "Kick user from chatroom"
msgstr "Tendang pengguna dari ruangan"
#: converse.js:1868
msgid "Ban user from chatroom"
msgstr "Larang pengguna dari ruangan"
#: converse.js:1898
msgid "Message"
msgstr "Pesan"
#: converse.js:2013 converse.js:3168
msgid "Save"
msgstr "Simpan"
#: converse.js:2014
msgid "Cancel"
msgstr "Batal"
#: converse.js:2061
msgid "An error occurred while trying to save the form."
msgstr "Kesalahan terjadi saat menyimpan formulir ini."
#: converse.js:2107
msgid "This chatroom requires a password"
msgstr "Ruangan ini membutuhkan kata sandi"
#: converse.js:2108
msgid "Password: "
msgstr "Kata sandi: "
#: converse.js:2109
msgid "Submit"
msgstr "Kirim"
#: converse.js:2123
msgid "This room is not anonymous"
msgstr "Ruangan ini tidak anonim"
#: converse.js:2124
msgid "This room now shows unavailable members"
msgstr "Ruangan ini menampilkan anggota yang tak tersedia"
#: converse.js:2125
msgid "This room does not show unavailable members"
msgstr "Ruangan ini tidak menampilkan anggota yang tak tersedia"
#: converse.js:2126
msgid "Non-privacy-related room configuration has changed"
msgstr "Konfigurasi ruangan yang tak berhubungan dengan privasi telah diubah"
#: converse.js:2127
msgid "Room logging is now enabled"
msgstr "Pencatatan di ruangan ini sekarang dinyalakan"
#: converse.js:2128
msgid "Room logging is now disabled"
msgstr "Pencatatan di ruangan ini sekarang dimatikan"
#: converse.js:2129
msgid "This room is now non-anonymous"
msgstr "Ruangan ini sekarang tak-anonim"
#: converse.js:2130
msgid "This room is now semi-anonymous"
msgstr "Ruangan ini sekarang semi-anonim"
#: converse.js:2131
msgid "This room is now fully-anonymous"
msgstr "Ruangan ini sekarang anonim"
#: converse.js:2132
msgid "A new room has been created"
msgstr "Ruangan baru telah dibuat"
#: converse.js:2133
msgid "Your nickname has been changed"
msgstr "Nama panggilan anda telah diubah"
#: converse.js:2147
msgid "<strong>%1$s</strong> has been banned"
msgstr "<strong>%1$s</strong> telah dicekal"
#: converse.js:2148
msgid "<strong>%1$s</strong> has been kicked out"
msgstr "<strong>%1$s</strong> telah ditendang keluar"
#: converse.js:2149
msgid "<strong>%1$s</strong> has been removed because of an affiliation change"
msgstr "<strong>%1$s</strong> telah dihapus karena perubahan afiliasi"
#: converse.js:2150
msgid "<strong>%1$s</strong> has been removed for not being a member"
msgstr "<strong>%1$s</strong> telah dihapus karena bukan anggota"
#: converse.js:2154 converse.js:2214
msgid "You have been banned from this room"
msgstr "Anda telah dicekal dari ruangan ini"
#: converse.js:2155
msgid "You have been kicked from this room"
msgstr "Anda telah ditendang dari ruangan ini"
#: converse.js:2156
msgid "You have been removed from this room because of an affiliation change"
msgstr "Anda telah dihapus dari ruangan ini karena perubahan afiliasi"
#: converse.js:2157
msgid ""
"You have been removed from this room because the room has changed to members-"
"only and you're not a member"
msgstr ""
"Anda telah dihapus dari ruangan ini karena ruangan ini hanya terbuka untuk "
"anggota dan anda bukan anggota"
#: converse.js:2158
msgid ""
"You have been removed from this room because the MUC (Multi-user chat) "
"service is being shut down."
msgstr ""
"Anda telah dihapus dari ruangan ini karena layanan MUC (Multi-user chat) "
"telah dimatikan."
#: converse.js:2212
msgid "You are not on the member list of this room"
msgstr "Anda bukan anggota dari ruangan ini"
#: converse.js:2218
msgid "No nickname was specified"
msgstr "Nama panggilan belum ditentukan"
#: converse.js:2222
msgid "You are not allowed to create new rooms"
msgstr "Anda tak diizinkan untuk membuat ruangan baru"
#: converse.js:2224
msgid "Your nickname doesn't conform to this room's policies"
msgstr "Nama panggilan anda tidak sesuai aturan ruangan ini"
#: converse.js:2226
msgid "Your nickname is already taken"
msgstr "Nama panggilan anda telah digunakan orang lain"
#: converse.js:2228
msgid "This room does not (yet) exist"
msgstr "Ruangan ini belum dibuat"
#: converse.js:2230
msgid "This room has reached it's maximum number of occupants"
msgstr "Ruangan ini telah mencapai jumlah penghuni maksimum"
#: converse.js:2309
msgid "Topic set by %1$s to: %2$s"
msgstr "Topik diganti oleh %1$s menjadi: %2$s"
#: converse.js:2330
msgid "This user is a moderator"
msgstr "Pengguna ini adalah moderator"
#: converse.js:2333
msgid "This user can send messages in this room"
msgstr "Pengguna ini dapat mengirim pesan di ruangan ini"
#: converse.js:2336
msgid "This user can NOT send messages in this room"
msgstr "Pengguna ini tak dapat mengirim pesan di ruangan ini"
#: converse.js:2562
msgid "Click to chat with this contact"
msgstr "Klik untuk mulai perbinjangan dengan teman ini"
#: converse.js:2565 converse.js:2569
msgid "Click to remove this contact"
msgstr "Klik untuk menghapus teman ini"
#: converse.js:2919
msgid "Contact requests"
msgstr "Permintaan pertemanan"
#: converse.js:2922
msgid "My contacts"
msgstr "Teman saya"
#: converse.js:2925
msgid "Pending contacts"
msgstr "Teman yang menunggu"
#: converse.js:3167
msgid "Custom status"
msgstr "Status kustom"
#: converse.js:3173
msgid "Click to change your chat status"
msgstr "Klik untuk mengganti status"
#: converse.js:3177
msgid "Click here to write a custom status message"
msgstr "Klik untuk menulis status kustom"
#: converse.js:3206 converse.js:3214
msgid "online"
msgstr "terhubung"
#: converse.js:3208
msgid "busy"
msgstr "sibuk"
#: converse.js:3210
msgid "away for long"
msgstr "lama tak di tempat"
#: converse.js:3212
msgid "away"
msgstr "tak di tempat"
#. For translators: the %1$s part gets replaced with the status
#. Example, I am online
#: converse.js:3226 converse.js:3263
msgid "I am %1$s"
msgstr "Saya %1$s"
#: converse.js:3334
msgid "Sign in"
msgstr "Masuk"
#: converse.js:3338
msgid "XMPP/Jabber Username:"
msgstr "Nama pengguna XMPP/Jabber:"
#: converse.js:3340
msgid "Password:"
msgstr "Kata sandi:"
#: converse.js:3342
msgid "Log In"
msgstr "Masuk"
#: converse.js:3346
msgid "BOSH Service URL:"
msgstr "URL Layanan BOSH:"

180
locale/id/LC_MESSAGES/id.js Normal file
View File

@ -0,0 +1,180 @@
(function(root, factory) {
var translations = {
"domain": "converse",
"locale_data": {
"converse": {
"": {
"project-id-version": "Converse.js 0.7.0",
"report-msgid-bugs-to": "",
"pot-creation-date": "2014-01-22 17:07+0200",
"po-revision-date": "2014-01-25 21:30+0700",
"last-translator": "Priyadi Iman Nurcahyo <priyadi@priyadi.net>",
"language-team": "Bahasa Indonesia",
"mime-version": "1.0",
"content-type": "text/plain; charset=UTF-8",
"content-transfer-encoding": "8bit",
"language": "id"
},
"unencrypted": [null, "tak dienkripsi"],
"unverified": [null, "tak diverifikasi"],
"verified": [null, "diverifikasi"],
"finished": [null, "selesai"],
"This contact is busy": [null, "Teman ini sedang sibuk"],
"This contact is online": [null, "Teman ini terhubung"],
"This contact is offline": [null, "Teman ini tidak terhubung"],
"This contact is unavailable": [null, "Teman ini tidak tersedia"],
"This contact is away for an extended period": [null, "Teman ini tidak di tempat untuk waktu yang lama"],
"This contact is away": [null, "Teman ini tidak di tempat"],
"Disconnected": [null, "Terputus"],
"Error": [null, "Kesalahan"],
"Connecting": [null, "Menyambung"],
"Connection Failed": [null, "Gagal Menyambung"],
"Authenticating": [null, "Melakukan otentikasi"],
"Authentication Failed": [null, "Otentikasi gagal"],
"Disconnecting": [null, "Memutuskan hubungan"],
"Online Contacts": [null, "Teman yang Terhubung"],
"Re-establishing encrypted session": [null, "Menyambung kembali sesi terenkripsi"],
"Your browser needs to generate a private key, which will be used in your encrypted chat session. This can take up to 30 seconds during which your browser might freeze and become unresponsive.": [null, "Perambah anda perlu membuat kunci privat, yang akan digunakan pada sesi perbincangan anda. Ini akan membutuhkan waktu sampai 30 detik, dan selama itu perambah mungkin akan tidak responsif."],
"Private key generated.": [null, "Kunci privat berhasil dibuat."],
"Authentication request from %1$s\n\nYour buddy is attempting to verify your identity, by asking you the question below.\n\n%2$s": [null, "Permintaan otentikasi dari %1$s\n\nTeman anda mencoba untuk melakukan verifikasi identitas anda dengan cara menanyakan pertanyaan di bawah ini.\n\n%2$s"],
"Could not verify this user's identify.": [null, "Tak dapat melakukan verifikasi identitas pengguna ini."],
"Personal message": [null, "Pesan pribadi"],
"Start encrypted conversation": [null, "Mulai sesi terenkripsi"],
"Refresh encrypted conversation": [null, "Setel ulang percakapan terenkripsi"],
"End encrypted conversation": [null, "Sudahi percakapan terenkripsi"],
"Verify with SMP": [null, "Verifikasi menggunakan SMP"],
"Verify with fingerprints": [null, "Verifikasi menggunakan sidik jari"],
"What's this?": [null, "Apakah ini?"],
"me": [null, "saya"],
"Show this menu": [null, "Tampilkan menu ini"],
"Write in the third person": [null, "Tulis ini menggunakan bahasa pihak ketiga"],
"Remove messages": [null, "Hapus pesan"],
"Your message could not be sent": [null, "Pesan anda tak dapat dikirim"],
"We received an unencrypted message": [null, "Kami menerima pesan terenkripsi"],
"We received an unreadable encrypted message": [null, "Kami menerima pesan terenkripsi yang gagal dibaca"],
"This user has requested an encrypted session.": [null, "Pengguna ini meminta sesi terenkripsi"],
"Here are the fingerprints, please confirm them with %1$s, outside of this chat.\n\nFingerprint for you, %2$s: %3$s\n\nFingerprint for %1$s: %4$s\n\nIf you have confirmed that the fingerprints match, click OK, otherwise click Cancel.": [null, "Ini adalah sidik jari anda, konfirmasikan bersama mereka dengan %1$s, di luar percakapan ini.\n\nSidik jari untuk anda, %2$s: %3$s\n\nSidik jari untuk %1$s: %4$s\n\nJika anda bisa mengkonfirmasi sidik jadi cocok, klik Lanjutkan, jika tidak klik Batal."],
"You will be prompted to provide a security question and then an answer to that question.\n\nYour buddy will then be prompted the same question and if they type the exact same answer (case sensitive), their identity will have been verified.": [null, "Anda akan ditanyakan pertanyaan untuk keamanan beserta jawaban untuk pertanyaan tersebut.\n\nTeman anda akan ditanyakan pertanyaan yang sama dan jika dia memberikan jawaban yang sama (huruf kapital diperhatikan), identitas mereka diverifikasi."],
"What is your security question?": [null, "Apakah pertanyaan keamanan anda?"],
"What is the answer to the security question?": [null, "Apa jawaban dari pertanyaan keamanan tersebut?"],
"Invalid authentication scheme provided": [null, "Skema otentikasi salah"],
"Your messages are not encrypted anymore": [null, "Pesan anda tidak lagi terenkripsi"],
"Your messages are now encrypted but your buddy's identity has not been verified.": [null, "Pesan anda sekarang terenkripsi, namun identitas teman anda belum dapat diverifikasi."],
"Your buddy's identify has been verified.": [null, "Identitas teman anda telah diverifikasi."],
"Your buddy has ended encryption on their end, you should do the same.": [null, "Teman anda menghentikan percakapan terenkripsi, anda sebaiknya melakukan hal yang sama."],
"Your messages are not encrypted. Click here to enable OTR encryption.": [null, "Pesan anda tak terenkripsi. Klik di sini untuk menyalakan enkripsi OTR."],
"Your messages are encrypted, but your buddy has not been verified.": [null, "Pesan anda terenkripsi, tetapi teman anda belum diverifikasi."],
"Your messages are encrypted and your buddy verified.": [null, "Pesan anda terenkripsi dan teman anda telah diverifikasi."],
"Your buddy has closed their end of the private session, you should do the same": [null, "Teman anda telah mematikan sesi terenkripsi, dan anda juga sebaiknya melakukan hal yang sama"],
"Contacts": [null, "Teman"],
"Online": [null, "Terhubung"],
"Busy": [null, "Sibuk"],
"Away": [null, "Pergi"],
"Offline": [null, "Tak Terhubung"],
"Click to add new chat contacts": [null, "Klik untuk menambahkan teman baru"],
"Add a contact": [null, "Tambah teman"],
"Contact username": [null, "Username teman"],
"Add": [null, "Tambah"],
"Contact name": [null, "Nama teman"],
"Search": [null, "Cari"],
"No users found": [null, "Pengguna tak ditemukan"],
"Click to add as a chat contact": [null, "Klik untuk menambahkan sebagai teman"],
"Click to open this room": [null, "Klik untuk membuka ruangan ini"],
"Show more information on this room": [null, "Tampilkan informasi ruangan ini"],
"Description:": [null, "Keterangan:"],
"Occupants:": [null, "Penghuni:"],
"Features:": [null, "Fitur:"],
"Requires authentication": [null, "Membutuhkan otentikasi"],
"Hidden": [null, "Tersembunyi"],
"Requires an invitation": [null, "Membutuhkan undangan"],
"Moderated": [null, "Dimoderasi"],
"Non-anonymous": [null, "Tidak anonim"],
"Open room": [null, "Ruangan terbuka"],
"Permanent room": [null, "Ruangan permanen"],
"Public": [null, "Umum"],
"Semi-anonymous": [null, "Semi-anonim"],
"Temporary room": [null, "Ruangan sementara"],
"Unmoderated": [null, "Tak dimoderasi"],
"Rooms": [null, "Ruangan"],
"Room name": [null, "Nama ruangan"],
"Nickname": [null, "Nama panggilan"],
"Server": [null, "Server"],
"Join": [null, "Ikuti"],
"Show rooms": [null, "Perlihatkan ruangan"],
"No rooms on %1$s": [null, "Tak ada ruangan di %1$s"],
"Rooms on %1$s": [null, "Ruangan di %1$s"],
"Set chatroom topic": [null, "Setel topik ruangan"],
"Kick user from chatroom": [null, "Tendang pengguna dari ruangan"],
"Ban user from chatroom": [null, "Larang pengguna dari ruangan"],
"Message": [null, "Pesan"],
"Save": [null, "Simpan"],
"Cancel": [null, "Batal"],
"An error occurred while trying to save the form.": [null, "Kesalahan terjadi saat menyimpan formulir ini."],
"This chatroom requires a password": [null, "Ruangan ini membutuhkan kata sandi"],
"Password: ": [null, "Kata sandi: "],
"Submit": [null, "Kirim"],
"This room is not anonymous": [null, "Ruangan ini tidak anonim"],
"This room now shows unavailable members": [null, "Ruangan ini menampilkan anggota yang tak tersedia"],
"This room does not show unavailable members": [null, "Ruangan ini tidak menampilkan anggota yang tak tersedia"],
"Non-privacy-related room configuration has changed": [null, "Konfigurasi ruangan yang tak berhubungan dengan privasi telah diubah"],
"Room logging is now enabled": [null, "Pencatatan di ruangan ini sekarang dinyalakan"],
"Room logging is now disabled": [null, "Pencatatan di ruangan ini sekarang dimatikan"],
"This room is now non-anonymous": [null, "Ruangan ini sekarang tak-anonim"],
"This room is now semi-anonymous": [null, "Ruangan ini sekarang semi-anonim"],
"This room is now fully-anonymous": [null, "Ruangan ini sekarang anonim"],
"A new room has been created": [null, "Ruangan baru telah dibuat"],
"Your nickname has been changed": [null, "Nama panggilan anda telah diubah"],
"<strong>%1$s</strong> has been banned": [null, "<strong>%1$s</strong> telah dicekal"],
"<strong>%1$s</strong> has been kicked out": [null, "<strong>%1$s</strong> telah ditendang keluar"],
"<strong>%1$s</strong> has been removed because of an affiliation change": [null, "<strong>%1$s</strong> telah dihapus karena perubahan afiliasi"],
"<strong>%1$s</strong> has been removed for not being a member": [null, "<strong>%1$s</strong> telah dihapus karena bukan anggota"],
"You have been banned from this room": [null, "Anda telah dicekal dari ruangan ini"],
"You have been kicked from this room": [null, "Anda telah ditendang dari ruangan ini"],
"You have been removed from this room because of an affiliation change": [null, "Anda telah dihapus dari ruangan ini karena perubahan afiliasi"],
"You have been removed from this room because the room has changed to members-only and you're not a member": [null, "Anda telah dihapus dari ruangan ini karena ruangan ini hanya terbuka untuk anggota dan anda bukan anggota"],
"You have been removed from this room because the MUC (Multi-user chat) service is being shut down.": [null, "Anda telah dihapus dari ruangan ini karena layanan MUC (Multi-user chat) telah dimatikan."],
"You are not on the member list of this room": [null, "Anda bukan anggota dari ruangan ini"],
"No nickname was specified": [null, "Nama panggilan belum ditentukan"],
"You are not allowed to create new rooms": [null, "Anda tak diizinkan untuk membuat ruangan baru"],
"Your nickname doesn't conform to this room's policies": [null, "Nama panggilan anda tidak sesuai aturan ruangan ini"],
"Your nickname is already taken": [null, "Nama panggilan anda telah digunakan orang lain"],
"This room does not (yet) exist": [null, "Ruangan ini belum dibuat"],
"This room has reached it's maximum number of occupants": [null, "Ruangan ini telah mencapai jumlah penghuni maksimum"],
"Topic set by %1$s to: %2$s": [null, "Topik diganti oleh %1$s menjadi: %2$s"],
"This user is a moderator": [null, "Pengguna ini adalah moderator"],
"This user can send messages in this room": [null, "Pengguna ini dapat mengirim pesan di ruangan ini"],
"This user can NOT send messages in this room": [null, "Pengguna ini tak dapat mengirim pesan di ruangan ini"],
"Click to chat with this contact": [null, "Klik untuk mulai perbinjangan dengan teman ini"],
"Click to remove this contact": [null, "Klik untuk menghapus teman ini"],
"Contact requests": [null, "Permintaan pertemanan"],
"My contacts": [null, "Teman saya"],
"Pending contacts": [null, "Teman yang menunggu"],
"Custom status": [null, "Status kustom"],
"Click to change your chat status": [null, "Klik untuk mengganti status"],
"Click here to write a custom status message": [null, "Klik untuk menulis status kustom"],
"online": [null, "terhubung"],
"busy": [null, "sibuk"],
"away for long": [null, "lama tak di tempat"],
"away": [null, "tak di tempat"],
"I am %1$s": [null, "Saya %1$s"],
"Sign in": [null, "Masuk"],
"XMPP/Jabber Username:": [null, "Nama pengguna XMPP/Jabber:"],
"Password:": [null, "Kata sandi:"],
"Log In": [null, "Masuk"],
"BOSH Service URL:": [null, "URL Layanan BOSH:"]
}
}
};
if (typeof define === 'function' && define.amd) {
define("id", ['jed'], function () {
return factory(new Jed(translations));
});
} else {
if (!window.locales) {
window.locales = {};
}
window.locales.id = factory(new Jed(translations));
}
}(this, function (id) {
return id;
}));

View File

@ -14,7 +14,9 @@
"en": "locale/en/LC_MESSAGES/en",
"es": "locale/es/LC_MESSAGES/es",
"fr": "locale/fr/LC_MESSAGES/fr",
"he": "locale/he/LC_MESSAGES/he",
"hu": "locale/hu/LC_MESSAGES/hu",
"id": "locale/id/LC_MESSAGES/id",
"it": "locale/it/LC_MESSAGES/it",
"ja": "locale/ja/LC_MESSAGES/ja",
"nl": "locale/nl/LC_MESSAGES/nl",
@ -30,20 +32,24 @@
'en',
'es',
'fr',
'he',
'hu',
'id',
'it',
'ja',
'nl',
'pt_BR',
'ru'
], function (jed, af, de, en, es, fr, hu, it, ja, nl, pt_BR, ru) {
], function (jed, af, de, en, es, fr, he, hu, id, it, ja, nl, pt_BR, ru) {
root.locales = {
'af': af,
'de': de,
'en': en,
'es': es,
'fr': fr,
'he': he,
'hu': hu,
'id': id,
'it': it,
'ja': ja,
'nl': nl,

View File

@ -1,6 +1,6 @@
{
"name": "converse.js",
"version": "0.7.2",
"version": "0.7.3",
"description": "Browser based XMPP instant messaging client",
"main": "main.js",
"directories": {

View File

@ -8,60 +8,40 @@
);
} (this, function (mock, utils) {
return describe("Converse", $.proxy(function(mock, utils) {
window.localStorage.clear();
it("allows you to subscribe to emitted events", function () {
this.callback = function () {};
spyOn(this, 'callback');
converse.on('onInitialized', this.callback);
converse.emit('onInitialized');
expect(this.callback).toHaveBeenCalled();
converse.emit('onInitialized');
expect(this.callback.callCount, 2);
converse.emit('onInitialized');
expect(this.callback.callCount, 3);
});
beforeEach($.proxy(function () {
window.localStorage.clear();
window.sessionStorage.clear();
}, converse));
it("allows you to listen once for an emitted event", function () {
this.callback = function () {};
spyOn(this, 'callback');
converse.once('onInitialized', this.callback);
converse.emit('onInitialized');
expect(this.callback).toHaveBeenCalled();
converse.emit('onInitialized');
expect(this.callback.callCount, 1);
converse.emit('onInitialized');
expect(this.callback.callCount, 1);
});
it("has an API method for retrieving the next RID", $.proxy(function () {
var old_connection = converse.connection;
converse.connection.rid = '1234';
converse.expose_rid_and_sid = false;
expect(converse_api.getRID()).toBe(null);
it("allows you to stop listening or subscribing to an event", function () {
this.callback = function () {};
this.anotherCallback = function () {};
this.neverCalled = function () {};
converse.expose_rid_and_sid = true;
expect(converse_api.getRID()).toBe('1234');
spyOn(this, 'callback');
spyOn(this, 'anotherCallback');
spyOn(this, 'neverCalled');
converse.on('onInitialized', this.callback);
converse.on('onInitialized', this.anotherCallback);
converse.connection = undefined;
expect(converse_api.getRID()).toBe(null);
// Restore the connection
converse.connection = old_connection;
}, converse));
converse.emit('onInitialized');
expect(this.callback).toHaveBeenCalled();
expect(this.anotherCallback).toHaveBeenCalled();
it("has an API method for retrieving the SID", $.proxy(function () {
var old_connection = converse.connection;
converse.connection.sid = '1234';
converse.expose_rid_and_sid = false;
expect(converse_api.getSID()).toBe(null);
converse.off('onInitialized', this.callback);
converse.expose_rid_and_sid = true;
expect(converse_api.getSID()).toBe('1234');
converse.emit('onInitialized');
expect(this.callback.callCount, 1);
expect(this.anotherCallback.callCount, 2);
converse.once('onInitialized', this.neverCalled);
converse.off('onInitialized', this.neverCalled);
converse.emit('onInitialized');
expect(this.callback.callCount, 1);
expect(this.anotherCallback.callCount, 3);
expect(this.neverCalled).not.toHaveBeenCalled();
});
converse.connection = undefined;
expect(converse_api.getSID()).toBe(null);
// Restore the connection
converse.connection = old_connection;
}, converse));
}, converse, mock, utils));
}));

67
spec/eventemitter.js Normal file
View File

@ -0,0 +1,67 @@
(function (root, factory) {
define([
"mock",
"utils"
], function (mock, utils) {
return factory(mock, utils);
}
);
} (this, function (mock, utils) {
return describe("The Converse Event Emitter", $.proxy(function(mock, utils) {
window.localStorage.clear();
it("allows you to subscribe to emitted events", function () {
this.callback = function () {};
spyOn(this, 'callback');
converse.on('onInitialized', this.callback);
converse.emit('onInitialized');
expect(this.callback).toHaveBeenCalled();
converse.emit('onInitialized');
expect(this.callback.callCount, 2);
converse.emit('onInitialized');
expect(this.callback.callCount, 3);
});
it("allows you to listen once for an emitted event", function () {
this.callback = function () {};
spyOn(this, 'callback');
converse.once('onInitialized', this.callback);
converse.emit('onInitialized');
expect(this.callback).toHaveBeenCalled();
converse.emit('onInitialized');
expect(this.callback.callCount, 1);
converse.emit('onInitialized');
expect(this.callback.callCount, 1);
});
it("allows you to stop listening or subscribing to an event", function () {
this.callback = function () {};
this.anotherCallback = function () {};
this.neverCalled = function () {};
spyOn(this, 'callback');
spyOn(this, 'anotherCallback');
spyOn(this, 'neverCalled');
converse.on('onInitialized', this.callback);
converse.on('onInitialized', this.anotherCallback);
converse.emit('onInitialized');
expect(this.callback).toHaveBeenCalled();
expect(this.anotherCallback).toHaveBeenCalled();
converse.off('onInitialized', this.callback);
converse.emit('onInitialized');
expect(this.callback.callCount, 1);
expect(this.anotherCallback.callCount, 2);
converse.once('onInitialized', this.neverCalled);
converse.off('onInitialized', this.neverCalled);
converse.emit('onInitialized');
expect(this.callback.callCount, 1);
expect(this.anotherCallback.callCount, 3);
expect(this.neverCalled).not.toHaveBeenCalled();
});
}, converse, mock, utils));
}));

40
spec/otr.js Normal file
View File

@ -0,0 +1,40 @@
(function (root, factory) {
define([
"mock",
"utils"
], function (mock, utils) {
return factory(mock, utils);
}
);
} (this, function (mock, utils) {
return describe("The OTR module", $.proxy(function(mock, utils) {
beforeEach($.proxy(function () {
window.localStorage.clear();
window.sessionStorage.clear();
}, converse));
it("can store a session passphrase in session storage", $.proxy(function () {
var pp;
// With no prebind, the user's XMPP password is used and nothing is
// stored in session storage.
this.prebind = false;
this.connection.pass = 's3cr3t!';
expect(this.otr.getSessionPassphrase()).toBe(this.connection.pass);
expect(window.sessionStorage.length).toBe(0);
expect(window.localStorage.length).toBe(0);
// With prebind, a random passphrase is generated and stored in
// session storage.
this.prebind = true;
pp = this.otr.getSessionPassphrase();
expect(pp).not.toBe(this.connection.pass);
expect(window.sessionStorage.length).toBe(1);
expect(window.localStorage.length).toBe(0);
expect(pp).toBe(window.sessionStorage[hex_sha1(converse.connection.jid)]);
// Clean up
this.prebind = false;
}, converse));
}, converse, mock, utils));
}));

View File

@ -7,8 +7,6 @@
"jquery": "components/jquery/jquery",
"jed": "components/jed/jed",
"locales": "locale/nolocales",
"pt_BR": "locale/pt_BR/LC_MESSAGES/pt_BR",
"ru": "locale/ru/LC_MESSAGES/ru",
"jquery.tinysort": "components/tinysort/src/jquery.tinysort",
"underscore": "components/underscore/underscore",
"backbone": "components/backbone/backbone",

View File

@ -12,8 +12,11 @@
"en": "locale/en/LC_MESSAGES/en",
"es": "locale/es/LC_MESSAGES/es",
"fr": "locale/fr/LC_MESSAGES/fr",
"he": "locale/he/LC_MESSAGES/he",
"hu": "locale/hu/LC_MESSAGES/hu",
"it": "locale/it/LC_MESSAGES/it",
"id": "locale/id/LC_MESSAGES/id",
"ja": "locale/ja/LC_MESSAGES/ja",
"nl": "locale/nl/LC_MESSAGES/nl",
"pt_BR": "locale/pt_BR/LC_MESSAGES/pt_BR",
"ru": "locale/ru/LC_MESSAGES/ru",

View File

@ -12,8 +12,11 @@
"en": "locale/en/LC_MESSAGES/en",
"es": "locale/es/LC_MESSAGES/es",
"fr": "locale/fr/LC_MESSAGES/fr",
"he": "locale/he/LC_MESSAGES/he",
"hu": "locale/hu/LC_MESSAGES/hu",
"id": "locale/id/LC_MESSAGES/id",
"it": "locale/it/LC_MESSAGES/it",
"ja": "locale/ja/LC_MESSAGES/ja",
"nl": "locale/nl/LC_MESSAGES/nl",
"pt_BR": "locale/pt_BR/LC_MESSAGES/pt_BR",
"ru": "locale/ru/LC_MESSAGES/ru",

View File

@ -47,6 +47,7 @@ require([
"jasmine-html"
], function($, converse, mock, jasmine) {
// Set up converse.js
window.converse_api = converse;
window.localStorage.clear();
converse.initialize({
prebind: false,
@ -58,10 +59,20 @@ require([
testing: true
}, function (converse) {
window.converse = converse;
window.crypto = {
getRandomValues: function (buf) {
var i;
for (i=0, len=buf.length; i<len; i++) {
buf[i] = Math.floor(Math.random()*256);
}
}
};
require([
"jasmine-console-reporter",
"jasmine-junit-reporter",
"spec/converse",
"spec/otr",
"spec/eventemitter",
"spec/controlbox",
"spec/chatbox",
"spec/chatroom"