tor-commits
Threads by month
- ----- 2025 -----
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
October 2016
- 18 participants
- 868 discussions

[tor/master] Merge remote-tracking branch 'yawning-schwanenlied/bug20261'
by nickm@torproject.org 11 Oct '16
by nickm@torproject.org 11 Oct '16
11 Oct '16
commit d25fed51746e848fc04cabefe58133e3957209de
Merge: 5a9696f 7b2c856
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Tue Oct 11 11:08:20 2016 -0400
Merge remote-tracking branch 'yawning-schwanenlied/bug20261'
changes/bug20261 | 4 ++++
doc/tor.1.txt | 5 +++--
src/common/address.c | 16 ++++++++++++++++
src/or/config.c | 7 +++++++
4 files changed, 30 insertions(+), 2 deletions(-)
1
0

[tor/master] Switch from "AF_UNIX is always equal" to "always unequal" to avoid wacky bugs. See discussion on 20261
by nickm@torproject.org 11 Oct '16
by nickm@torproject.org 11 Oct '16
11 Oct '16
commit 2e7e635c593f13012303ced2bb85d50ed3195d24
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Tue Oct 11 11:11:21 2016 -0400
Switch from "AF_UNIX is always equal" to "always unequal" to avoid wacky bugs. See discussion on 20261
---
src/common/address.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/src/common/address.c b/src/common/address.c
index dae1800..773e688 100644
--- a/src/common/address.c
+++ b/src/common/address.c
@@ -1042,9 +1042,9 @@ tor_addr_copy_tight(tor_addr_t *dest, const tor_addr_t *src)
* <b>how</b> is CMP_EXACT; otherwise, IPv6-mapped IPv4 addresses are
* considered equivalent to their IPv4 equivalents.
*
- * As a special case, all AF_UNIX addresses are always considered equal
- * since tor_addr_t currently does not contain the information required to
- * make the comparison.
+ * As a special case, all pointer-wise distinct AF_UNIX addresses are always
+ * considered unequal since tor_addr_t currently does not contain the
+ * information required to make the comparison.
*/
int
tor_addr_compare(const tor_addr_t *addr1, const tor_addr_t *addr2,
@@ -1125,11 +1125,17 @@ tor_addr_compare_masked(const tor_addr_t *addr1, const tor_addr_t *addr2,
*
* Since the only time we currently actually should be comparing
* 2 AF_UNIX addresses is when dealing with ISO_CLIENTADDR (which
- * is diesabled for AF_UNIX SocksPorts anyway), this just returns 0.
+ * is disabled for AF_UNIX SocksPorts anyway), this just does
+ * a pointer comparison.
*
* See: #20261.
*/
- return 0;
+ if (addr1 < addr2)
+ return -1;
+ else if (addr1 == addr2)
+ return 0;
+ else
+ return 1;
default:
/* LCOV_EXCL_START */
tor_fragile_assert();
1
0

[tor/master] Fix a new compilation warning with broken-mulodi i386 clang builds. :(
by nickm@torproject.org 11 Oct '16
by nickm@torproject.org 11 Oct '16
11 Oct '16
commit 5a9696fad864406d7d65cc25e356c543957e596f
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Tue Oct 11 10:29:43 2016 -0400
Fix a new compilation warning with broken-mulodi i386 clang builds. :(
---
src/ext/mulodi/mulodi4.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/ext/mulodi/mulodi4.c b/src/ext/mulodi/mulodi4.c
index bfa5e01..9891bbf 100644
--- a/src/ext/mulodi/mulodi4.c
+++ b/src/ext/mulodi/mulodi4.c
@@ -17,6 +17,7 @@
#else
#define COMPILER_RT_ABI
#define di_int int64_t
+#define di_uint uint64_t
#include "torint.h"
di_int __mulodi4(di_int a, di_int b, int* overflow);
@@ -30,9 +31,9 @@ COMPILER_RT_ABI di_int
__mulodi4(di_int a, di_int b, int* overflow)
{
const int N = (int)(sizeof(di_int) * CHAR_BIT);
- const di_int MIN = (di_int)1 << (N-1);
+ const di_int MIN = (di_int) ((di_uint)1 << (N-1));
const di_int MAX = ~MIN;
- *overflow = 0;
+ *overflow = 0;
di_int result = a * b;
if (a == MIN)
{
1
0

11 Oct '16
commit 7026b607a0b873ddbee16d5bd8ac2975c7092f5b
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Tue Oct 11 09:34:08 2016 -0400
Fix spurious compiler warning in do_getpass().
Some compilers apparently noticed that p2len was allowed to be equal
to msg, and so maybe we would be doing memset(prompt2, ' ', 0), and
decided that we probably meant to do memset(prompt2, 0, 0x20);
instead.
Stupid compilers, doing optimization before this kind of warning!
My fix is to just fill the entire prompt2 buffer with spaces,
because it's harmless.
Bugfix on e59f0d4cb964387c5, not in any released Tor.
---
src/or/routerkeys.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/or/routerkeys.c b/src/or/routerkeys.c
index d5e7051..ca32228 100644
--- a/src/or/routerkeys.c
+++ b/src/or/routerkeys.c
@@ -49,7 +49,7 @@ do_getpass(const char *prompt, char *buf, size_t buflen,
if (p2len < sizeof(msg))
p2len = sizeof(msg);
prompt2 = tor_malloc(p2len);
- memset(prompt2, ' ', p2len - sizeof(msg));
+ memset(prompt2, ' ', p2len);
memcpy(prompt2 + p2len - sizeof(msg), msg, sizeof(msg));
buf2 = tor_malloc_zero(buflen);
1
0
commit ab78a4df93d1aed26cb13343cdd012c8309a206f
Author: paolo.ingls(a)gmail.com <paolo.ingls(a)gmail.com>
Date: Mon Sep 26 23:25:16 2016 +0200
torrc parsing b0rks on carriage-return
(Specifically, carriage return after a quoted value in a config
line. Fixes bug 19167; bugfix on 0.2.0.16-alpha when we introduced
support for quoted values. Unit tests, changes file, and this
parenthetical by nickm.)
---
changes/bug19167 | 4 ++++
src/common/util.c | 2 ++
src/test/test_util.c | 31 +++++++++++++++++++++++++++++++
3 files changed, 37 insertions(+)
diff --git a/changes/bug19167 b/changes/bug19167
new file mode 100644
index 0000000..4a6c22d
--- /dev/null
+++ b/changes/bug19167
@@ -0,0 +1,4 @@
+ o Minor bugfixes (configuration):
+ - When parsing quoted configuration values from the torrc file,
+ handle windows line endings correctly. Fixes bug 19167; bugfix on
+ 0.2.0.16-alpha. Patch from "Pingl".
diff --git a/src/common/util.c b/src/common/util.c
index 259ff87..d1c87d3 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -3079,6 +3079,8 @@ parse_config_line_from_str_verbose(const char *line, char **key_out,
}
while (*line == ' ' || *line == '\t')
++line;
+ if (*line == '\r' && *(++line) == '\n')
+ ++line;
if (*line && *line != '#' && *line != '\n') {
if (err_out)
*err_out = "Excess data after quoted string";
diff --git a/src/test/test_util.c b/src/test/test_util.c
index d2152dd..8d5dce3 100644
--- a/src/test/test_util.c
+++ b/src/test/test_util.c
@@ -1642,6 +1642,36 @@ test_util_config_line_escaped_content(void *arg)
tor_free(v);
}
+static void
+test_util_config_line_crlf(void *arg)
+{
+ char *k=NULL, *v=NULL;
+ const char *err = NULL;
+ (void)arg;
+ const char *str =
+ "Hello world\r\n"
+ "Hello \"nice big world\"\r\n";
+
+ str = parse_config_line_from_str_verbose(str, &k, &v, &err);
+ tt_assert(str);
+ tt_str_op(k,OP_EQ,"Hello");
+ tt_str_op(v,OP_EQ,"world");
+ tt_assert(!err);
+ tor_free(k); tor_free(v);
+
+ str = parse_config_line_from_str_verbose(str, &k, &v, &err);
+ tt_assert(str);
+ tt_str_op(k,OP_EQ,"Hello");
+ tt_str_op(v,OP_EQ,"nice big world");
+ tt_assert(!err);
+ tor_free(k); tor_free(v);
+ tt_str_op(str,OP_EQ, "");
+
+ done:
+ tor_free(k); tor_free(v);
+}
+
+
#ifndef _WIN32
static void
test_util_expand_filename(void *arg)
@@ -5609,6 +5639,7 @@ struct testcase_t util_tests[] = {
UTIL_LEGACY(config_line_quotes),
UTIL_LEGACY(config_line_comment_character),
UTIL_LEGACY(config_line_escaped_content),
+ UTIL_LEGACY(config_line_crlf),
UTIL_LEGACY_NO_WIN(expand_filename),
UTIL_LEGACY(escape_string_socks),
UTIL_LEGACY(string_is_key_value),
1
0

[tor-browser-bundle/master] Bug 20217: check that OSX incremental MARs are made with code signing
by gk@torproject.org 11 Oct '16
by gk@torproject.org 11 Oct '16
11 Oct '16
commit 9836227e4ae27123a3eb27167dc6dca13b5d1027
Author: Nicolas Vigier <boklm(a)torproject.org>
Date: Mon Oct 10 19:44:10 2016 +0200
Bug 20217: check that OSX incremental MARs are made with code signing
When updating the OSX incremental MAR files after running dmg2mar, we check
that both the old and the new mar files contain code signing.
We don't check this while creating the incremental MAR files during the
build.
---
gitian/Makefile | 4 ++--
tools/update-responses/update_responses | 6 ++++++
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/gitian/Makefile b/gitian/Makefile
index f008834..a4a757f 100644
--- a/gitian/Makefile
+++ b/gitian/Makefile
@@ -48,12 +48,12 @@ signmars-nightly:
dmg2mars:
cd $(shell ../tools/update-responses/get_channel_version release) && ../../tools/dmg2mar
$(TORSOCKS) ../tools/update-responses/download_missing_versions release
- MAR_SKIP_EXISTING=1 ../tools/update-responses/gen_incrementals release
+ CHECK_CODESIGNATURE_EXISTS=1 MAR_SKIP_EXISTING=1 ../tools/update-responses/gen_incrementals release
dmg2mars-alpha:
cd $(shell ../tools/update-responses/get_channel_version alpha) && ../../tools/dmg2mar
$(TORSOCKS) ../tools/update-responses/download_missing_versions alpha
- MAR_SKIP_EXISTING=1 ../tools/update-responses/gen_incrementals alpha
+ CHECK_CODESIGNATURE_EXISTS=1 MAR_SKIP_EXISTING=1 ../tools/update-responses/gen_incrementals alpha
update_responses:
../tools/update-responses/update_responses release
diff --git a/tools/update-responses/update_responses b/tools/update-responses/update_responses
index 7962f69..ceba144 100755
--- a/tools/update-responses/update_responses
+++ b/tools/update-responses/update_responses
@@ -197,6 +197,12 @@ sub create_incremental_mar {
my $tmpdir = File::Temp->newdir();
extract_mar(mar_filename($from_version, $os, $lang), "$tmpdir/A");
extract_mar(mar_filename($new_version, $os, $lang), "$tmpdir/B");
+ if ($ENV{CHECK_CODESIGNATURE_EXISTS}) {
+ unless (-f "$tmpdir/A/TorBrowser.app/Contents/_CodeSignature/CodeResources"
+ && -f "$tmpdir/B/TorBrowser.app/Contents/_CodeSignature/CodeResources") {
+ exit_error "Missing code signature while creating $mar_file";
+ }
+ }
my ($out, $err, $success) = capture_exec('make_incremental_update.sh',
$mar_file_path, "$tmpdir/A", "$tmpdir/B");
if (!$success) {
1
0

11 Oct '16
commit 332865872846c38b518adc4189ca0aa5eaab1378
Merge: 4f169a0 e59f0d4
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Tue Oct 11 08:48:39 2016 -0400
Merge remote-tracking branch 'asn/bug19223'
changes/bug19223 | 4 ++++
src/or/routerkeys.c | 4 ++--
2 files changed, 6 insertions(+), 2 deletions(-)
1
0

[tor/master] Fix non-triggerable heap corruption at do_getpass().
by nickm@torproject.org 11 Oct '16
by nickm@torproject.org 11 Oct '16
11 Oct '16
commit e59f0d4cb964387c5c653d3943ae4ecb9cab55b9
Author: George Kadianakis <desnacked(a)riseup.net>
Date: Mon Oct 10 12:03:39 2016 -0400
Fix non-triggerable heap corruption at do_getpass().
---
changes/bug19223 | 4 ++++
src/or/routerkeys.c | 4 ++--
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/changes/bug19223 b/changes/bug19223
new file mode 100644
index 0000000..e8ca6d4
--- /dev/null
+++ b/changes/bug19223
@@ -0,0 +1,4 @@
+ o Minor bugfixes (getpass):
+ - Defensively fix a non-triggerable heap corruption at do_getpass() tow
+ protect ourselves from mistakes in the future. Fixes bug #19223; bugfix
+ on 0.2.7.3-rc. Bug found by Guido Vranken, patch by nherring.
\ No newline at end of file
diff --git a/src/or/routerkeys.c b/src/or/routerkeys.c
index 060ffd8..d5e7051 100644
--- a/src/or/routerkeys.c
+++ b/src/or/routerkeys.c
@@ -48,8 +48,8 @@ do_getpass(const char *prompt, char *buf, size_t buflen,
size_t p2len = strlen(prompt) + 1;
if (p2len < sizeof(msg))
p2len = sizeof(msg);
- prompt2 = tor_malloc(strlen(prompt)+1);
- memset(prompt2, ' ', p2len);
+ prompt2 = tor_malloc(p2len);
+ memset(prompt2, ' ', p2len - sizeof(msg));
memcpy(prompt2 + p2len - sizeof(msg), msg, sizeof(msg));
buf2 = tor_malloc_zero(buflen);
1
0

11 Oct '16
commit 490f935191fe5edabc7cab58f1d68bc6dbae2408
Author: Arlo Breault <arlolra(a)gmail.com>
Date: Sun Oct 9 21:28:13 2016 -0700
Move patches to comm-esr45 fork
---
.../0001-Set-Tor-Messenger-preferences.patch | 198 +
...0002-Trac-16489-Prevent-account-autologin.patch | 121 +
...Support-Special-Characters-input-prompt-o.patch | 78 +
...Better-error-reporting-for-failed-outgoin.patch | 67 +
.../0005-Trac-13312-OTR-over-Twitter-DMs.patch | 1006 ++++
...-Fix-tab-strip-background-colour-on-OS-X..patch | 26 +
...-XMPP-createConversation-should-handle-in.patch | 26 +
...-Set-_userVCard-own-property-when-downloa.patch | 39 +
.../0009-XMPP-in-band-registration.patch | 396 ++
.../instantbird/0010-Remove-search-from-UI.patch | 64 +
.../0011-Add-Tor-Messenger-branding.patch | 5133 ++++++++++++++++++++
projects/instantbird/0012-Account-picture.patch | 26 +
.../0013-Modify-protocol-defaults.patch | 48 +
.../instantbird/0014-Modify-IRC-defaults.patch | 65 +
projects/instantbird/0015-Modify-themes.patch | 78 +
.../instantbird/0016-Modify-XMPP-defaults.patch | 48 +
projects/instantbird/0017-Remove-logging-UI.patch | 43 +
projects/instantbird/0018-Cert-override.patch | 64 +
.../0019-Display-all-traffic-over-Tor.patch | 38 +
.../instantbird/0020-Trac-17480-Content-sink.patch | 101 +
projects/instantbird/about-logo.png | Bin 6681 -> 0 bytes
projects/instantbird/about-logo(a)2x.png | Bin 13886 -> 0 bytes
projects/instantbird/about-wordmark.png | Bin 3754 -> 0 bytes
projects/instantbird/aboutDialog-appUpdater.js | 576 ---
projects/instantbird/aboutDialog-jar.patch | 15 -
projects/instantbird/aboutDialog.css | 91 -
projects/instantbird/aboutDialog.dtd | 129 -
projects/instantbird/aboutDialog.js | 79 -
projects/instantbird/aboutDialog.xul | 173 -
projects/instantbird/account-picture.patch | 13 -
projects/instantbird/branding-aboutDialog.css | 48 -
projects/instantbird/branding/about.png | Bin 9880 -> 0 bytes
projects/instantbird/branding/blistWindow.ico | Bin 9662 -> 0 bytes
projects/instantbird/branding/blistWindow.png | Bin 1003 -> 0 bytes
projects/instantbird/branding/blistWindow16.png | Bin 576 -> 0 bytes
projects/instantbird/branding/blistWindow48.png | Bin 2089 -> 0 bytes
projects/instantbird/branding/convWindow.ico | Bin 10058 -> 0 bytes
projects/instantbird/branding/convWindow.png | Bin 1126 -> 0 bytes
projects/instantbird/branding/convWindow16.png | Bin 637 -> 0 bytes
projects/instantbird/branding/convWindow48.png | Bin 1563 -> 0 bytes
projects/instantbird/branding/default.ico | Bin 7262 -> 0 bytes
projects/instantbird/branding/default.png | Bin 867 -> 0 bytes
projects/instantbird/branding/default16.png | Bin 520 -> 0 bytes
projects/instantbird/branding/default48.png | Bin 1178 -> 0 bytes
projects/instantbird/branding/instantbird.icns | Bin 21624 -> 0 bytes
projects/instantbird/branding/instantbird.ico | Bin 7262 -> 0 bytes
projects/instantbird/branding/jar.patch | 11 -
projects/instantbird/branding/name.patch | 46 -
projects/instantbird/branding/osx.patch | 9 -
projects/instantbird/browserMountPoints.inc | 12 -
projects/instantbird/bug-1218193.patch | 31 -
projects/instantbird/bug-1246431.patch | 31 -
projects/instantbird/bug-1298574.patch | 47 -
projects/instantbird/build | 53 +-
projects/instantbird/cert-installer.patch | 36 -
projects/instantbird/cert_override.txt | 3 -
projects/instantbird/config | 86 +-
projects/instantbird/ctcp-ping.patch | 24 -
projects/instantbird/ctcp-time.patch | 12 -
projects/instantbird/disable-links.patch | 102 -
projects/instantbird/hide-get-protocols.patch | 12 -
projects/instantbird/irc-default-server.patch | 12 -
projects/instantbird/log-preferences-xul.patch | 30 -
projects/instantbird/preferences.patch | 196 -
projects/instantbird/search-context-menu.patch | 28 -
projects/instantbird/search-preferences-xul.patch | 21 -
projects/instantbird/show-traffic-tor.patch | 23 -
projects/instantbird/theme-extension-update.patch | 12 -
projects/instantbird/themes-remove-links.patch | 46 -
projects/instantbird/top-protocols.patch | 18 -
projects/instantbird/trac-13312.patch | 1414 ------
projects/instantbird/trac-16489.patch | 108 -
projects/instantbird/trac-17494.patch | 83 -
projects/instantbird/trac-17896.patch | 67 -
projects/instantbird/trac-20207.patch | 27 -
projects/instantbird/updater-text.patch | 9 -
projects/instantbird/xmpp-default-domain.patch | 12 -
projects/instantbird/xmpp-gtalk-resource.patch | 24 -
.../instantbird/xmpp-inband-registration.patch | 188 -
projects/instantbird/xmpp-onion-js.patch | 89 -
projects/instantbird/xmpp-onion-locale.patch | 10 -
projects/instantbird/xmpp-onion-xul.patch | 23 -
projects/instantbird/xmppRegister.js | 142 -
projects/instantbird/xmppRegister.xul | 27 -
84 files changed, 7701 insertions(+), 4212 deletions(-)
diff --git a/projects/instantbird/0001-Set-Tor-Messenger-preferences.patch b/projects/instantbird/0001-Set-Tor-Messenger-preferences.patch
new file mode 100644
index 0000000..96f3f5b
--- /dev/null
+++ b/projects/instantbird/0001-Set-Tor-Messenger-preferences.patch
@@ -0,0 +1,198 @@
+From 81e0dfcc4197e987a8c64cce36b3cda48e84fe54 Mon Sep 17 00:00:00 2001
+From: Sukhbir Singh <sukhbir(a)torproject.org>
+Date: Mon, 10 Oct 2016 19:48:41 -0700
+Subject: [PATCH 01/20] Set Tor Messenger preferences
+
+---
+ im/app/profile/all-instantbird.js | 107 +++++++++++++++++++++++++++++++-------
+ 1 file changed, 87 insertions(+), 20 deletions(-)
+
+diff --git a/im/app/profile/all-instantbird.js b/im/app/profile/all-instantbird.js
+index b7a3970..86f0559 100644
+--- a/im/app/profile/all-instantbird.js
++++ b/im/app/profile/all-instantbird.js
+@@ -28,7 +28,7 @@ pref("general.autoScroll", true);
+ // 0 = spellcheck nothing
+ // 1 = check multi-line controls [default]
+ // 2 = check multi/single line controls
+-pref("layout.spellcheckDefault", 1);
++pref("layout.spellcheckDefault", 0);
+
+ pref("messenger.accounts.convertOldPasswords", true);
+ pref("messenger.accounts.promptOnDelete", true);
+@@ -66,7 +66,7 @@ pref("extensions.mintrayr.singleClickRestore", false);
+
+ // Whether message related sounds should be played at all. If this is enabled
+ // then the more specific prefs are checked as well.
+-pref("messenger.options.playSounds.message", true);
++pref("messenger.options.playSounds.message", false);
+ // Specifies whether each message event should trigger a sound for incoming
+ // and outgoing messages, or when your nickname is mentioned in a chat.
+ pref("messenger.options.playSounds.outgoing", true);
+@@ -142,26 +142,28 @@ pref("app.update.staging.enabled", true);
+
+ // Update service URL:
+ // You do not need to use all the %VAR% parameters. Use what you need, %PRODUCT%,%VERSION%,%BUILD_ID%,%CHANNEL% for example
+-pref("app.update.url", "https://update.instantbird.org/1/%PRODUCT%/%VERSION%/%BUILD_ID%/%BUILD_TARG…");
++pref("app.update.url", "https://aus2.torproject.org/tormessenger/update_2/%CHANNEL%/%BUILD_TARGET%/…");
++
++#ifdef XP_WIN
++// For now, disable staged updates on Windows (see #18292).
++pref("app.update.staging.enabled", false);
++#endif
+
+ // URL user can browse to manually if for some reason all update installation
+ // attempts fail.
+-pref("app.update.url.manual", "http://www.instantbird.com/download.html");
++pref("app.update.url.manual", "https://www.torproject.org");
+
+ // A default value for the "More information about this update" link
+ // supplied in the "An update is available" page of the update wizard.
+-pref("app.update.url.details", "http://www.instantbird.com/");
+-
+-// User-settable override to app.update.url for testing purposes.
+-//pref("app.update.url.override", "");
++pref("app.update.url.details", "https://trac.torproject.org/projects/tor/wiki/doc/TorMessenger");
+
+ // Interval: Time between checks for a new version (in seconds)
+ // default=1 day
+-pref("app.update.interval", 86400);
++pref("app.update.interval", 43200);
+
+ // Interval: Time before prompting the user to download a new version that
+ // is available (in seconds) default=1 day
+-pref("app.update.nagTimer.download", 86400);
++pref("app.update.nagTimer.download", 3600);
+
+ // Interval: Time before prompting the user to restart to install the latest
+ // download (in seconds) default=30 minutes
+@@ -202,7 +204,7 @@ pref("browser.search.order.1", "chrome://instantbird/locale/regio
+ pref("browser.search.order.2", "chrome://instantbird/locale/region.properties");
+
+ // send ping to the server to update
+-pref("browser.search.update", true);
++pref("browser.search.update", false);
+
+ // disable logging for the search service update system by default
+ pref("browser.search.update.log", false);
+@@ -222,7 +224,7 @@ pref("extensions.ignoreMTimeChanges", false);
+ pref("extensions.logging.enabled", false);
+ pref("general.skins.selectedSkin", "classic/1.0");
+
+-pref("extensions.update.enabled", true);
++pref("extensions.update.enabled", false);
+ pref("extensions.update.interval", 86400);
+ pref("extensions.update.url", "https://addons.instantbird.org/services/update.php?reqVersion=%REQ_VERSION%…");
+ pref("extensions.update.autoUpdateDefault", true);
+@@ -245,9 +247,9 @@ pref("extensions.getMoreEmoticonsURL", "https://add-ons.instantbird.org/%LOCALE%
+ pref("extensions.getMoreProtocolsURL", "https://add-ons.instantbird.org/%LOCALE%/%APP%/%VERSION%/protocols/");
+
+ // suppress external-load warning for standard browser schemes
+-pref("network.protocol-handler.warn-external.http", false);
+-pref("network.protocol-handler.warn-external.https", false);
+-pref("network.protocol-handler.warn-external.ftp", false);
++pref("network.protocol-handler.warn-external.http", true);
++pref("network.protocol-handler.warn-external.https", true);
++pref("network.protocol-handler.warn-external.ftp", true);
+
+ // don't load links inside Instantbird
+ pref("network.protocol-handler.expose-all", false);
+@@ -262,10 +264,10 @@ pref("network.protocol-handler.expose.https", true);
+ pref("network.protocol-handler.expose.javascript", true);
+
+ // 0-Accept, 1-dontAcceptForeign, 2-dontUse
+-pref("network.cookie.cookieBehavior", 0);
++pref("network.cookie.cookieBehavior", 1);
+
+ // The breakpad report server to link to in about:crashes
+-pref("breakpad.reportURL", "http://crash-stats.instantbird.com/report/index/");
++pref("breakpad.reportURL", "https://crash-stats.instantbird.com/report/index/");
+
+ // We have an Error Console menu item by default so let's display chrome errors
+ pref("javascript.options.showInConsole", true);
+@@ -300,14 +302,79 @@ pref("browser.tabs.tabClipWidth", 140);
+ // 3 at the end of the tabstrip
+ pref("browser.tabs.closeButtons", 1);
+
+-#expand pref("chat.irc.defaultQuitMessage", "Instantbird __APP_VERSION__ -- http://www.instantbird.com");
++#expand pref("chat.irc.defaultQuitMessage", "");
+
+ pref("chat.twitter.consumerKey", "TSuyS1ieRAkB3qWv8yyEw");
+ pref("chat.twitter.consumerSecret", "DKtKaSf5a7pBNhdBsSZHTnI5Y03hRlPFYWmb4xXBlkU");
+
+ // Comma separated list of prpl ids that should use libpurple even if there is
+ // a JS implementation. This is used to land JS-prpls pref'ed off in nightlies.
+-pref("chat.prpls.forcePurple", "prpl-jabber");
++pref("chat.prpls.forcePurple", "");
+
+ // Whether to parse log files for conversation statistics.
+-pref("statsService.parseLogsForStats", true);
++pref("statsService.parseLogsForStats", false);
++
++/* Tor Messenger */
++// Logging
++// Disable all logging
++pref("purple.logging.log_chats", false);
++pref("purple.logging.log_ims", false);
++pref("purple.logging.log_system", false);
++
++// Network
++// Use a manual proxy configuration
++pref("network.proxy.type", 1);
++// Empty the "no proxy" setting
++pref("network.proxy.no_proxies_on", "");
++// Configure Instantbird to use the SOCKS5 proxy
++pref("network.proxy.socks", "127.0.0.1");
++pref("network.proxy.socks_port", 9152);
++pref("network.proxy.socks_version", 5);
++// Set DNS proxying through SOCKS5
++pref("network.proxy.socks_remote_dns", true);
++// Disable DNS prefetching
++pref("network.dns.disablePrefetch", true);
++// Disable SPDY
++pref("network.http.spdy.enabled", false);
++// Set the user-agent to Instantbird stable
++pref("general.useragent.override", "Mozilla/5.0 (Windows NT 6.1; rv:25.0) Gecko/20100101 Instantbird/1.5");
++
++// Security
++// Disable SSLv3 by setting the minimum supported protocol to TLS 1.0.
++pref("security.tls.version.min", 1);
++// We use the certdb. Necessary for the TB patch,
++// "Bug 14716: HTTP Basic Authentication prompt only displayed once"
++pref("security.nocertdb", false);
++// Disable geolocation
++pref("geo.enabled", false);
++
++// Do not report idle status or the away message
++pref("messenger.status.awayWhenIdle", false);
++pref("messenger.status.defaultIdleAwayMessage", "");
++pref("messenger.status.reportIdle", false);
++// Do not send the message format (fonts, colors)
++pref("messenger.conversations.sendFormat", false);
++// Disable text formatting (remove the tags)
++pref("messenger.options.filterMode", 0);
++// Disable typing notifications
++pref("purple.conversations.im.send_typing", false);
++
++// Browser
++// Disable caching
++pref("browser.cache.disk.enable", false);
++pref("browser.cache.offline.enable", false);
++
++// Media
++// Disable WebRTC
++pref("media.peerconnection.enabled", false);
++// Disable "Take Picture" functionality that accesses the webcam
++pref("media.navigator.video.enabled", false);
++// Disable hardware acceleration
++pref("gfx.direct2d.disabled", true);
++pref("layers.acceleration.disabled", true);
++
++// Other Updates
++pref("app.update.promptWaitTime", 3600);
++
++// Put conversations on hold so that OTR disconnect is not sent. See #20208.
++pref("messenger.conversations.holdByDefault", true);
+--
+2.10.1
+
diff --git a/projects/instantbird/0002-Trac-16489-Prevent-account-autologin.patch b/projects/instantbird/0002-Trac-16489-Prevent-account-autologin.patch
new file mode 100644
index 0000000..b3e386e
--- /dev/null
+++ b/projects/instantbird/0002-Trac-16489-Prevent-account-autologin.patch
@@ -0,0 +1,121 @@
+From 9cb6308cee43524e5b9368d6fc2f0b862dde0a3e Mon Sep 17 00:00:00 2001
+From: Arlo Breault <arlolra(a)gmail.com>
+Date: Mon, 16 Nov 2015 20:37:53 -0800
+Subject: [PATCH 02/20] Trac 16489: Prevent account autologin
+
+---
+ chat/components/src/imAccounts.js | 2 +-
+ im/content/account.xml | 4 ----
+ im/content/accountWizard.js | 11 +----------
+ im/content/accountWizard.xul | 2 --
+ im/content/preferences/main.xul | 18 ------------------
+ 5 files changed, 2 insertions(+), 35 deletions(-)
+
+diff --git a/chat/components/src/imAccounts.js b/chat/components/src/imAccounts.js
+index c13c610..5bfea57 100644
+--- a/chat/components/src/imAccounts.js
++++ b/chat/components/src/imAccounts.js
+@@ -588,7 +588,7 @@ imAccount.prototype = {
+ },
+
+ get autoLogin() {
+- let autoLogin = true;
++ let autoLogin = false;
+ try {
+ autoLogin = this.prefBranch.getBoolPref(kPrefAccountAutoLogin);
+ } catch (e) { }
+diff --git a/im/content/account.xml b/im/content/account.xml
+index e063318..78195b7 100644
+--- a/im/content/account.xml
++++ b/im/content/account.xml
+@@ -41,10 +41,6 @@
+ accesskey="&certmgr.addException.accesskey;"/>
+ <xul:spacer flex="1"/>
+ </xul:vbox>
+- <xul:checkbox label="&account.autoSignOn.label;" dir="reverse"
+- xbl:inherits="checked=autologin" class="autoSignOn"
+- accesskey="&account.autoSignOn.accesskey;"
+- oncommand="gAccountManager.autologin()"/>
+ </xul:hbox>
+ <xul:hbox flex="1" class="account-buttons" anonid="buttons"
+ xbl:inherits="autologin"/>
+diff --git a/im/content/accountWizard.js b/im/content/accountWizard.js
+index 73707c9..ed3b8f0 100644
+--- a/im/content/accountWizard.js
++++ b/im/content/accountWizard.js
+@@ -442,22 +442,13 @@ var accountWizard = {
+ throw "unknown type";
+ }
+ }
+- let autologin = this.getValue("connectAutomatically");
+- acc.autoLogin = autologin;
++ acc.autoLogin = false;
+
+ if (this.proto.usePurpleProxy)
+ acc.proxyInfo = this.proxy;
+
+ acc.save();
+
+- try {
+- if (autologin)
+- acc.connect();
+- } catch (e) {
+- // If the connection fails (for example if we are currently in
+- // offline mode), we still want to close the account wizard
+- }
+-
+ if (window.opener) {
+ let am = window.opener.gAccountManager;
+ if (am)
+diff --git a/im/content/accountWizard.xul b/im/content/accountWizard.xul
+index 5fa5b82..9eb5352 100644
+--- a/im/content/accountWizard.xul
++++ b/im/content/accountWizard.xul
+@@ -137,8 +137,6 @@
+ </columns>
+ <rows id="summaryRows"/>
+ </grid>
+- <separator/>
+- <checkbox id="connectAutomatically" label= "&accountSummary.connectAutomatically.label;" checked="true"/>
+ </wizardpage>
+
+ </wizard>
+diff --git a/im/content/preferences/main.xul b/im/content/preferences/main.xul
+index e5f7fb6..5e0024d 100644
+--- a/im/content/preferences/main.xul
++++ b/im/content/preferences/main.xul
+@@ -20,7 +20,6 @@
+ <script type="application/javascript" src="chrome://instantbird/content/preferences/main.js"/>
+
+ <preferences id="mainPreferences">
+- <preference id="messenger.startup.action" name="messenger.startup.action" type="int"/>
+ <preference id="messenger.options.playSounds.blist" name="messenger.options.playSounds.blist" type="bool"/>
+ <preference id="messenger.options.playSounds.message" name="messenger.options.playSounds.message" type="bool"/>
+ <preference id="messenger.options.getAttentionOnNewMessages" name="messenger.options.getAttentionOnNewMessages" type="bool"/>
+@@ -33,23 +32,6 @@
+ <preference id="messenger.options.notifyOfNewMessages" name="messenger.options.notifyOfNewMessages" type="bool"/>
+ </preferences>
+
+- <!-- Startup -->
+- <groupbox id="startupGroup">
+- <caption label="&startup.label;"/>
+-
+- <hbox align="center">
+- <label value="&startupAction.label;" accesskey="&startupAction.accesskey;"
+- control="messengerStartupAction"/>
+- <menulist id="messengerStartupAction" preference="messenger.startup.action">
+- <menupopup>
+- <menuitem label="&startupOffline.label;" value="0"/>
+- <menuitem label="&startupConnectAuto.label;" value="1"/>
+- </menupopup>
+- </menulist>
+- </hbox>
+- </groupbox>
+-
+-
+ <groupbox id="accountsMgrGroup" orient="horizontal" align="center">
+ <caption label="&accountsMgr.label;"/>
+
+--
+2.10.1
+
diff --git a/projects/instantbird/0003-Trac-17896-Support-Special-Characters-input-prompt-o.patch b/projects/instantbird/0003-Trac-17896-Support-Special-Characters-input-prompt-o.patch
new file mode 100644
index 0000000..df362aa
--- /dev/null
+++ b/projects/instantbird/0003-Trac-17896-Support-Special-Characters-input-prompt-o.patch
@@ -0,0 +1,78 @@
+From ae27272d58c8f3654ba23b1329f07f0dc8fe5a10 Mon Sep 17 00:00:00 2001
+From: aleth <aleth(a)instantbird.org>
+Date: Sat, 30 Jan 2016 20:56:38 +0100
+Subject: [PATCH 03/20] Trac 17896: Support "Special Characters" input prompt
+ on OS X
+
+ * Bug 1151784 - Add Edit menu to the conversation window on OS X. r=nhnt11,florian
+
+ Adding an edit menu also enables the emoji panel and dictation.
+---
+ im/content/instantbird.xul | 23 ++++++++++++++++++++++-
+ im/content/menus.xul | 2 +-
+ im/content/menus.xul.inc | 2 ++
+ 3 files changed, 25 insertions(+), 2 deletions(-)
+
+diff --git a/im/content/instantbird.xul b/im/content/instantbird.xul
+index 15a3f98..d208921 100644
+--- a/im/content/instantbird.xul
++++ b/im/content/instantbird.xul
+@@ -48,7 +48,28 @@
+ <script type="application/javascript" src="chrome://instantbird/content/nsContextMenu.js"/>
+
+ #ifdef XP_MACOSX
+-#include menus.xul.inc
++# As menus.xul.inc, but with an Edit menu.
++ <commandset id="maincommandset"/>
++ <keyset id="mainkeyset"/>
++ <menubar id="blistMenubar">
++ <menu id="menu_edit">
++ <menupopup id="menu_editpopup">
++ <menuitem id="menu_undo"/>
++ <menuitem id="menu_redo"/>
++ <menuseparator/>
++ <menuitem id="menu_cut"/>
++ <menuitem id="menu_copy"/>
++ <menuitem id="menu_paste"/>
++ <menuitem id="menu_delete"/>
++ <menuseparator/>
++ <menuitem id="menu_selectAll"/>
++ <menuseparator/>
++ <menuitem id="menu_find"/>
++ <menuitem id="menu_findAgain"/>
++ </menupopup>
++ </menu>
++ </menubar>
++ <popupset id="mainPopupSet"/>
+ #endif
+
+ <commandset id="conversationsCommands">
+diff --git a/im/content/menus.xul b/im/content/menus.xul
+index 0889ce8..894ef13 100644
+--- a/im/content/menus.xul
++++ b/im/content/menus.xul
+@@ -43,7 +43,7 @@
+ </keyset>
+
+ <menubar id="blistMenubar">
+- <menu label="&file.menu;" id="fileMenu" accesskey="&file.accesskey;">
++ <menu label="&file.menu;" id="fileMenu" accesskey="&file.accesskey;" insertbefore="menu_edit">
+ <menupopup id="fileMenuPopup" onpopupshowing="menus.updateFileMenuitems();">
+ <menuitem id="addBuddyMenuItem" label="&addContact;" command="cmd_addbuddy" key="addBuddykey" accesskey="&addContact.accesskey;"/>
+ <menuitem id="newTabMenuItem" label="&newtab;" command="cmd_newtab" key="newtabkey" accesskey="&newtab.accesskey;"/>
+diff --git a/im/content/menus.xul.inc b/im/content/menus.xul.inc
+index 30aeb1f..14fc9e8 100644
+--- a/im/content/menus.xul.inc
++++ b/im/content/menus.xul.inc
+@@ -2,6 +2,8 @@
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
++# Note instantbird.xul contains a modified copy of this file that
++# should be kept in sync.
+ <commandset id="maincommandset"/>
+ <keyset id="mainkeyset"/>
+ <menubar id="blistMenubar"/>
+--
+2.10.1
+
diff --git a/projects/instantbird/0004-Trac-17494-Better-error-reporting-for-failed-outgoin.patch b/projects/instantbird/0004-Trac-17494-Better-error-reporting-for-failed-outgoin.patch
new file mode 100644
index 0000000..4c3501d
--- /dev/null
+++ b/projects/instantbird/0004-Trac-17494-Better-error-reporting-for-failed-outgoin.patch
@@ -0,0 +1,67 @@
+From 13ffc7769be983fbd7668ad40f716683351b249f Mon Sep 17 00:00:00 2001
+From: Arlo Breault <arlolra(a)gmail.com>
+Date: Tue, 2 Feb 2016 16:04:51 -0800
+Subject: [PATCH 04/20] Trac 17494: Better error reporting for failed outgoing
+ messages
+
+ * Bug 1245325 - Better error reporting for failed outgoing messages. r=clokep
+---
+ chat/locales/en-US/xmpp.properties | 6 ++++--
+ chat/protocols/xmpp/xmpp.jsm | 17 ++++++++++++-----
+ 2 files changed, 16 insertions(+), 7 deletions(-)
+
+diff --git a/chat/locales/en-US/xmpp.properties b/chat/locales/en-US/xmpp.properties
+index 7f824e5..293ab01 100644
+--- a/chat/locales/en-US/xmpp.properties
++++ b/chat/locales/en-US/xmpp.properties
+@@ -66,7 +66,10 @@ conversation.error.sendFailedAsNotInRoom=Message could not be sent to %1$S as yo
+ # %2$S is the text of the message that wasn't delivered.
+ conversation.error.sendFailedAsRecipientNotInRoom=Message could not be sent to %1$S as the recipient is no longer in the room: %2$S
+ # These are displayed in a conversation as a system error message.
+-conversation.error.remoteServerNotFound=Could not reach the recipient's server
++conversation.error.remoteServerNotFound=Could not reach the recipient's server.
++conversation.error.unknownSendError=An unknown error occurred on sending this message.
++# %S is the name of the message recipient.
++conversation.error.sendServiceUnavailable=It is not possible to send messages to %S at this time.
+ # %S is the nick of participant that is not in room.
+ conversation.error.nickNotInRoom=%S is not in the room.
+ conversation.error.banCommandAnonymousRoom=You can't ban participants from anonymous rooms. Try /kick instead.
+@@ -80,7 +83,6 @@ conversation.error.failedJIDNotFound=Could not reach %S.
+ # %S is the jid that is invalid.
+ conversation.error.invalidJID=%S is an invalid jid (Jabber identifiers must be of the form user@domain).
+ conversation.error.commandFailedNotInRoom=You have to rejoin the room to be able to use this command.
+-conversation.error.unknownError=Unknown error
+
+ # LOCALIZATION NOTE (tooltip.*):
+ # These are the titles of lines of information that will appear in
+diff --git a/chat/protocols/xmpp/xmpp.jsm b/chat/protocols/xmpp/xmpp.jsm
+index 67cab77..0022be3 100644
+--- a/chat/protocols/xmpp/xmpp.jsm
++++ b/chat/protocols/xmpp/xmpp.jsm
+@@ -679,11 +679,18 @@ var XMPPConversationPrototype = {
+ let muc = this._account._mucs.get(norm);
+
+ if (!aMsg) {
+- // Failed outgoing message unknown.
+- if (error.condition == "remote-server-not-found")
+- aMsg = _("conversation.error.remoteServerNotFound");
+- else
+- aMsg = _("conversation.error.unknownError");
++ // Failed outgoing message.
++ switch (error.condition) {
++ case "remote-server-not-found":
++ aMsg = _("conversation.error.remoteServerNotFound");
++ break;
++ case "service-unavailable":
++ aMsg = _("conversation.error.sendServiceUnavailable", this.shortName);
++ break;
++ default:
++ aMsg = _("conversation.error.unknownSendError");
++ break;
++ }
+ }
+ else if (this._isMucParticipant && muc && !muc.left &&
+ error.condition == "item-not-found") {
+--
+2.10.1
+
diff --git a/projects/instantbird/0005-Trac-13312-OTR-over-Twitter-DMs.patch b/projects/instantbird/0005-Trac-13312-OTR-over-Twitter-DMs.patch
new file mode 100644
index 0000000..0743dde
--- /dev/null
+++ b/projects/instantbird/0005-Trac-13312-OTR-over-Twitter-DMs.patch
@@ -0,0 +1,1006 @@
+From ea824468b2e4084a40863c934cc0ce72ac2d7076 Mon Sep 17 00:00:00 2001
+From: Arlo Breault <arlolra(a)gmail.com>
+Date: Tue, 15 Mar 2016 17:40:42 -0700
+Subject: [PATCH 05/20] Trac 13312: OTR over Twitter DMs
+
+---
+ chat/components/src/imConversations.js | 4 +-
+ chat/modules/jsProtoHelper.jsm | 1 +
+ chat/protocols/twitter/twitter-text.jsm | 267 +++++++++++----------
+ chat/protocols/twitter/twitter.js | 406 ++++++++++++++++----------------
+ 4 files changed, 355 insertions(+), 323 deletions(-)
+
+diff --git a/chat/components/src/imConversations.js b/chat/components/src/imConversations.js
+index 6fc5d0d..5187212 100644
+--- a/chat/components/src/imConversations.js
++++ b/chat/components/src/imConversations.js
+@@ -30,6 +30,7 @@ function imMessage(aPrplMessage) {
+ }
+ imMessage.prototype = {
+ __proto__: ClassInfo(["imIMessage", "prplIMessage"], "IM Message"),
++ get wrappedJSObject() { return this; },
+ cancelled: false,
+ color: "",
+ _displayMessage: null,
+@@ -414,7 +415,8 @@ UIConversation.prototype = {
+ this.notifyObservers(aSubject, "received-message");
+ if (aSubject.cancelled)
+ return;
+- aSubject.conversation.prepareForDisplaying(aSubject);
++ if (!aSubject.system)
++ aSubject.conversation.prepareForDisplaying(aSubject);
+
+ this._messages.push(aSubject);
+ ++this._unreadMessageCount;
+diff --git a/chat/modules/jsProtoHelper.jsm b/chat/modules/jsProtoHelper.jsm
+index 42bd9f6..69af716 100644
+--- a/chat/modules/jsProtoHelper.jsm
++++ b/chat/modules/jsProtoHelper.jsm
+@@ -381,6 +381,7 @@ AccountBuddy.prototype = GenericAccountBuddyPrototype;
+
+ var GenericMessagePrototype = {
+ __proto__: ClassInfo("prplIMessage", "generic message object"),
++ get wrappedJSObject() { return this; },
+
+ _lastId: 0,
+ _init: function (aWho, aMessage, aObject) {
+diff --git a/chat/protocols/twitter/twitter-text.jsm b/chat/protocols/twitter/twitter-text.jsm
+index 1940fd2..a8f8370 100644
+--- a/chat/protocols/twitter/twitter-text.jsm
++++ b/chat/protocols/twitter/twitter-text.jsm
+@@ -19,7 +19,7 @@ var window = {};
+
+ // The code below is imported from Twitter's JavaScript utility for parsing
+ // tweets. The original version of this file can be found at
+-// https://github.com/twitter/twitter-text-js/blob/master/twitter-text.js
++// https://github.com/twitter/twitter-text/blob/master/js/twitter-text.js
+
+ (function() {
+ if (typeof twttr === "undefined" || twttr === null) {
+@@ -125,80 +125,6 @@ var window = {};
+ twttr.txt.regexen.rtl_chars = /[\u0600-\u06FF]|[\u0750-\u077F]|[\u0590-\u05FF]|[\uFE70-\uFEFF]/mg;
+ twttr.txt.regexen.non_bmp_code_pairs = /[\uD800-\uDBFF][\uDC00-\uDFFF]/mg;
+
+- var nonLatinHashtagChars = [];
+- // Cyrillic
+- addCharsToCharClass(nonLatinHashtagChars, 0x0400, 0x04ff); // Cyrillic
+- addCharsToCharClass(nonLatinHashtagChars, 0x0500, 0x0527); // Cyrillic Supplement
+- addCharsToCharClass(nonLatinHashtagChars, 0x2de0, 0x2dff); // Cyrillic Extended A
+- addCharsToCharClass(nonLatinHashtagChars, 0xa640, 0xa69f); // Cyrillic Extended B
+- // Hebrew
+- addCharsToCharClass(nonLatinHashtagChars, 0x0591, 0x05bf); // Hebrew
+- addCharsToCharClass(nonLatinHashtagChars, 0x05c1, 0x05c2);
+- addCharsToCharClass(nonLatinHashtagChars, 0x05c4, 0x05c5);
+- addCharsToCharClass(nonLatinHashtagChars, 0x05c7, 0x05c7);
+- addCharsToCharClass(nonLatinHashtagChars, 0x05d0, 0x05ea);
+- addCharsToCharClass(nonLatinHashtagChars, 0x05f0, 0x05f4);
+- addCharsToCharClass(nonLatinHashtagChars, 0xfb12, 0xfb28); // Hebrew Presentation Forms
+- addCharsToCharClass(nonLatinHashtagChars, 0xfb2a, 0xfb36);
+- addCharsToCharClass(nonLatinHashtagChars, 0xfb38, 0xfb3c);
+- addCharsToCharClass(nonLatinHashtagChars, 0xfb3e, 0xfb3e);
+- addCharsToCharClass(nonLatinHashtagChars, 0xfb40, 0xfb41);
+- addCharsToCharClass(nonLatinHashtagChars, 0xfb43, 0xfb44);
+- addCharsToCharClass(nonLatinHashtagChars, 0xfb46, 0xfb4f);
+- // Arabic
+- addCharsToCharClass(nonLatinHashtagChars, 0x0610, 0x061a); // Arabic
+- addCharsToCharClass(nonLatinHashtagChars, 0x0620, 0x065f);
+- addCharsToCharClass(nonLatinHashtagChars, 0x066e, 0x06d3);
+- addCharsToCharClass(nonLatinHashtagChars, 0x06d5, 0x06dc);
+- addCharsToCharClass(nonLatinHashtagChars, 0x06de, 0x06e8);
+- addCharsToCharClass(nonLatinHashtagChars, 0x06ea, 0x06ef);
+- addCharsToCharClass(nonLatinHashtagChars, 0x06fa, 0x06fc);
+- addCharsToCharClass(nonLatinHashtagChars, 0x06ff, 0x06ff);
+- addCharsToCharClass(nonLatinHashtagChars, 0x0750, 0x077f); // Arabic Supplement
+- addCharsToCharClass(nonLatinHashtagChars, 0x08a0, 0x08a0); // Arabic Extended A
+- addCharsToCharClass(nonLatinHashtagChars, 0x08a2, 0x08ac);
+- addCharsToCharClass(nonLatinHashtagChars, 0x08e4, 0x08fe);
+- addCharsToCharClass(nonLatinHashtagChars, 0xfb50, 0xfbb1); // Arabic Pres. Forms A
+- addCharsToCharClass(nonLatinHashtagChars, 0xfbd3, 0xfd3d);
+- addCharsToCharClass(nonLatinHashtagChars, 0xfd50, 0xfd8f);
+- addCharsToCharClass(nonLatinHashtagChars, 0xfd92, 0xfdc7);
+- addCharsToCharClass(nonLatinHashtagChars, 0xfdf0, 0xfdfb);
+- addCharsToCharClass(nonLatinHashtagChars, 0xfe70, 0xfe74); // Arabic Pres. Forms B
+- addCharsToCharClass(nonLatinHashtagChars, 0xfe76, 0xfefc);
+- addCharsToCharClass(nonLatinHashtagChars, 0x200c, 0x200c); // Zero-Width Non-Joiner
+- // Thai
+- addCharsToCharClass(nonLatinHashtagChars, 0x0e01, 0x0e3a);
+- addCharsToCharClass(nonLatinHashtagChars, 0x0e40, 0x0e4e);
+- // Hangul (Korean)
+- addCharsToCharClass(nonLatinHashtagChars, 0x1100, 0x11ff); // Hangul Jamo
+- addCharsToCharClass(nonLatinHashtagChars, 0x3130, 0x3185); // Hangul Compatibility Jamo
+- addCharsToCharClass(nonLatinHashtagChars, 0xA960, 0xA97F); // Hangul Jamo Extended-A
+- addCharsToCharClass(nonLatinHashtagChars, 0xAC00, 0xD7AF); // Hangul Syllables
+- addCharsToCharClass(nonLatinHashtagChars, 0xD7B0, 0xD7FF); // Hangul Jamo Extended-B
+- addCharsToCharClass(nonLatinHashtagChars, 0xFFA1, 0xFFDC); // half-width Hangul
+- // Japanese and Chinese
+- addCharsToCharClass(nonLatinHashtagChars, 0x30A1, 0x30FA); // Katakana (full-width)
+- addCharsToCharClass(nonLatinHashtagChars, 0x30FC, 0x30FE); // Katakana Chouon and iteration marks (full-width)
+- addCharsToCharClass(nonLatinHashtagChars, 0xFF66, 0xFF9F); // Katakana (half-width)
+- addCharsToCharClass(nonLatinHashtagChars, 0xFF70, 0xFF70); // Katakana Chouon (half-width)
+- addCharsToCharClass(nonLatinHashtagChars, 0xFF10, 0xFF19); // \
+- addCharsToCharClass(nonLatinHashtagChars, 0xFF21, 0xFF3A); // - Latin (full-width)
+- addCharsToCharClass(nonLatinHashtagChars, 0xFF41, 0xFF5A); // /
+- addCharsToCharClass(nonLatinHashtagChars, 0x3041, 0x3096); // Hiragana
+- addCharsToCharClass(nonLatinHashtagChars, 0x3099, 0x309E); // Hiragana voicing and iteration mark
+- addCharsToCharClass(nonLatinHashtagChars, 0x3400, 0x4DBF); // Kanji (CJK Extension A)
+- addCharsToCharClass(nonLatinHashtagChars, 0x4E00, 0x9FFF); // Kanji (Unified)
+- // -- Disabled as it breaks the Regex.
+- //addCharsToCharClass(nonLatinHashtagChars, 0x20000, 0x2A6DF); // Kanji (CJK Extension B)
+- addCharsToCharClass(nonLatinHashtagChars, 0x2A700, 0x2B73F); // Kanji (CJK Extension C)
+- addCharsToCharClass(nonLatinHashtagChars, 0x2B740, 0x2B81F); // Kanji (CJK Extension D)
+- addCharsToCharClass(nonLatinHashtagChars, 0x2F800, 0x2FA1F); // Kanji (CJK supplement)
+- addCharsToCharClass(nonLatinHashtagChars, 0x3003, 0x3003); // Kanji iteration mark
+- addCharsToCharClass(nonLatinHashtagChars, 0x3005, 0x3005); // Kanji iteration mark
+- addCharsToCharClass(nonLatinHashtagChars, 0x303B, 0x303B); // Han iteration mark
+-
+- twttr.txt.regexen.nonLatinHashtagChars = regexSupplant(nonLatinHashtagChars.join(""));
+-
+ var latinAccentChars = [];
+ // Latin accented characters (subtracted 0xD7 from the range, it's a confusable multiplication sign. Looks like "x")
+ addCharsToCharClass(latinAccentChars, 0x00c0, 0x00d6);
+@@ -225,16 +151,20 @@ var window = {};
+ addCharsToCharClass(latinAccentChars, 0x1e00, 0x1eff);
+ twttr.txt.regexen.latinAccentChars = regexSupplant(latinAccentChars.join(""));
+
+- // A hashtag must contain characters, numbers and underscores, but not all numbers.
++ var unicodeLettersAndMarks = "A-Za-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B2\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0
B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8
-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u
2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\u
FB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC\u0300-\u036F\u0483-\u0489\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08E4-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B62\u0B63\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0C00-\u0C03\u0C3E-\u0C44
\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0D01-\u0D03\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D82\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F\u109A-\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u180B-\u180D\u18A9\u1920-\u192B\u1930-\u193B\u19B0-\u19C0\u19C8\u19C9\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F\u1AB0-\u1ABE\u1B00-\u1B04\u1B34-\u1B44\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BE6-\u1BF3\u1C24-\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF2-\u1CF4\u1CF8\u1CF9\u1DC0-\u1DF5\u1DFC-\u1DFF\u20D0-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099
\u309A\uA66F-\uA672\uA674-\uA67D\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA880\uA881\uA8B4-\uA8C4\uA8E0-\uA8F1\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9E5\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2D";
++ var unicodeNumbers = "0-9\u0660-\u0669\u06F0-\u06F9\u07C0-\u07C9\u0966-\u096F\u09E6-\u09EF\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0BE6-\u0BEF\u0C66-\u0C6F\u0CE6-\u0CEF\u0D66-\u0D6F\u0DE6-\u0DEF\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F29\u1040-\u1049\u1090-\u1099\u17E0-\u17E9\u1810-\u1819\u1946-\u194F\u19D0-\u19D9\u1A80-\u1A89\u1A90-\u1A99\u1B50-\u1B59\u1BB0-\u1BB9\u1C40-\u1C49\u1C50-\u1C59\uA620-\uA629\uA8D0-\uA8D9\uA900-\uA909\uA9D0-\uA9D9\uA9F0-\uA9F9\uAA50-\uAA59\uABF0-\uABF9\uFF10-\uFF19";
++ var hashtagSpecialChars = "_\u200c\u200d\ua67e\u05be\u05f3\u05f4\uff5e\u301c\u309b\u309c\u30a0\u30fb\u3003\u0f0b\u0f0c\u00b7";
++
++ // A hashtag must contain at least one unicode letter or mark, as well as numbers, underscores, and select special characters.
+ twttr.txt.regexen.hashSigns = /[##]/;
+- twttr.txt.regexen.hashtagAlpha = regexSupplant(/[a-z_#{latinAccentChars}#{nonLatinHashtagChars}]/i);
+- twttr.txt.regexen.hashtagAlphaNumeric = regexSupplant(/[a-z0-9_#{latinAccentChars}#{nonLatinHashtagChars}]/i);
++ twttr.txt.regexen.hashtagAlpha = new RegExp("[" + unicodeLettersAndMarks + "]");
++ twttr.txt.regexen.hashtagAlphaNumeric = new RegExp("[" + unicodeLettersAndMarks + unicodeNumbers + hashtagSpecialChars + "]");
+ twttr.txt.regexen.endHashtagMatch = regexSupplant(/^(?:#{hashSigns}|:\/\/)/);
+- twttr.txt.regexen.hashtagBoundary = regexSupplant(/(?:^|$|[^&a-z0-9_#{latinAccentChars}#{nonLatinHashtagChars}])/);
+- twttr.txt.regexen.validHashtag = regexSupplant(/(#{hashtagBoundary})(#{hashSigns})(#{hashtagAlphaNumeric}*#{hashtagAlpha}#{hashtagAlphaNumeric}*)/gi);
++ twttr.txt.regexen.hashtagBoundary = new RegExp("(?:^|$|[^&" + unicodeLettersAndMarks + unicodeNumbers + hashtagSpecialChars + "])");
++ twttr.txt.regexen.validHashtag = regexSupplant(/(#{hashtagBoundary})(#{hashSigns})(?!\ufe0f|\u20e3)(#{hashtagAlphaNumeric}*#{hashtagAlpha}#{hashtagAlphaNumeric}*)/gi);
+
+ // Mention related regex collection
+- twttr.txt.regexen.validMentionPrecedingChars = /(?:^|[^a-zA-Z0-9_!#$%&*@@]|RT:?)/;
++ twttr.txt.regexen.validMentionPrecedingChars = /(?:^|[^a-zA-Z0-9_!#$%&*@@]|(?:^|[^a-zA-Z0-9_+~.-])(?:rt|RT|rT|Rt):?)/;
+ twttr.txt.regexen.atSigns = /[@@]/;
+ twttr.txt.regexen.validMentionOrList = regexSupplant(
+ '(#{validMentionPrecedingChars})' + // $1: Preceding character
+@@ -252,30 +182,110 @@ var window = {};
+ twttr.txt.regexen.validDomainChars = regexSupplant(/[^#{invalidDomainChars}]/);
+ twttr.txt.regexen.validSubdomain = regexSupplant(/(?:(?:#{validDomainChars}(?:[_-]|#{validDomainChars})*)?#{validDomainChars}\.)/);
+ twttr.txt.regexen.validDomainName = regexSupplant(/(?:(?:#{validDomainChars}(?:-|#{validDomainChars})*)?#{validDomainChars}\.)/);
+- twttr.txt.regexen.validGTLD = regexSupplant(/(?:(?:aero|asia|biz|cat|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|net|org|pro|tel|travel|xxx)(?=[^0-9a-zA-Z]|$))/);
++ twttr.txt.regexen.validGTLD = regexSupplant(RegExp(
++ '(?:(?:' +
++ 'abb|abbott|abogado|academy|accenture|accountant|accountants|aco|active|actor|ads|adult|aeg|aero|' +
++ 'afl|agency|aig|airforce|airtel|allfinanz|alsace|amsterdam|android|apartments|app|aquarelle|' +
++ 'archi|army|arpa|asia|associates|attorney|auction|audio|auto|autos|axa|azure|band|bank|bar|' +
++ 'barcelona|barclaycard|barclays|bargains|bauhaus|bayern|bbc|bbva|bcn|beer|bentley|berlin|best|' +
++ 'bet|bharti|bible|bid|bike|bing|bingo|bio|biz|black|blackfriday|bloomberg|blue|bmw|bnl|' +
++ 'bnpparibas|boats|bond|boo|boots|boutique|bradesco|bridgestone|broker|brother|brussels|budapest|' +
++ 'build|builders|business|buzz|bzh|cab|cafe|cal|camera|camp|cancerresearch|canon|capetown|capital|' +
++ 'caravan|cards|care|career|careers|cars|cartier|casa|cash|casino|cat|catering|cba|cbn|ceb|center|' +
++ 'ceo|cern|cfa|cfd|chanel|channel|chat|cheap|chloe|christmas|chrome|church|cisco|citic|city|' +
++ 'claims|cleaning|click|clinic|clothing|cloud|club|coach|codes|coffee|college|cologne|com|' +
++ 'commbank|community|company|computer|condos|construction|consulting|contractors|cooking|cool|' +
++ 'coop|corsica|country|coupons|courses|credit|creditcard|cricket|crown|crs|cruises|cuisinella|' +
++ 'cymru|cyou|dabur|dad|dance|date|dating|datsun|day|dclk|deals|degree|delivery|delta|democrat|' +
++ 'dental|dentist|desi|design|dev|diamonds|diet|digital|direct|directory|discount|dnp|docs|dog|' +
++ 'doha|domains|doosan|download|drive|durban|dvag|earth|eat|edu|education|email|emerck|energy|' +
++ 'engineer|engineering|enterprises|epson|equipment|erni|esq|estate|eurovision|eus|events|everbank|' +
++ 'exchange|expert|exposed|express|fage|fail|faith|family|fan|fans|farm|fashion|feedback|film|' +
++ 'finance|financial|firmdale|fish|fishing|fit|fitness|flights|florist|flowers|flsmidth|fly|foo|' +
++ 'football|forex|forsale|forum|foundation|frl|frogans|fund|furniture|futbol|fyi|gal|gallery|game|' +
++ 'garden|gbiz|gdn|gent|genting|ggee|gift|gifts|gives|giving|glass|gle|global|globo|gmail|gmo|gmx|' +
++ 'gold|goldpoint|golf|goo|goog|google|gop|gov|graphics|gratis|green|gripe|group|guge|guide|' +
++ 'guitars|guru|hamburg|hangout|haus|healthcare|help|here|hermes|hiphop|hitachi|hiv|hockey|' +
++ 'holdings|holiday|homedepot|homes|honda|horse|host|hosting|hoteles|hotmail|house|how|hsbc|ibm|' +
++ 'icbc|ice|icu|ifm|iinet|immo|immobilien|industries|infiniti|info|ing|ink|institute|insure|int|' +
++ 'international|investments|ipiranga|irish|ist|istanbul|itau|iwc|java|jcb|jetzt|jewelry|jlc|jll|' +
++ 'jobs|joburg|jprs|juegos|kaufen|kddi|kim|kitchen|kiwi|koeln|komatsu|krd|kred|kyoto|lacaixa|' +
++ 'lancaster|land|lasalle|lat|latrobe|law|lawyer|lds|lease|leclerc|legal|lexus|lgbt|liaison|lidl|' +
++ 'life|lighting|limited|limo|link|live|lixil|loan|loans|lol|london|lotte|lotto|love|ltda|lupin|' +
++ 'luxe|luxury|madrid|maif|maison|man|management|mango|market|marketing|markets|marriott|mba|media|' +
++ 'meet|melbourne|meme|memorial|men|menu|miami|microsoft|mil|mini|mma|mobi|moda|moe|mom|monash|' +
++ 'money|montblanc|mormon|mortgage|moscow|motorcycles|mov|movie|movistar|mtn|mtpc|museum|nadex|' +
++ 'nagoya|name|navy|nec|net|netbank|network|neustar|new|news|nexus|ngo|nhk|nico|ninja|nissan|nokia|' +
++ 'nra|nrw|ntt|nyc|office|okinawa|omega|one|ong|onl|online|ooo|oracle|orange|org|organic|osaka|' +
++ 'otsuka|ovh|page|panerai|paris|partners|parts|party|pet|pharmacy|philips|photo|photography|' +
++ 'photos|physio|piaget|pics|pictet|pictures|pink|pizza|place|play|plumbing|plus|pohl|poker|porn|' +
++ 'post|praxi|press|pro|prod|productions|prof|properties|property|pub|qpon|quebec|racing|realtor|' +
++ 'realty|recipes|red|redstone|rehab|reise|reisen|reit|ren|rent|rentals|repair|report|republican|' +
++ 'rest|restaurant|review|reviews|rich|ricoh|rio|rip|rocks|rodeo|rsvp|ruhr|run|ryukyu|saarland|' +
++ 'sakura|sale|samsung|sandvik|sandvikcoromant|sanofi|sap|sarl|saxo|sca|scb|schmidt|scholarships|' +
++ 'school|schule|schwarz|science|scor|scot|seat|seek|sener|services|sew|sex|sexy|shiksha|shoes|' +
++ 'show|shriram|singles|site|ski|sky|skype|sncf|soccer|social|software|sohu|solar|solutions|sony|' +
++ 'soy|space|spiegel|spreadbetting|srl|starhub|statoil|studio|study|style|sucks|supplies|supply|' +
++ 'support|surf|surgery|suzuki|swatch|swiss|sydney|systems|taipei|tatamotors|tatar|tattoo|tax|taxi|' +
++ 'team|tech|technology|tel|telefonica|temasek|tennis|thd|theater|tickets|tienda|tips|tires|tirol|' +
++ 'today|tokyo|tools|top|toray|toshiba|tours|town|toyota|toys|trade|trading|training|travel|trust|' +
++ 'tui|ubs|university|uno|uol|vacations|vegas|ventures|vermögensberater|vermögensberatung|' +
++ 'versicherung|vet|viajes|video|villas|vin|vision|vista|vistaprint|vlaanderen|vodka|vote|voting|' +
++ 'voto|voyage|wales|walter|wang|watch|webcam|website|wed|wedding|weir|whoswho|wien|wiki|' +
++ 'williamhill|win|windows|wine|wme|work|works|world|wtc|wtf|xbox|xerox|xin|xperia|xxx|xyz|yachts|' +
++ 'yandex|yodobashi|yoga|yokohama|youtube|zip|zone|zuerich|дети|ком|москва|онлайн|орг|рус|сайт|קום|' +
++ 'بازار|شبكة|كوم|موقع|कॉम|नेट|संगठन|คอม|みんな|グーグル|コム|世界|中信|中文网|企业|佛山|信息|健康|八卦|公司|公益|商城|商店|商标|在线|大拿|' +
++ '娱乐|工行|广东|慈善|我爱你|手机|政务|政府|新闻|时尚|机构|淡马锡|游戏|点看|移动|组织机构|网址|网店|网络|谷歌|集团|飞利浦|餐厅|닷넷|닷컴|삼성|onion' +
++ ')(?=[^0-9a-zA-Z@]|$))'));
+ twttr.txt.regexen.validCCTLD = regexSupplant(RegExp(
+- "(?:(?:ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|" +
+- "ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|" +
+- "ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|" +
+- "ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|" +
+- "na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|" +
+- "sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|" +
+- "ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|za|zm|zw)(?=[^0-9a-zA-Z]|$))"));
++ '(?:(?:' +
++ 'ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bl|bm|bn|bo|bq|' +
++ 'br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cw|cx|cy|cz|de|dj|dk|dm|do|dz|' +
++ 'ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|' +
++ 'gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|' +
++ 'la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mf|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|' +
++ 'my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|' +
++ 'rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|' +
++ 'tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|um|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|za|zm|zw|ελ|' +
++ 'бел|мкд|мон|рф|срб|укр|қаз|հայ|الاردن|الجزائر|السعودية|المغرب|امارات|ایران|بھارت|تونس|سودان|' +
++ 'سورية|عراق|عمان|فلسطين|قطر|مصر|مليسيا|پاکستان|भारत|বাংলা|ভারত|ਭਾਰਤ|ભારત|இந்தியா|இலங்கை|' +
++ 'சிங்கப்பூர்|భారత్|ලංකා|ไทย|გე|中国|中國|台湾|台灣|新加坡|澳門|香港|한국' +
++ ')(?=[^0-9a-zA-Z@]|$))'));
+ twttr.txt.regexen.validPunycode = regexSupplant(/(?:xn--[0-9a-z]+)/);
++ twttr.txt.regexen.validSpecialCCTLD = regexSupplant(RegExp(
++ '(?:(?:co|tv)(?=[^0-9a-zA-Z@]|$))'));
+ twttr.txt.regexen.validDomain = regexSupplant(/(?:#{validSubdomain}*#{validDomainName}(?:#{validGTLD}|#{validCCTLD}|#{validPunycode}))/);
+ twttr.txt.regexen.validAsciiDomain = regexSupplant(/(?:(?:[\-a-z0-9#{latinAccentChars}]+)\.)+(?:#{validGTLD}|#{validCCTLD}|#{validPunycode})/gi);
+- twttr.txt.regexen.invalidShortDomain = regexSupplant(/^#{validDomainName}#{validCCTLD}$/);
++ twttr.txt.regexen.invalidShortDomain = regexSupplant(/^#{validDomainName}#{validCCTLD}$/i);
++ twttr.txt.regexen.validSpecialShortDomain = regexSupplant(/^#{validDomainName}#{validSpecialCCTLD}$/i);
+
+ twttr.txt.regexen.validPortNumber = regexSupplant(/[0-9]+/);
+
+- twttr.txt.regexen.validGeneralUrlPathChars = regexSupplant(/[a-z0-9!\*';:=\+,\.\$\/%#\[\]\-_~@|&#{latinAccentChars}]/i);
+- // Allow URL paths to contain balanced parens
++ twttr.txt.regexen.cyrillicLettersAndMarks = regexSupplant("\u0400-\u04FF");
++ twttr.txt.regexen.validGeneralUrlPathChars = regexSupplant(/[a-z#{cyrillicLettersAndMarks}0-9!\*';:=\+,\.\$\/%#\[\]\-_~@\|&#{latinAccentChars}]/i);
++ // Allow URL paths to contain up to two nested levels of balanced parens
+ // 1. Used in Wikipedia URLs like /Primer_(film)
+ // 2. Used in IIS sessions like /S(dfd346)/
+- twttr.txt.regexen.validUrlBalancedParens = regexSupplant(/\(#{validGeneralUrlPathChars}+\)/i);
++ // 3. Used in Rdio URLs like /track/We_Up_(Album_Version_(Edited))/
++ twttr.txt.regexen.validUrlBalancedParens = regexSupplant(
++ '\\(' +
++ '(?:' +
++ '#{validGeneralUrlPathChars}+' +
++ '|' +
++ // allow one nested level of balanced parentheses
++ '(?:' +
++ '#{validGeneralUrlPathChars}*' +
++ '\\(' +
++ '#{validGeneralUrlPathChars}+' +
++ '\\)' +
++ '#{validGeneralUrlPathChars}*' +
++ ')' +
++ ')' +
++ '\\)'
++ , 'i');
+ // Valid end-of-path chracters (so /foo. does not gobble the period).
+ // 1. Allow =&# for empty URL parameters and other URL-join artifacts
+- twttr.txt.regexen.validUrlPathEndingChars = regexSupplant(/[\+\-a-z0-9=_#\/#{latinAccentChars}]|(?:#{validUrlBalancedParens})/i);
++ twttr.txt.regexen.validUrlPathEndingChars = regexSupplant(/[\+\-a-z#{cyrillicLettersAndMarks}0-9=_#\/#{latinAccentChars}]|(?:#{validUrlBalancedParens})/i);
+ // Allow @ in a url, but only in the middle. Catch things like http://example.com/@user/
+ twttr.txt.regexen.validUrlPath = regexSupplant('(?:' +
+ '(?:' +
+@@ -309,7 +319,7 @@ var window = {};
+ twttr.txt.regexen.validCashtag = regexSupplant('(^|#{spaces})(\\$)(#{cashtag})(?=$|\\s|[#{punct}])', 'gi');
+
+ // These URL validation pattern strings are based on the ABNF from RFC 3986
+- twttr.txt.regexen.validateUrlUnreserved = /[a-z0-9\-._~]/i;
++ twttr.txt.regexen.validateUrlUnreserved = /[a-z\u0400-\u04FF0-9\-._~]/i;
+ twttr.txt.regexen.validateUrlPctEncoded = /(?:%[0-9a-f]{2})/i;
+ twttr.txt.regexen.validateUrlSubDelims = /[!$&'()*+,;=]/i;
+ twttr.txt.regexen.validateUrlPchar = regexSupplant('(?:' +
+@@ -478,7 +488,7 @@ var window = {};
+ attrs.href = options.hashtagUrlBase + hashtag;
+ attrs.title = "#" + hashtag;
+ attrs["class"] = options.hashtagClass;
+- if (hashtag[0].match(twttr.txt.regexen.rtl_chars)){
++ if (hashtag.charAt(0).match(twttr.txt.regexen.rtl_chars)){
+ attrs["class"] += " rtl";
+ }
+ if (options.targetBlank) {
+@@ -683,22 +693,34 @@ var window = {};
+ };
+
+ twttr.txt.autoLinkWithJSON = function(text, json, options) {
++ // map JSON entity to twitter-text entity
++ if (json.user_mentions) {
++ for (var i = 0; i < json.user_mentions.length; i++) {
++ // this is a @mention
++ json.user_mentions[i].screenName = json.user_mentions[i].screen_name;
++ }
++ }
++
++ if (json.hashtags) {
++ for (var i = 0; i < json.hashtags.length; i++) {
++ // this is a #hashtag
++ json.hashtags[i].hashtag = json.hashtags[i].text;
++ }
++ }
++
++ if (json.symbols) {
++ for (var i = 0; i < json.symbols.length; i++) {
++ // this is a $CASH tag
++ json.symbols[i].cashtag = json.symbols[i].text;
++ }
++ }
++
+ // concatenate all entities
+ var entities = [];
+ for (var key in json) {
+ entities = entities.concat(json[key]);
+ }
+- // map JSON entity to twitter-text entity
+- for (var i = 0; i < entities.length; i++) {
+- entity = entities[i];
+- if (entity.screen_name) {
+- // this is @mention
+- entity.screenName = entity.screen_name;
+- } else if (entity.text) {
+- // this is #hashtag
+- entity.hashtag = entity.text;
+- }
+- }
++
+ // modify indices to UTF-16
+ twttr.txt.modifyIndicesFromUnicodeToUTF16(text, entities);
+
+@@ -861,7 +883,6 @@ var window = {};
+ if (!options) {
+ options = {extractUrlsWithoutProtocol: true};
+ }
+-
+ if (!text || (options.extractUrlsWithoutProtocol ? !text.match(/\./) : !text.match(/:/))) {
+ return [];
+ }
+@@ -881,7 +902,6 @@ var window = {};
+ continue;
+ }
+ var lastUrl = null,
+- lastUrlInvalidMatch = false,
+ asciiEndPosition = 0;
+ domain.replace(twttr.txt.regexen.validAsciiDomain, function(asciiDomain) {
+ var asciiStartPosition = domain.indexOf(asciiDomain, asciiEndPosition);
+@@ -890,8 +910,9 @@ var window = {};
+ url: asciiDomain,
+ indices: [startPosition + asciiStartPosition, startPosition + asciiEndPosition]
+ };
+- lastUrlInvalidMatch = asciiDomain.match(twttr.txt.regexen.invalidShortDomain);
+- if (!lastUrlInvalidMatch) {
++ if (path
++ || asciiDomain.match(twttr.txt.regexen.validSpecialShortDomain)
++ || !asciiDomain.match(twttr.txt.regexen.invalidShortDomain)) {
+ urls.push(lastUrl);
+ }
+ });
+@@ -903,9 +924,6 @@ var window = {};
+
+ // lastUrl only contains domain. Need to add path and query if they exist.
+ if (path) {
+- if (lastUrlInvalidMatch) {
+- urls.push(lastUrl);
+- }
+ lastUrl.url = url.replace(domain, lastUrl.url);
+ lastUrl.indices[1] = endPosition;
+ }
+@@ -1199,7 +1217,7 @@ var window = {};
+ options = {
+ // These come from https://api.twitter.com/1/help/configuration.json
+ // described by https://dev.twitter.com/docs/api/1/get/help/configuration
+- short_url_length: 22,
++ short_url_length: 23,
+ short_url_length_https: 23
+ };
+ }
+@@ -1208,11 +1226,11 @@ var window = {};
+ twttr.txt.modifyIndicesFromUTF16ToUnicode(text, urlsWithIndices);
+
+ for (var i = 0; i < urlsWithIndices.length; i++) {
+- // Subtract the length of the original URL
++ // Subtract the length of the original URL
+ textLength += urlsWithIndices[i].indices[0] - urlsWithIndices[i].indices[1];
+
+ // Add 23 characters for URL starting with https://
+- // Otherwise add 22 characters
++ // http:// URLs still use https://t.co so they are 23 characters as well
+ if (urlsWithIndices[i].url.toLowerCase().match(twttr.txt.regexen.urlHasHttps)) {
+ textLength += options.short_url_length_https;
+ } else {
+@@ -1242,12 +1260,19 @@ var window = {};
+ return "too_long";
+ }
+
++ if (twttr.txt.hasInvalidCharacters(text)) {
++ return "invalid_characters";
++ }
++
++ return false;
++ };
++
++ twttr.txt.hasInvalidCharacters = function(text) {
+ for (var i = 0; i < INVALID_CHARACTERS.length; i++) {
+ if (text.indexOf(INVALID_CHARACTERS[i]) >= 0) {
+- return "invalid_characters";
++ return true;
+ }
+ }
+-
+ return false;
+ };
+
+@@ -1339,6 +1364,10 @@ var window = {};
+ module.exports = twttr.txt;
+ }
+
++ if (typeof define == 'function' && define.amd) {
++ define([], twttr.txt);
++ }
++
+ if (typeof window != 'undefined') {
+ if (window.twttr) {
+ for (var prop in twttr) {
+diff --git a/chat/protocols/twitter/twitter.js b/chat/protocols/twitter/twitter.js
+index fac9c56..af5e4d5 100644
+--- a/chat/protocols/twitter/twitter.js
++++ b/chat/protocols/twitter/twitter.js
+@@ -36,8 +36,11 @@ ChatBuddy.prototype = {
+ set buddyIconFilename(aName) {
+ // Prevent accidental removal of the getter.
+ throw("Don't set chatBuddy.buddyIconFilename directly for Twitter.");
++ },
++ createConversation: function() {
++ return this._account.createConversation(this._name);
+ }
+-}
++};
+
+ function Tweet(aTweet, aWho, aMessage, aObject)
+ {
+@@ -51,7 +54,12 @@ Tweet.prototype = {
+ let account = this.conversation._account;
+ let actions = [];
+
+- if (account.connected) {
++ if (!this.conversation.isChat) {
++ if (aCount)
++ aCount.value = actions.length;
++ return actions;
++ }
++ else if (account.connected) {
+ actions.push(
+ new Action(_("action.reply"), function() {
+ this.conversation.startReply(this._tweet);
+@@ -123,13 +131,109 @@ Action.prototype = {
+ get run() { return this._action.bind(this._tweet); }
+ };
+
+-function Conversation(aAccount)
++// Properties / methods shared by both DirectMessageConversation and
++// TimelineConversation.
++var GenericTwitterConversation = {
++ getTweetLength: function (aString) {
++ // Use the Twitter library to calculate the length.
++ return twttr.txt.getTweetLength(aString, this._account.config);
++ },
++ systemMessage: function(aMessage, aIsError, aDate) {
++ let flags = {system: true};
++ if (aIsError)
++ flags.error = true;
++ if (aDate)
++ flags.time = aDate;
++ this.writeMessage("twitter.com", aMessage, flags);
++ },
++ onSentCallback: function(aMsg, aData) {
++ // The conversation may have been unitialized in the time it takes for
++ // the async callback to fire. Use `_observers` as a proxy for uninit'd.
++ if (!Array.isArray(this._observers))
++ return;
++
++ let tweet = JSON.parse(aData);
++ // The OTR extension requires that the protocol not modify the message
++ // (see the notes at `imIOutgoingMessage`). That's the contract we made.
++ // Unfortunately, Twitter trims tweets and substitutes links.
++ tweet.text = aMsg;
++ this.displayMessages([tweet]);
++ },
++ prepareForDisplaying: function(aMsg) {
++ let text = aMsg.displayMessage;
++ let tweet = aMsg.wrappedJSObject.prplMessage.wrappedJSObject._tweet;
++
++ // Handle retweets: retweeted_status contains the object for the original
++ // tweet that is being retweeted.
++ // If the retweet prefix ("RT @<username>: ") causes the tweet to be over
++ // 140 characters, ellipses will be added. In this case, we want to get
++ // the FULL text from the original tweet and update the entities to match.
++ // Note: the truncated flag is not always set correctly by twitter, so we
++ // always make use of the original tweet.
++ if ("retweeted_status" in tweet) {
++ let retweet = tweet["retweeted_status"];
++ // We're going to take portions of the retweeted status and replace parts
++ // of the original tweet, the retweeted status prepends the original
++ // status with "RT @<username>: ", we need to keep the prefix.
++ // Note: this doesn't play nice with extensions that may have altered
++ // `text` to this point, but at least OTR doesn't act on `isChat`.
++ let offset = text.indexOf(": ") + 2;
++ text = text.slice(0, offset) + retweet.text;
++ }
++
++ // Pass in the url entities so the t.co links are replaced.
++ aMsg.displayMessage = twttr.txt.autoLink(text, {
++ urlEntities: tweet.entities.urls.map(function(u) {
++ var o = Object.assign(u);
++ // But remove the indices so they apply in the face of modifications.
++ delete o.indices;
++ return o;
++ })
++ });
++
++ GenericConversationPrototype.prepareForDisplaying.apply(this, arguments);
++ },
++ displayTweet: function(aTweet, aUser) {
++ let name = aUser.screen_name;
++
++ let flags = name == this.nick ? {outgoing: true} : {incoming: true};
++ flags.time = Math.round(new Date(aTweet.created_at) / 1000);
++ flags._iconURL = aUser.profile_image_url;
++ if (aTweet.delayed)
++ flags.delayed = true;
++ if (aTweet.entities && aTweet.entities.user_mentions &&
++ Array.isArray(aTweet.entities.user_mentions) &&
++ aTweet.entities.user_mentions.some(mention => mention.screen_name == this.nick))
++ flags.containsNick = true;
++
++ (new Tweet(aTweet, name, aTweet.text, flags)).conversation = this;
++ },
++ _parseError: function(aData) {
++ let error = "";
++ try {
++ let data = JSON.parse(aData);
++ if ("error" in data)
++ error = data.error;
++ else if ("errors" in data)
++ error = data.errors[0].message;
++ if (error)
++ error = "(" + error + ")";
++ } catch(e) {}
++ return error;
++ }
++};
++
++function TimelineConversation(aAccount)
+ {
+ this._init(aAccount);
+ this._ensureParticipantExists(aAccount.name);
+ // We need the screen names for the IDs in _friends, but _userInfo is
+ // indexed by name, so we build an ID -> name map.
+- let names = new Map([userInfo.id_str, name] for ([name, userInfo] of aAccount._userInfo));
++ let entries = [];
++ for (let [name, userInfo] of aAccount._userInfo) {
++ entries.push([userInfo.id_str, name]);
++ }
++ let names = new Map(entries);
+ for (let id_str of aAccount._friends)
+ this._ensureParticipantExists(names.get(id_str));
+
+@@ -140,7 +244,7 @@ function Conversation(aAccount)
+ this.setTopic(userInfo.description, aAccount.name, true);
+ }
+ }
+-Conversation.prototype = {
++TimelineConversation.prototype = {
+ __proto__: GenericConvChatPrototype,
+ unInit: function() {
+ delete this._account._timeline;
+@@ -170,22 +274,18 @@ Conversation.prototype = {
+ _("replyingToStatusText", aTweet.text));
+ },
+ reTweet: function(aTweet) {
+- this._account.reTweet(aTweet, this.onSentCallback,
+- function(aException, aData) {
++ this._account.reTweet(aTweet, null, function(aException, aData) {
+ this.systemMessage(_("error.retweet", this._parseError(aData),
+ aTweet.text), true);
+ }, this);
+ },
+- getTweetLength: function (aString) {
+- // Use the Twitter library to calculate the length.
+- return twttr.txt.getTweetLength(aString, this._account.config);
+- },
+- sendMsg: function (aMsg) {
++ sendMsg: function(aMsg) {
+ if (this.getTweetLength(aMsg) > kMaxMessageLength) {
+ this.systemMessage(_("error.tooLong"), true);
+ throw Cr.NS_ERROR_INVALID_ARG;
+ }
+- this._account.tweet(aMsg, this.inReplyToStatusId, this.onSentCallback,
++ this._account.tweet(aMsg, this.inReplyToStatusId,
++ this.onSentCallback.bind(this, aMsg),
+ function(aException, aData) {
+ let error = this._parseError(aData);
+ this.systemMessage(_("error.general", error, aMsg), true);
+@@ -200,163 +300,30 @@ Conversation.prototype = {
+ }
+ return kMaxMessageLength - this.getTweetLength(aString);
+ },
+- systemMessage: function(aMessage, aIsError, aDate) {
+- let flags = {system: true};
+- if (aIsError)
+- flags.error = true;
+- if (aDate)
+- flags.time = aDate;
+- this.writeMessage("twitter.com", aMessage, flags);
+- },
+- onSentCallback: function(aData) {
+- let tweet = JSON.parse(aData);
+- if (tweet.user.screen_name != this._account.name)
+- throw "Wrong screen_name... Uh?";
+- this._account.displayMessages([tweet]);
+- },
+- _parseError: function(aData) {
+- let error = "";
+- try {
+- let data = JSON.parse(aData);
+- if ("error" in data)
+- error = data.error;
+- else if ("errors" in data)
+- error = data.errors[0].message;
+- if (error)
+- error = "(" + error + ")";
+- } catch(e) {}
+- return error;
+- },
+- parseTweet: function(aTweet) {
+- let text = aTweet.text;
+- let entities = {};
+- // Handle retweets: retweeted_status contains the object for the original
+- // tweet that is being retweeted.
+- // If the retweet prefix ("RT @<username>: ") causes the tweet to be over
+- // 140 characters, ellipses will be added. In this case, we want to get
+- // the FULL text from the original tweet and update the entities to match.
+- // Note: the truncated flag is not always set correctly by twitter, so we
+- // always make use of the original tweet.
+- if ("retweeted_status" in aTweet) {
+- let retweet = aTweet["retweeted_status"];
+- // We're going to take portions of the retweeted status and replace parts
+- // of the original tweet, the retweeted status prepends the original
+- // status with "RT @<username>: ", we need to keep the prefix.
+- let offset = text.indexOf(": ") + 2;
+- text = text.slice(0, offset) + retweet.text;
+-
+- // Keep any entities that refer to the prefix (we can refer directly to
+- // aTweet for these since they are not edited).
+- if ("entities" in aTweet) {
+- for (let type in aTweet.entities) {
+- let filteredEntities =
+- aTweet.entities[type].filter(e => e.indices[0] < offset);
+- if (filteredEntities.length)
+- entities[type] = filteredEntities;
+- }
+- }
++ displayMessages: function(aMessages) {
++ let account = this._account;
++ let lastMsgId = account._lastMsgId;
++ for (let tweet of aMessages) {
++ if (!("user" in tweet) || !("text" in tweet) || !("id_str" in tweet) ||
++ account._knownMessageIds.has(tweet.id_str))
++ continue;
++ let id = tweet.id_str;
++ // Update the last known message.
++ // Compare the length of the ids first, and then the text.
++ // This avoids converting tweet ids into rounded numbers.
++ if (id.length > lastMsgId.length ||
++ (id.length == lastMsgId.length && id > lastMsgId))
++ lastMsgId = id;
++ account._knownMessageIds.add(id);
++ account.setUserInfo(tweet.user);
+
+- // Add the entities from the retweet (a copy of these must be made since
+- // they will be edited and we do not wish to change aTweet).
+- if ("entities" in retweet) {
+- for (let type in retweet.entities) {
+- if (!(type in entities))
+- entities[type] = [];
+-
+- // Append the entities from the original status.
+- entities[type] = entities[type].concat(
+- retweet.entities[type].map(function(aEntity) {
+- let entity = Object.create(aEntity);
+- // Add the offset to the indices to account for the prefix.
+- entity.indices = entity.indices.map(i => i + offset);
+- return entity;
+- })
+- );
+- }
+- }
+- } else {
+- // For non-retweets, we just want to use the entities that are given.
+- if ("entities" in aTweet)
+- entities = aTweet.entities;
++ this._ensureParticipantExists(tweet.user.screen_name);
++ this.displayTweet(tweet, tweet.user);
+ }
+-
+- if (Object.keys(entities).length) {
+- /* entArray is an array of entities ready to be replaced in the tweet,
+- * each entity contains:
+- * - start: the start index of the entity inside the tweet,
+- * - end: the end index of the entity inside the tweet,
+- * - str: the string that should be replaced inside the tweet,
+- * - href: the url (href attribute) of the created link tag,
+- * - [optional] text: the text to display for the link,
+- * The original string (str) will be used if this is not set.
+- * - [optional] title: the title attribute for the link.
+- */
+- let entArray = [];
+- if ("hashtags" in entities && Array.isArray(entities.hashtags)) {
+- entArray = entArray.concat(entities.hashtags.map(h => ({
+- start: h.indices[0],
+- end: h.indices[1],
+- str: "#" + h.text,
+- href: "https://twitter.com/#!/search?q=%23" + h.text})));
+- }
+- if ("urls" in entities && Array.isArray(entities.urls)) {
+- entArray = entArray.concat(entities.urls.map(u => ({
+- start: u.indices[0],
+- end: u.indices[1],
+- str: u.url,
+- text: u.display_url || u.url,
+- href: u.expanded_url || u.url})));
+- }
+- if ("user_mentions" in entities &&
+- Array.isArray(entities.user_mentions)) {
+- entArray = entArray.concat(entities.user_mentions.map(um => ({
+- start: um.indices[0],
+- end: um.indices[1],
+- str: "@" + um.screen_name,
+- text: '@<span class="ib-person">' + um.screen_name + "</span>",
+- title: um.name,
+- href: "https://twitter.com/" + um.screen_name})));
+- }
+- entArray.sort((a, b) => a.start - b.start);
+- let offset = 0;
+- for each (let entity in entArray) {
+- let str = text.substring(offset + entity.start, offset + entity.end);
+- if (str[0] == "\uFF20") // @ - unicode character similar to @
+- str = "@" + str.substring(1);
+- if (str[0] == "\uFF03") // # - unicode character similar to #
+- str = "#" + str.substring(1);
+- if (str.toLowerCase() != entity.str.toLowerCase())
+- continue;
+-
+- let html = "<a href=\"" + entity.href + "\"";
+- if ("title" in entity)
+- html += " title=\"" + entity.title + "\"";
+- html += ">" + ("text" in entity ? entity.text : entity.str) + "</a>";
+- text = text.slice(0, offset + entity.start) + html +
+- text.slice(offset + entity.end);
+- offset += html.length - (entity.end - entity.start);
+- }
++ if (lastMsgId != account._lastMsgId) {
++ account._lastMsgId = lastMsgId;
++ account.prefs.setCharPref("lastMessageId", account._lastMsgId);
+ }
+-
+- return text;
+- },
+- displayTweet: function(aTweet) {
+- let name = aTweet.user.screen_name;
+- this._ensureParticipantExists(name);
+- let text = this.parseTweet(aTweet);
+-
+- let flags =
+- name == this._account.name ? {outgoing: true} : {incoming: true};
+- flags.time = Math.round(new Date(aTweet.created_at) / 1000);
+- flags._iconURL = aTweet.user.profile_image_url;
+- if (aTweet.delayed)
+- flags.delayed = true;
+- if (aTweet.entities && aTweet.entities.user_mentions &&
+- Array.isArray(aTweet.entities.user_mentions) &&
+- aTweet.entities.user_mentions.some(mention => mention.screen_name == this.nick))
+- flags.containsNick = true;
+-
+- (new Tweet(aTweet, name, text, flags)).conversation = this;
+ },
+ _ensureParticipantExists: function(aNick) {
+ if (this._participants.has(aNick))
+@@ -378,6 +345,41 @@ Conversation.prototype = {
+ this._account.setUserDescription(aTopic);
+ }
+ };
++Object.assign(TimelineConversation.prototype, GenericTwitterConversation);
++
++function DirectMessageConversation(aAccount, aName)
++{
++ this._init(aAccount, aName);
++}
++DirectMessageConversation.prototype = {
++ __proto__: GenericConvIMPrototype,
++ sendMsg: function(aMsg) {
++ this._account.directMessage(aMsg, this.name,
++ this.onSentCallback.bind(this, aMsg),
++ function(aException, aData) {
++ let error = this._parseError(aData);
++ this.systemMessage(_("error.general", error, aMsg), true);
++ }, this);
++ },
++ displayMessages: function(aMessages) {
++ let account = this._account;
++ for (let tweet of aMessages) {
++ if (!("sender" in tweet) || !("recipient" in tweet) ||
++ !("text" in tweet) || !("id_str" in tweet))
++ continue;
++ account.setUserInfo(tweet.sender);
++ account.setUserInfo(tweet.recipient);
++ this.displayTweet(tweet, tweet.sender);
++ }
++ },
++ unInit: function() {
++ this._account.removeConversation(this.name);
++ GenericConvIMPrototype.unInit.call(this);
++ },
++ get nick() { return this._account.name; },
++ set nick(aNick) {}
++}
++Object.assign(DirectMessageConversation.prototype, GenericTwitterConversation);
+
+ function Account(aProtocol, aImAccount)
+ {
+@@ -385,15 +387,12 @@ function Account(aProtocol, aImAccount)
+ this._knownMessageIds = new Set();
+ this._userInfo = new Map();
+ this._friends = new Set();
++ // Contains just `DirectMessageConversation`s
++ this._conversations = new Map();
+ }
+ Account.prototype = {
+ __proto__: GenericAccountPrototype,
+
+- // The correct normalization for twitter would be just toLowerCase().
+- // Unfortunately, for backwards compatibility we retain this normalization,
+- // which can cause edge cases for usernames with underscores.
+- normalize: aString => aString.replace(/[^a-z0-9]/gi, "").toLowerCase(),
+-
+ consumerKey: Services.prefs.getCharPref("chat.twitter.consumerKey"),
+ consumerSecret: Services.prefs.getCharPref("chat.twitter.consumerSecret"),
+ completionURI: "http://oauthcallback.local/",
+@@ -512,7 +511,7 @@ Account.prototype = {
+ hmac.init(hmac.SHA1,
+ keyFactory.keyFromString(Ci.nsIKeyObject.HMAC, signatureKey));
+ // No UTF-8 encoding, special chars are already escaped.
+- let bytes = [b.charCodeAt() for each (b in signatureBase)];
++ let bytes = [...signatureBase].map(b => b.charCodeAt());
+ hmac.update(bytes, bytes.length);
+ let signature = hmac.finish(true);
+
+@@ -555,6 +554,11 @@ Account.prototype = {
+ let url = "1.1/statuses/destroy/" + aTweet.id_str + ".json";
+ this.signAndSend(url, null, [], aOnSent, aOnError, aThis);
+ },
++ directMessage: function(aMsg, aName, aOnSent, aOnError, aThis) {
++ let POSTData = [["text", aMsg], ["screen_name", aName]];
++ this.signAndSend("1.1/direct_messages/new.json", null, POSTData, aOnSent,
++ aOnError, aThis);
++ },
+
+ _friends: null,
+ follow: function(aUserName) {
+@@ -617,29 +621,7 @@ Account.prototype = {
+ }
+ },
+
+- get timeline() { return this._timeline || (this._timeline = new Conversation(this)); },
+- displayMessages: function(aMessages) {
+- let lastMsgId = this._lastMsgId;
+- for each (let tweet in aMessages) {
+- if (!("user" in tweet) || !("text" in tweet) || !("id_str" in tweet) ||
+- this._knownMessageIds.has(tweet.id_str))
+- continue;
+- let id = tweet.id_str;
+- // Update the last known message.
+- // Compare the length of the ids first, and then the text.
+- // This avoids converting tweet ids into rounded numbers.
+- if (id.length > lastMsgId.length ||
+- (id.length == lastMsgId.length && id > lastMsgId))
+- lastMsgId = id;
+- this._knownMessageIds.add(id);
+- this.setUserInfo(tweet.user);
+- this.timeline.displayTweet(tweet);
+- }
+- if (lastMsgId != this._lastMsgId) {
+- this._lastMsgId = lastMsgId;
+- this.prefs.setCharPref("lastMessageId", this._lastMsgId);
+- }
+- },
++ get timeline() { return this._timeline || (this._timeline = new TimelineConversation(this)); },
+
+ onTimelineError: function(aError, aResponseText, aRequest) {
+ this.ERROR(aError);
+@@ -687,7 +669,7 @@ Account.prototype = {
+
+ this._timelineBuffer.sort(this.sortByDate);
+ this._timelineBuffer.forEach(aTweet => aTweet.delayed = true);
+- this.displayMessages(this._timelineBuffer);
++ this.timeline.displayMessages(this._timelineBuffer);
+
+ // Fetch userInfo for the user if we don't already have it.
+ this.requestBuddyInfo(this.name);
+@@ -739,7 +721,7 @@ Account.prototype = {
+ this.DEBUG("Received data: " + newText);
+ let messages = newText.split(/\r\n?/);
+ this._pendingData = messages.pop();
+- for each (let message in messages) {
++ for (let message of messages) {
+ if (!message.trim())
+ continue;
+ let msg;
+@@ -749,13 +731,18 @@ Account.prototype = {
+ this.ERROR(e + " while parsing " + message);
+ continue;
+ }
+- if ("text" in msg)
+- this.displayMessages([msg]);
++ if ("direct_message" in msg) {
++ let dm = msg["direct_message"];
++ if (dm.sender_screen_name !== this.name) // These are displayed on send.
++ this.getConversation(dm.sender_screen_name).displayMessages([dm]);
++ }
++ else if ("text" in msg)
++ this.timeline.displayMessages([msg]);
+ else if ("friends" in msg) {
+ // Filter out the IDs that info has already been received from (e.g. a
+ // tweet has been received as part of the timeline request).
+ let userInfoIds = new Set();
+- for each (let userInfo in this._userInfo)
++ for (let userInfo of this._userInfo.values())
+ userInfoIds.add(userInfo.id_str);
+ let ids = msg.friends.filter(
+ aId => !userInfoIds.has(aId.toString()));
+@@ -951,7 +938,7 @@ Account.prototype = {
+ cleanUp: function() {
+ this.finishAuthorizationRequest();
+ if (this._pendingRequests.length != 0) {
+- for each (let request in this._pendingRequests)
++ for (let request of this._pendingRequests)
+ request.abort();
+ delete this._pendingRequests;
+ }
+@@ -1088,7 +1075,7 @@ Account.prototype = {
+ // create the participant.
+ onLookupReceived: function(aData) {
+ let users = JSON.parse(aData);
+- for each (let user in users) {
++ for (let user of users) {
+ this.setUserInfo(user);
+ this.timeline._ensureParticipantExists(user.screen_name);
+ }
+@@ -1103,6 +1090,19 @@ Account.prototype = {
+ joinChat: function(aComponents) {
+ // The 'timeline' getter opens a timeline conversation if none exists.
+ this.timeline;
++ },
++
++ getConversation: function(aName) {
++ if (!this._conversations.has(aName))
++ this._conversations.set(aName, new DirectMessageConversation(this, aName));
++ return this._conversations.get(aName);
++ },
++ removeConversation: function(aName) {
++ if (this._conversations.has(aName))
++ this._conversations.delete(aName);
++ },
++ createConversation: function(aName) {
++ return this.getConversation(aName);
+ }
+ };
+
+--
+2.10.1
+
diff --git a/projects/instantbird/0006-Bug-1218193-Fix-tab-strip-background-colour-on-OS-X..patch b/projects/instantbird/0006-Bug-1218193-Fix-tab-strip-background-colour-on-OS-X..patch
new file mode 100644
index 0000000..2634d9d
--- /dev/null
+++ b/projects/instantbird/0006-Bug-1218193-Fix-tab-strip-background-colour-on-OS-X..patch
@@ -0,0 +1,26 @@
+From 820516967b23c191fda8c33b74260808838acb7d Mon Sep 17 00:00:00 2001
+From: Nihanth Subramanya <nhnt11(a)gmail.com>
+Date: Sun, 9 Oct 2016 21:53:04 -0700
+Subject: [PATCH 06/20] Bug 1218193 - Fix tab strip background colour on OS X.
+ r=aleth
+
+---
+ im/themes/tabbrowser-pinstripe/tabbrowser.css | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/im/themes/tabbrowser-pinstripe/tabbrowser.css b/im/themes/tabbrowser-pinstripe/tabbrowser.css
+index 76c5094..2915450 100644
+--- a/im/themes/tabbrowser-pinstripe/tabbrowser.css
++++ b/im/themes/tabbrowser-pinstripe/tabbrowser.css
+@@ -208,7 +208,7 @@ statusbarpanel#statusbar-display {
+ }
+
+ .tabbrowser-strip {
+- -moz-appearance: -moz-mac-unified-toolbar;
++ -moz-appearance: toolbar;
+ height: 26px;
+ background-repeat: repeat-x;
+ }
+--
+2.10.1
+
diff --git a/projects/instantbird/0007-Bug-1246431-XMPP-createConversation-should-handle-in.patch b/projects/instantbird/0007-Bug-1246431-XMPP-createConversation-should-handle-in.patch
new file mode 100644
index 0000000..c80e60d
--- /dev/null
+++ b/projects/instantbird/0007-Bug-1246431-XMPP-createConversation-should-handle-in.patch
@@ -0,0 +1,26 @@
+From f05bcdd1b1554e5acf3ce5ac95de62d2f2341361 Mon Sep 17 00:00:00 2001
+From: Arlo Breault <arlolra(a)gmail.com>
+Date: Sun, 9 Oct 2016 21:57:07 -0700
+Subject: [PATCH 07/20] Bug 1246431 - XMPP createConversation should handle
+ incoming messages from the server properly. r=aleth
+
+---
+ chat/protocols/xmpp/xmpp.jsm | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/chat/protocols/xmpp/xmpp.jsm b/chat/protocols/xmpp/xmpp.jsm
+index 0022be3..4420a1d 100644
+--- a/chat/protocols/xmpp/xmpp.jsm
++++ b/chat/protocols/xmpp/xmpp.jsm
+@@ -2108,7 +2108,7 @@ var XMPPAccountPrototype = {
+
+ // Checking that the aName can be parsed and is not broken.
+ let jid = this._parseJID(convName);
+- if (!jid || !jid.node || (isMucParticipant && !jid.resource)) {
++ if (!jid || !jid.domain || (isMucParticipant && (!jid.node || !jid.resource))) {
+ this.ERROR("Could not create conversation as jid is broken: " + convName);
+ throw "Invalid JID";
+ }
+--
+2.10.1
+
diff --git a/projects/instantbird/0008-Bug-1298574-Set-_userVCard-own-property-when-downloa.patch b/projects/instantbird/0008-Bug-1298574-Set-_userVCard-own-property-when-downloa.patch
new file mode 100644
index 0000000..ab5aef1
--- /dev/null
+++ b/projects/instantbird/0008-Bug-1298574-Set-_userVCard-own-property-when-downloa.patch
@@ -0,0 +1,39 @@
+From 4fff3e33c39807680dab5961e6577fa128237921 Mon Sep 17 00:00:00 2001
+From: Arlo Breault <arlolra(a)gmail.com>
+Date: Sun, 28 Aug 2016 08:57:41 -0700
+Subject: [PATCH 08/20] Bug 1298574 - Set _userVCard own property when
+ downloading vCard fails. r=aleth
+
+ * This prevents an infinite req / res cycle.
+---
+ chat/protocols/xmpp/xmpp.jsm | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/chat/protocols/xmpp/xmpp.jsm b/chat/protocols/xmpp/xmpp.jsm
+index 4420a1d..71f7770 100644
+--- a/chat/protocols/xmpp/xmpp.jsm
++++ b/chat/protocols/xmpp/xmpp.jsm
+@@ -2243,6 +2243,20 @@ var XMPPAccountPrototype = {
+ .replace(/.{74}/g, "$&\n");
+ }
+ }
++ else {
++ // Downloading the vCard failed.
++ if (this.handleErrors({
++ itemNotFound: () => false, // OK, no vCard exists yet.
++ default: () => true
++ })(aStanza)) {
++ this.WARN("Unexpected error retrieving the user's vcard, " +
++ "so we won't attempt to set it either.");
++ return;
++ }
++ // Set this so that we don't get into an infinite loop trying to download
++ // the vcard again. The check in sendVCard is for hasOwnProperty.
++ this._userVCard = null;
++ }
+ this._sendVCard();
+ },
+
+--
+2.10.1
+
diff --git a/projects/instantbird/0009-XMPP-in-band-registration.patch b/projects/instantbird/0009-XMPP-in-band-registration.patch
new file mode 100644
index 0000000..1912917
--- /dev/null
+++ b/projects/instantbird/0009-XMPP-in-band-registration.patch
@@ -0,0 +1,396 @@
+From b773d4ee2dc099c684840cc1aef6984572e3dd8d Mon Sep 17 00:00:00 2001
+From: Sukhbir Singh <sukhbir(a)torproject.org>
+Date: Mon, 10 Oct 2016 18:42:25 -0700
+Subject: [PATCH 09/20] XMPP in-band registration
+
+---
+ chat/locales/en-US/xmpp.properties | 5 +
+ chat/protocols/xmpp/xmpp-session.jsm | 78 +++++++++++
+ im/content/accountWizard.js | 8 ++
+ im/content/accountWizard.xul | 1 +
+ im/content/jar.mn | 2 +
+ im/content/xmppRegister.js | 142 +++++++++++++++++++++
+ im/content/xmppRegister.xul | 27 ++++
+ .../en-US/chrome/instantbird/accountWizard.dtd | 2 +
+ 8 files changed, 265 insertions(+)
+ create mode 100644 im/content/xmppRegister.js
+ create mode 100644 im/content/xmppRegister.xul
+
+diff --git a/chat/locales/en-US/xmpp.properties b/chat/locales/en-US/xmpp.properties
+index 293ab01..237d20c 100644
+--- a/chat/locales/en-US/xmpp.properties
++++ b/chat/locales/en-US/xmpp.properties
+@@ -13,6 +13,9 @@ connection.initializingEncryption=Initializing encryption
+ connection.authenticating=Authenticating
+ connection.gettingResource=Getting resource
+ connection.downloadingRoster=Downloading contact list
++connection.registering=Registering new account
++connection.gettingRegistration=Getting registration form
++connection.onRegistrationSuccess=Account registered
+
+ # LOCALIZATION NOTE (connection.error.*)
+ # These will show in the account manager if an error occurs during the
+@@ -33,6 +36,8 @@ connection.error.notSendingPasswordInClear=The server only supports authenticati
+ connection.error.authenticationFailure=Authentication failure
+ connection.error.notAuthorized=Not authorized (Did you enter the wrong password?)
+ connection.error.failedToGetAResource=Failed to get a resource
++connection.error.noRegistrationSupport=The server does not support in-band registration
++connection.error.registrationCancel=Registration canceled
+
+
+ # LOCALIZATION NOTE (conversation.error.notDelivered):
+diff --git a/chat/protocols/xmpp/xmpp-session.jsm b/chat/protocols/xmpp/xmpp-session.jsm
+index 24618ee..246ec2b 100644
+--- a/chat/protocols/xmpp/xmpp-session.jsm
++++ b/chat/protocols/xmpp/xmpp-session.jsm
+@@ -11,6 +11,8 @@ Cu.import("resource:///modules/socket.jsm");
+ Cu.import("resource:///modules/xmpp-xml.jsm");
+ Cu.import("resource:///modules/xmpp-authmechs.jsm");
+
++const registerWindow = "chrome://instantbird/content/xmppRegister.xul";
++
+ XPCOMUtils.defineLazyGetter(this, "_", () =>
+ l10nHelper("chrome://chat/locale/xmpp.properties")
+ );
+@@ -68,6 +70,7 @@ XMPPSession.prototype = {
+ Stanza.node("ping", Stanza.NS.ping)),
+ this.cancelDisconnectTimer, this);
+ },
++ nodes: {},
+ _lastReceiveTime: 0,
+ _lastSendTime: 0,
+ checkPingTimer(aJustSentSomething = false) {
+@@ -271,6 +274,69 @@ XMPPSession.prototype = {
+ this.onXmppStanza = this.stanzaListeners.startAuth;
+ this.onXmppStanza(aStanza);
+ },
++ onRegisterResponse: function(aStanza) {
++ let error = this._account.parseError(aStanza);
++ if (error) {
++ this.onError(null, aStanza.getElement(["error"]).innerText);
++ return;
++ }
++ if (aStanza.attributes["type"] == "result") {
++ this._account.reportConnecting(_("connection.onRegistrationSuccess"));
++ this._account.prefs.setBoolPref("register", false);
++ this._account.connect();
++ }
++ return;
++ },
++ startRegister: function(aStanza) {
++ // Some servers do not support in-band registration. In that case,
++ // complain and quit the registration process.
++ let error = this._account.parseError(aStanza);
++ if (error) {
++ this.onError(null, _("connection.error.noRegistrationSupport"));
++ return;
++ }
++
++ // Clear the existing elements from previous registrations.
++ for (let elem in this.nodes)
++ delete this.nodes[elem];
++
++ this._account.reportConnecting(_("connection.gettingRegistration"));
++ let registerStanza = aStanza.getChildrenByNS(Stanza.NS.register)[0];
++ // If we get registration data, show the form, else quit.
++ if (registerStanza.getElement(["x"])) {
++ this.nodes["username"] = this._jid.node;
++ registerStanza.wrappedJSObject = registerStanza;
++ let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"]
++ .getService(Ci.nsIWindowWatcher);
++ let win = ww.openWindow(null, registerWindow, "",
++ "centerscreen,chrome,modal,minimizable=no", registerStanza);
++ } else {
++ this.onError(null, _("connection.error.noRegistrationSupport"));
++ return;
++ }
++
++ // If the user cancelled the form, we should stop the registration.
++ if (this.nodes["cancel"]) {
++ this.onError(null, _("connection.error.registrationCancel"));
++ return;
++ }
++
++ let xml = '<?xml version="1.0"?>';
++ let fieldNodes = [];
++ for (let key in this.nodes) {
++ let node = Stanza.node("field", null, {"var": key});
++ let childNode = Stanza.node("value");
++ childNode.addText(this.nodes[key]);
++ node.addChild(childNode);
++ fieldNodes.push(node);
++ }
++ let registerResponse = Stanza.iq("set", null, this._domain,
++ Stanza.node("query", Stanza.NS.register, null,
++ Stanza.node("x", Stanza.NS.xdata,
++ {"type": "submit"}, fieldNodes)));
++ this.sendStanza(registerResponse);
++ this.onXmppStanza = this.stanzaListeners.onRegisterResponse;
++ },
+ startTLS: function(aStanza) {
+ if (aStanza.localName != "proceed") {
+ this._networkError(_("connection.error.failedToStartTLS"));
+@@ -283,6 +349,18 @@ XMPPSession.prototype = {
+ this.onXmppStanza = this.stanzaListeners.startAuth;
+ },
+ startAuth: function(aStanza) {
++ // If the user has requested for a new account, we try to perform
++ // in-band registration first (if the server supports it) and then
++ // we authenticate.
++ if (this._account.getBool("register")) {
++ this._account.reportConnecting(_("connection.registering"));
++ let register = Stanza.iq("get", null, null,
++ Stanza.node("query", Stanza.NS.register));
++ this.sendStanza(register);
++ this.onXmppStanza = this.stanzaListeners.startRegister;
++ return;
++ }
++
+ if (aStanza.localName != "features") {
+ this.ERROR("Unexpected stanza " + aStanza.localName + ", expected 'features'");
+ this._networkError(_("connection.error.incorrectResponse"));
+diff --git a/im/content/accountWizard.js b/im/content/accountWizard.js
+index ed3b8f0..7c26d0d 100644
+--- a/im/content/accountWizard.js
++++ b/im/content/accountWizard.js
+@@ -119,6 +119,12 @@ var accountWizard = {
+ return;
+ }
+
++ if (this.proto.id == "prpl-jabber") {
++ document.getElementById("registerXMPP").hidden = false;
++ } else {
++ document.getElementById("registerXMPP").hidden = true;
++ }
++
+ let bundle = document.getElementById("accountsBundle");
+ let usernameInfo;
+ let emptyText = this.proto.usernameEmptyText;
+@@ -424,6 +430,8 @@ var accountWizard = {
+ acc.alias = this.alias;
+ //FIXME: newMailNotification
+
++ acc.setBool("register", document.getElementById("registerXMPP").checked);
++
+ for (let i = 0; i < this.prefs.length; ++i) {
+ let option = this.prefs[i];
+ let opt = option.opt;
+diff --git a/im/content/accountWizard.xul b/im/content/accountWizard.xul
+index 9eb5352..759f42b 100644
+--- a/im/content/accountWizard.xul
++++ b/im/content/accountWizard.xul
+@@ -65,6 +65,7 @@
+ <vbox id="userNameBox"/>
+ <separator/>
+ <description id="duplicateAccount" hidden="true">&accountUsernameDuplicate.label;</description>
++ <checkbox id="registerXMPP" label="®isterXMPP.label;" hidden="true" />
+ </wizardpage>
+
+ <wizardpage id="accountpassword" pageid="accountpassword" next="accountadvanced"
+diff --git a/im/content/jar.mn b/im/content/jar.mn
+index 98d9a09..20ea9dc 100644
+--- a/im/content/jar.mn
++++ b/im/content/jar.mn
+@@ -61,6 +61,8 @@ instantbird.jar:
+ * content/instantbird/viewlog.xul
+ content/instantbird/viewlog.js
+ content/instantbird/viewlog.css
++ content/instantbird/xmppRegister.xul
++ content/instantbird/xmppRegister.js
+ #ifdef XP_MACOSX
+ * content/instantbird/hiddenWindow.xul
+ content/instantbird/menus-mac.xul
+diff --git a/im/content/xmppRegister.js b/im/content/xmppRegister.js
+new file mode 100644
+index 0000000..52852f0
+--- /dev/null
++++ b/im/content/xmppRegister.js
+@@ -0,0 +1,142 @@
++const { interfaces: Ci, utils: Cu, classes: Cc } = Components;
++
++Cu.import("resource:///modules/imXPCOMUtils.jsm");
++Cu.import("resource:///modules/xmpp-session.jsm");
++
++XPCOMUtils.defineLazyGetter(this, "_", function()
++ l10nHelper("chrome://branding/locale/brand.properties")
++);
++
++let registerAccount = {
++ createElement: function(aType, aID, aValue) {
++ let element = document.createElement(aType);
++ if (aID)
++ element.setAttribute("id", aID);
++ if (aValue)
++ element.setAttribute("value", aValue);
++ return element;
++ },
++
++ createRow: function() {
++ let row = document.createElement("row");
++ row.setAttribute("align", "baseline");
++ return row;
++ },
++
++ onLoad: function() {
++ document.documentElement.getButton("accept").disabled = true;
++
++ this.rows = document.getElementById("register-rows");
++ this.groupbox = document.getElementById("register-groupbox");
++
++ this.nodes = XMPPSession.prototype.nodes;
++ this.registerStanza = window.arguments[0].wrappedJSObject;
++ this.dataStanza = this.registerStanza.getElement(["x"]);
++
++ let instructions = this.dataStanza.getElement(["instructions"]);
++ if (instructions) {
++ let instructionLabel = this.createElement("caption");
++ instructionLabel.setAttribute("label", instructions.innerText);
++ this.groupbox.appendChild(instructionLabel);
++ }
++
++ let title = this.dataStanza.getElement(["title"]);
++ if (title)
++ document.title = title.innerText;
++ else
++ document.title = _("brandShortName");
++
++ for each (let ele in this.dataStanza.getElements(["field"])) {
++ let attrib = ele.attributes;
++ let fieldType = attrib["type"];
++ switch (fieldType) {
++
++ case "text-single":
++ case "text-private":
++ let textRow = this.createRow();
++ let textLabel = this.createElement("label", null,
++ ele.getElement(["required"]) ?
++ attrib["label"] + " *" : attrib["label"]);
++
++ let textBox = this.createElement("textbox", attrib["var"],
++ ele.getElement(["value"]) ?
++ ele.getElement(["value"]).innerText : "");
++
++ if (attrib["var"] == "username")
++ textBox.setAttribute("value", this.nodes["username"]);
++ if (attrib["var"] == "url")
++ textBox.setAttribute("readonly", "true");
++
++ if (fieldType == "text-private") {
++ textBox.setAttribute("type", "password");
++ textBox.setAttribute("oninput", "onInput(this);");
++ }
++
++ textRow.appendChild(textLabel);
++ textRow.appendChild(textBox);
++ this.rows.appendChild(textRow);
++ break;
++
++ case "fixed":
++ let fixedRow = this.createRow();
++ let fixedLabel = this.createElement("label", null, ele.getElement(["value"]).innerText);
++ fixedRow.appendChild(fixedLabel);
++ this.rows.appendChild(fixedRow);
++ break;
++ }
++ }
++
++ // Some forms have an OCR field. In that case, show the OCR image
++ // and provide input for the same.
++ let ocr = this.dataStanza.getElements(["field"]).find(e => e.attributes["var"] == "ocr");
++ if (ocr) {
++ let ocrRow = this.createRow();
++
++ let ocrImage = this.createElement("image");
++ ocrImage.setAttribute("src", "data:image/png;base64," + this.registerStanza.getElement(["data"]).innerText);
++
++ // OCR will always be a required entry.
++ let ocrLabel = this.createElement("label", null, ocr.attributes["label"] + " *");
++ let ocrInput = this.createElement("textbox", ocr.attributes["var"], null);
++
++ ocrRow.appendChild(ocrLabel);
++ this.rows.appendChild(ocrRow);
++
++ let ocrBox = document.createElement("hbox");
++ ocrBox.setAttribute("flex", "1");
++ let spacer = document.createElement("spacer");
++ spacer.setAttribute("flex", "1");
++
++ ocrBox.appendChild(ocrImage);
++ ocrBox.appendChild(spacer);
++ ocrBox.appendChild(ocrInput);
++ this.groupbox.appendChild(ocrBox);
++ }
++ // Set focus on the password field.
++ if (document.getElementById("password")) {
++ document.getElementById("password").focus();
++ }
++ },
++
++ onSave: function() {
++ for each (let elements in this.dataStanza.getElements(["field"])) {
++ if (elements.attributes["var"] != undefined) {
++ let variable = elements.attributes["var"];
++ if (document.getElementById(variable))
++ this.nodes[variable] = document.getElementById(variable).value;
++ else
++ this.nodes[variable] = elements.getElement(["value"]).innerText;
++ }
++ }
++ delete this.nodes["cancel"];
++ },
++
++ onCancel: function() {
++ // The form was cancelled so we quit the registration.
++ this.nodes["cancel"] = true;
++ },
++};
++
++function onInput(e) {
++ document.documentElement.getButton("accept").disabled = !e.value;
++}
+diff --git a/im/content/xmppRegister.xul b/im/content/xmppRegister.xul
+new file mode 100644
+index 0000000..e2bd367
+--- /dev/null
++++ b/im/content/xmppRegister.xul
+@@ -0,0 +1,27 @@
++<?xml version="1.0" ?>
++<?xml-stylesheet href="chrome://global/skin/" type="text/css" ?>
++
++<dialog
++ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
++ id="registerDialog"
++ onload="registerAccount.onLoad()"
++ buttons="accept,cancel"
++ ondialogaccept="return registerAccount.onSave()"
++ ondialogcancel="registerAccount.onCancel()">
++
++ <script type="application/javascript" src="chrome://instantbird/content/xmppRegister.js" />
++
++ <groupbox id="register-groupbox" flex="1">
++
++ <grid flex="1">
++ <columns>
++ <column flex="1" />
++ </columns>
++
++ <rows id="register-rows" />
++
++ </grid>
++
++ </groupbox>
++
++</dialog>
+diff --git a/im/locales/en-US/chrome/instantbird/accountWizard.dtd b/im/locales/en-US/chrome/instantbird/accountWizard.dtd
+index 43d0f19..c46fb2f 100644
+--- a/im/locales/en-US/chrome/instantbird/accountWizard.dtd
++++ b/im/locales/en-US/chrome/instantbird/accountWizard.dtd
+@@ -31,3 +31,5 @@
+ <!ENTITY accountSummaryTitle.label "Summary">
+ <!ENTITY accountSummaryInfo.label "A summary of the information you entered is displayed below. Please check it before the account is created.">
+ <!ENTITY accountSummary.connectAutomatically.label "Connect this account automatically.">
++
++<!ENTITY registerXMPP.label "Create this new account on the server">
+--
+2.10.1
+
diff --git a/projects/instantbird/0010-Remove-search-from-UI.patch b/projects/instantbird/0010-Remove-search-from-UI.patch
new file mode 100644
index 0000000..434ab0f
--- /dev/null
+++ b/projects/instantbird/0010-Remove-search-from-UI.patch
@@ -0,0 +1,64 @@
+From 43116629bf42352a656ae1b77b2774d2898b1905 Mon Sep 17 00:00:00 2001
+From: Sukhbir Singh <sukhbir(a)torproject.org>
+Date: Mon, 10 Oct 2016 18:47:48 -0700
+Subject: [PATCH 10/20] Remove search from UI
+
+---
+ im/content/nsContextMenu.js | 18 +-----------------
+ im/content/preferences/advanced.xul | 11 -----------
+ 2 files changed, 1 insertion(+), 28 deletions(-)
+
+diff --git a/im/content/nsContextMenu.js b/im/content/nsContextMenu.js
+index 5261b79..f667793 100644
+--- a/im/content/nsContextMenu.js
++++ b/im/content/nsContextMenu.js
+@@ -468,23 +468,7 @@ nsContextMenu.prototype = {
+ if (selectedText.length > 15)
+ selectedText = selectedText.substr(0,15) + this.ellipsis;
+
+- var engine = Services.search.defaultEngine;
+- if (!engine)
+- return false;
+-
+- // format "Search <engine> for <selection>" string to show in menu
+- var bundle = document.getElementById("bundle_instantbird");
+- var menuLabel = bundle.getFormattedString("contextMenuSearchText",
+- [engine.name,
+- selectedText]);
+- document.getElementById("context-searchselect").label = menuLabel;
+- document.getElementById("context-searchselect").accessKey =
+- bundle.getString("contextMenuSearchText.accesskey");
+- menuLabel = bundle.getFormattedString("contextMenuSearchWith",
+- [selectedText]);
+- document.getElementById("context-searchselect-with").label = menuLabel;
+-
+- return true;
++ return false;
+ },
+
+ // Returns true if anything is selected.
+diff --git a/im/content/preferences/advanced.xul b/im/content/preferences/advanced.xul
+index fad67c1..cfe2405 100644
+--- a/im/content/preferences/advanced.xul
++++ b/im/content/preferences/advanced.xul
+@@ -143,17 +143,6 @@
+ preference="layout.spellcheckDefault"/>
+ </groupbox>
+
+- <!-- Search engines -->
+- <groupbox id="searchEnginesGroup" orient="horizontal" align="center">
+- <caption label="&searchEnginesGroup.label;"/>
+-
+- <description control="manageSearchEnginesButton"
+- flex="1">&searchEnginesDesc.label;</description>
+- <button id="manageSearchEnginesButton" label="&searchEngines.label;"
+- accesskey="&searchEngines.accesskey;"
+- oncommand="gAdvancedPane.showSearchEngineManager();"/>
+- </groupbox>
+-
+ <!-- Advanced Configuration -->
+ <groupbox>
+ <caption label="&configEditDesc.label;"/>
+--
+2.10.1
+
diff --git a/projects/instantbird/0011-Add-Tor-Messenger-branding.patch b/projects/instantbird/0011-Add-Tor-Messenger-branding.patch
new file mode 100644
index 0000000..1ec97fa
--- /dev/null
+++ b/projects/instantbird/0011-Add-Tor-Messenger-branding.patch
@@ -0,0 +1,5133 @@
+From 321249d5df13876ec3eca14d764e05d11ba5f353 Mon Sep 17 00:00:00 2001
+From: Sukhbir Singh <sukhbir(a)torproject.org>
+Date: Mon, 10 Oct 2016 18:56:27 -0700
+Subject: [PATCH 11/20] Add Tor Messenger branding
+
+---
+ im/app/macbuild/Contents/Info.plist.in | 2 +-
+ im/branding/messenger/Makefile.in | 49 ++
+ im/branding/messenger/background.png | Bin 0 -> 1143 bytes
+ im/branding/messenger/branding.nsi | 13 +
+ im/branding/messenger/configure.sh | 5 +
+ im/branding/messenger/content/about-credits.png | Bin 0 -> 15182 bytes
+ im/branding/messenger/content/about-footer.png | Bin 0 -> 764 bytes
+ im/branding/messenger/content/about-logo.png | Bin 0 -> 6681 bytes
+ im/branding/messenger/content/about-logo(a)2x.png | Bin 0 -> 13886 bytes
+ im/branding/messenger/content/about-wordmark.png | Bin 0 -> 3754 bytes
+ im/branding/messenger/content/about.png | Bin 0 -> 9880 bytes
+ im/branding/messenger/content/aboutDialog.css | 48 ++
+ im/branding/messenger/content/icon64.png | Bin 0 -> 6661 bytes
+ im/branding/messenger/default16.png | Bin 0 -> 932 bytes
+ im/branding/messenger/disk.icns | Bin 0 -> 43113 bytes
+ im/branding/messenger/dsstore | Bin 0 -> 12292 bytes
+ im/branding/messenger/gtk/blistWindow.png | Bin 0 -> 1003 bytes
+ im/branding/messenger/gtk/blistWindow16.png | Bin 0 -> 576 bytes
+ im/branding/messenger/gtk/blistWindow48.png | Bin 0 -> 2089 bytes
+ im/branding/messenger/gtk/convWindow.png | Bin 0 -> 1126 bytes
+ im/branding/messenger/gtk/convWindow16.png | Bin 0 -> 637 bytes
+ im/branding/messenger/gtk/convWindow48.png | Bin 0 -> 1563 bytes
+ im/branding/messenger/gtk/default.png | Bin 0 -> 867 bytes
+ im/branding/messenger/gtk/default16.png | Bin 0 -> 520 bytes
+ im/branding/messenger/gtk/default48.png | Bin 0 -> 1178 bytes
+ im/branding/messenger/instantbird.icns | Bin 0 -> 21624 bytes
+ im/branding/messenger/instantbird.ico | Bin 0 -> 7262 bytes
+ im/branding/messenger/jar.mn | 14 +
+ im/branding/messenger/locales/en-US/brand.dtd | 10 +
+ .../messenger/locales/en-US/brand.properties | 7 +
+ im/branding/messenger/locales/jar.mn | 10 +
+ im/branding/messenger/locales/moz.build | 8 +
+ im/branding/messenger/moz.build | 8 +
+ im/branding/messenger/mozicon128.png | Bin 0 -> 16878 bytes
+ im/branding/messenger/mozicon16.xpm | 193 +++++++
+ im/branding/messenger/mozicon50.xpm | 314 +++++++++++
+ im/branding/messenger/windows/blistWindow.ico | Bin 0 -> 9662 bytes
+ im/branding/messenger/windows/convWindow.ico | Bin 0 -> 10058 bytes
+ im/branding/messenger/windows/default.ico | Bin 0 -> 7262 bytes
+ im/branding/messenger/wizHeader.bmp | Bin 0 -> 25818 bytes
+ im/branding/messenger/wizHeaderRTL.bmp | Bin 0 -> 25818 bytes
+ im/branding/messenger/wizWatermark.bmp | Bin 0 -> 154542 bytes
+ im/content/aboutDialog-appUpdater.js | 576 +++++++++++++++++++++
+ im/content/aboutDialog.css | 105 ++--
+ im/content/aboutDialog.js | 79 +++
+ im/content/aboutDialog.xul | 257 +++++----
+ im/content/browserMountPoints.inc | 12 +
+ im/content/jar.mn | 3 +-
+ .../en-US/chrome/instantbird/aboutDialog.dtd | 139 ++++-
+ im/locales/en-US/updater/updater.ini | 2 +-
+ 50 files changed, 1694 insertions(+), 160 deletions(-)
+ create mode 100644 im/branding/messenger/Makefile.in
+ create mode 100644 im/branding/messenger/background.png
+ create mode 100755 im/branding/messenger/branding.nsi
+ create mode 100644 im/branding/messenger/configure.sh
+ create mode 100755 im/branding/messenger/content/about-credits.png
+ create mode 100644 im/branding/messenger/content/about-footer.png
+ create mode 100644 im/branding/messenger/content/about-logo.png
+ create mode 100644 im/branding/messenger/content/about-logo(a)2x.png
+ create mode 100644 im/branding/messenger/content/about-wordmark.png
+ create mode 100644 im/branding/messenger/content/about.png
+ create mode 100644 im/branding/messenger/content/aboutDialog.css
+ create mode 100644 im/branding/messenger/content/icon64.png
+ create mode 100644 im/branding/messenger/default16.png
+ create mode 100644 im/branding/messenger/disk.icns
+ create mode 100755 im/branding/messenger/dsstore
+ create mode 100644 im/branding/messenger/gtk/blistWindow.png
+ create mode 100644 im/branding/messenger/gtk/blistWindow16.png
+ create mode 100644 im/branding/messenger/gtk/blistWindow48.png
+ create mode 100644 im/branding/messenger/gtk/convWindow.png
+ create mode 100644 im/branding/messenger/gtk/convWindow16.png
+ create mode 100644 im/branding/messenger/gtk/convWindow48.png
+ create mode 100644 im/branding/messenger/gtk/default.png
+ create mode 100644 im/branding/messenger/gtk/default16.png
+ create mode 100644 im/branding/messenger/gtk/default48.png
+ create mode 100644 im/branding/messenger/instantbird.icns
+ create mode 100644 im/branding/messenger/instantbird.ico
+ create mode 100644 im/branding/messenger/jar.mn
+ create mode 100644 im/branding/messenger/locales/en-US/brand.dtd
+ create mode 100644 im/branding/messenger/locales/en-US/brand.properties
+ create mode 100755 im/branding/messenger/locales/jar.mn
+ create mode 100644 im/branding/messenger/locales/moz.build
+ create mode 100644 im/branding/messenger/moz.build
+ create mode 100644 im/branding/messenger/mozicon128.png
+ create mode 100644 im/branding/messenger/mozicon16.xpm
+ create mode 100644 im/branding/messenger/mozicon50.xpm
+ create mode 100644 im/branding/messenger/windows/blistWindow.ico
+ create mode 100644 im/branding/messenger/windows/convWindow.ico
+ create mode 100644 im/branding/messenger/windows/default.ico
+ create mode 100644 im/branding/messenger/wizHeader.bmp
+ create mode 100644 im/branding/messenger/wizHeaderRTL.bmp
+ create mode 100644 im/branding/messenger/wizWatermark.bmp
+ create mode 100644 im/content/aboutDialog-appUpdater.js
+ create mode 100644 im/content/aboutDialog.js
+ create mode 100644 im/content/browserMountPoints.inc
+
+diff --git a/im/app/macbuild/Contents/Info.plist.in b/im/app/macbuild/Contents/Info.plist.in
+index 615e4e6..ac61e61 100644
+--- a/im/app/macbuild/Contents/Info.plist.in
++++ b/im/app/macbuild/Contents/Info.plist.in
+@@ -11,7 +11,7 @@
+ <key>CFBundleIconFile</key>
+ <string>instantbird.icns</string>
+ <key>CFBundleIdentifier</key>
+- <string>org.instantbird</string>
++ <string>org.mozilla.tor messenger</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+diff --git a/im/branding/messenger/Makefile.in b/im/branding/messenger/Makefile.in
+new file mode 100644
+index 0000000..b430956
+--- /dev/null
++++ b/im/branding/messenger/Makefile.in
+@@ -0,0 +1,49 @@
++# This Source Code Form is subject to the terms of the Mozilla Public
++# License, v. 2.0. If a copy of the MPL was not distributed with this
++# file, You can obtain one at http://mozilla.org/MPL/2.0/.
++
++# Branding Makefile for nightlies/unofficial branding
++
++include $(topsrcdir)/config/rules.mk
++
++export::
++ $(NSINSTALL) -D $(DIST)/branding
++ifeq ($(OS_ARCH),WINNT)
++ cp $(srcdir)/instantbird.ico $(DIST)/branding/instantbird.ico
++ cp $(srcdir)/instantbird.ico $(DIST)/branding/app.ico
++ cp $(srcdir)/branding.nsi $(DIST)/branding/branding.nsi
++ cp $(srcdir)/wizHeader.bmp $(DIST)/branding/wizHeader.bmp
++ cp $(srcdir)/wizHeaderRTL.bmp $(DIST)/branding/wizHeaderRTL.bmp
++ cp $(srcdir)/wizWatermark.bmp $(DIST)/branding/wizWatermark.bmp
++endif
++ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
++ cp $(srcdir)/instantbird.icns $(DIST)/branding/instantbird.icns
++ cp $(srcdir)/dsstore $(DIST)/branding/dsstore
++ cp $(srcdir)/background.png $(DIST)/branding/background.png
++ cp $(srcdir)/disk.icns $(DIST)/branding/disk.icns
++# cp $(srcdir)/license.r $(DIST)/branding/license.r
++endif
++ifdef MOZ_WIDGET_GTK
++ cp $(srcdir)/mozicon128.png $(DIST)/branding/mozicon128.png
++ cp $(srcdir)/mozicon16.xpm $(DIST)/branding/mozicon16.xpm
++ cp $(srcdir)/mozicon50.xpm $(DIST)/branding/mozicon50.xpm
++ cp $(srcdir)/default16.png $(DIST)/branding/default16.png
++endif
++
++# Now sort out the branding specific icons
++ifeq ($(OS_ARCH),WINNT)
++ cp $(srcdir)/windows/blistWindow.ico $(DIST)/branding/blistWindow.ico
++ cp $(srcdir)/windows/convWindow.ico $(DIST)/branding/convWindow.ico
++ cp $(srcdir)/windows/default.ico $(DIST)/branding/default.ico
++endif
++ifdef MOZ_WIDGET_GTK
++ cp $(srcdir)/gtk/blistWindow.png $(DIST)/branding/blistWindow.png
++ cp $(srcdir)/gtk/blistWindow16.png $(DIST)/branding/blistWindow16.png
++ cp $(srcdir)/gtk/blistWindow48.png $(DIST)/branding/blistWindow48.png
++ cp $(srcdir)/gtk/convWindow.png $(DIST)/branding/convWindow.png
++ cp $(srcdir)/gtk/convWindow16.png $(DIST)/branding/convWindow16.png
++ cp $(srcdir)/gtk/convWindow48.png $(DIST)/branding/convWindow48.png
++ cp $(srcdir)/gtk/default.png $(DIST)/branding/default.png
++ cp $(srcdir)/gtk/default16.png $(DIST)/branding/default16.png
++ cp $(srcdir)/gtk/default48.png $(DIST)/branding/default48.png
++endif
+diff --git a/im/branding/messenger/background.png b/im/branding/messenger/background.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..e52f31d051010215470ae91fc84a6d29d8645efa
+GIT binary patch
+literal 1143
+zcmeAS@N?(olHy`uVBq!ia0y~yV4MKNIvh+uk)*3dQyCao>^xl@Ln`LHxx&cHz`$`p
+zA^rckS&yY#68IF7*cF^29NIQC@FX%y9%3?TVNK!SJ|Q4BK~YD+nS2RZb^!_u=wWAI
+z`2Qd1T27!B8W#Lte_QYcM=NU%2lovDu?>nk3C<A*fKKL3WRyO{WY#jk5-g*RrBPgr
+nhAgd8IdLJ|3(S81|1&c<eez%YX0_TEAeX_@)z4*}Q$iB}lQ?mb
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/branding.nsi b/im/branding/messenger/branding.nsi
+new file mode 100755
+index 0000000..4683827
+--- /dev/null
++++ b/im/branding/messenger/branding.nsi
+@@ -0,0 +1,13 @@
++# This Source Code Form is subject to the terms of the Mozilla Public
++# License, v. 2.0. If a copy of the MPL was not distributed with this
++# file, You can obtain one at http://mozilla.org/MPL/2.0/.
++
++# NSIS defines for nightly builds.
++
++# BrandFullNameInternal is used for some registry and file system values that
++# should not contain release that may be in the BrandFullName (e.g. Beta 1, etc.)
++!define BrandFullNameInternal "Tor Messenger"
++!define CompanyName "Tor Project"
++!define URLInfoAbout "https://www.torproject.org"
++!define URLUpdateInfo "https://www.torproject.org"
++
+diff --git a/im/branding/messenger/configure.sh b/im/branding/messenger/configure.sh
+new file mode 100644
+index 0000000..7e58051
+--- /dev/null
++++ b/im/branding/messenger/configure.sh
+@@ -0,0 +1,5 @@
++# This Source Code Form is subject to the terms of the Mozilla Public
++# License, v. 2.0. If a copy of the MPL was not distributed with this
++# file, You can obtain one at http://mozilla.org/MPL/2.0/.
++
++MOZ_APP_DISPLAYNAME="Tor Messenger"
+diff --git a/im/branding/messenger/content/about-credits.png b/im/branding/messenger/content/about-credits.png
+new file mode 100755
+index 0000000000000000000000000000000000000000..5df30c77fd5f82a1de8fe54f7ddb00bf48006669
+GIT binary patch
+literal 15182
+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
+QXJ6rz<u&9WG8W<g2ZjpLi~s-t
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/content/about-footer.png b/im/branding/messenger/content/about-footer.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..94d9124a3500e9b495b89a6a20d92085f53444d8
+GIT binary patch
+literal 764
+zcmeAS@N?(olHy`uVBq!ia0y~yVAKJ!jX2nV<g;tfw15;#x}&cn1H<|g=B!;Wfqcml
+z*NBqf{Irtt#G+IN$CUh}R0Yr6#Prml)Wnp^!jq{s3=B+to-U3d6}OW9{Qqx%SVMw!
+zae@dBD}#W8&tgXdF1Ldk5?Txj4Q||P0zte9j0}t>Q3<_GKwcXU1IL1kOxYqmKwb)i
+z14FM^1W<ENlOi(%Q^uA9QedMbfkrK6y#_Y;1VaOZl<o$Qp{&kq3@ifN0>=Gp5KA?H
+za!HMkz_w^ee8FR<LO|kCD=8kZRSSV0K(T58Q+KY31jGhL29^sM+(_=*hGg}M14;6{
+zZD8vHfMIEJ>kyKAb*bfBCea9)#Rnnb$OZCKG;$ENnt}t^2;H-{RAmrhhwK)djzp2b
+z5!x3r8gbZ%5~1E2@c6+QdKX@VenpCEWPhM|5Gf7l1lWK*%i1gliWVGBVPmjhWLYoC
+T<2@aid>K4l{an^LB{Ts5l2O&#
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/content/about-logo.png b/im/branding/messenger/content/about-logo.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..c6e4c49370087bf5bdafb3ff801d77163db29d54
+GIT binary patch
+literal 6681
+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
+QNyY)FD7=-gk+TZ_9|IdT#sB~S
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/content/about-logo(a)2x.png b/im/branding/messenger/content/about-logo(a)2x.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..99d626ef66ac6183e1c348306d7ba30970db7038
+GIT binary patch
+literal 13886
+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
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/content/about-wordmark.png b/im/branding/messenger/content/about-wordmark.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..52923b6cf08acd09bf329142cab8066a8fbe4794
+GIT binary patch
+literal 3754
+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
+R|Mp6NrJ1eiE2K~Ie*nv{{Ivi8
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/content/about.png b/im/branding/messenger/content/about.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..5d7f5797038d8c2727457cc4512401a3404ecc5c
+GIT binary patch
+literal 9880
+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
+H9QywNYWoZa
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/content/aboutDialog.css b/im/branding/messenger/content/aboutDialog.css
+new file mode 100644
+index 0000000..9a3c04e
+--- /dev/null
++++ b/im/branding/messenger/content/aboutDialog.css
+@@ -0,0 +1,48 @@
++/* This Source Code Form is subject to the terms of the Mozilla Public
++ * License, v. 2.0. If a copy of the MPL was not distributed with this
++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
++
++#clientBox {
++ background-color: #F7F7F7;
++ color: #222222;
++}
++
++#leftBox {
++ background-image: url("chrome://branding/content/about-logo.png");
++ background-position: right top;
++ background-repeat: no-repeat;
++ background-size: 180px;
++ /* min-width and min-height create room for the logo */
++ min-width: 210px;
++ min-height: 210px;
++ margin-top: 20px;
++ -moz-margin-start: 30px;
++}
++
++
++@media (min-resolution: 2dppx) {
++ #leftBox {
++ background-image: url("chrome://branding/content/about-logo@2x.png");
++ }
++}
++
++#rightBox {
++ margin-left: 30px;
++ margin-right: 30px;
++}
++
++#updateDeck > hbox > label:not([class="text-link"]) {
++ color: #909090;
++}
++
++#trademark {
++ display: none;
++}
++
++#contributeDesc {
++ display: none;
++}
++
++#communityDesc {
++ display: none;
++}
+diff --git a/im/branding/messenger/content/icon64.png b/im/branding/messenger/content/icon64.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..37a25b24f28233b6812f9e2e03ce73400ef18bfc
+GIT binary patch
+literal 6661
+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
+P00000NkvXXu0mjfAMoz!
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/default16.png b/im/branding/messenger/default16.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..09dcf2a708548e619042d9fdbbc75ed7ad338052
+GIT binary patch
+literal 932
+zcmV;V16%xwP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00004b3#c}2nYxW
+zd<bNS00009a7bBm0002J0002J0UcV#`Tzg`8FWQhbW?9;ba!ELWdL_~cP?peYja~^
+zaAhuUa%Y?FJQ@H110hL7K~y-6jg!w$Ty+%1Ki|iDGehSM^NSfQogzO31zRntqD~c?
+zxG*u0YN8PrlE!KvF)U16;L^muz_?I1E^L~*XhM|6#0K3!Q|b>$DnTS*VJKl*XC5=d
+z49u4|@47Hfy3oX%oaE*#&P~oeM~Mjkca&0QZ*T9^et!G2TiHV88r0Ok3ADAfy%h`w
+zM_kwKTVG#~d!DxmEDj9~b=PXO{^8Td`S9b*ukI8IR}hgpK6uvd>Fevekxr*2olZ-4
+zceel%jYb8K(a})}27?lbL?oF^&WH#~CTRpl%7>hI`TLFwd;XSityaTv9CEoFKA#WU
+zw%Od=L@9;V8l}{JI2>+u9A_7qWK1TxH2oUuiHI$Jzh7dpm;eHZ&*!V}_rtQRPelX+
+z=-Me0Dj(7@{^%ZEp(?vhzV3(C8r!x>rBe9){yOiu?pTLX51GK$n#1$ODhwWnt|%0$
+zuw8<Z{`*|AC4@g<@#ET2Vl63-9gR@UWm#F;xNZUqI~Da_*e|R(P_Bikc?JWm4)@C7
+z0S)Rdv0#jBBFXDxuW;k)cXal*;d*Y+0OtQZFdM33q0I!XFTR879Avv3;+K3o>-4ix
+zv=J0Xi~|<u<|&s;%q{%E%39V^BEra%EtiJd58l`)HgWdN3sjsOi?j0tx}TuQba|||
+zh07POv394(t=$8(2q;CdSe!KgZsvklHoYW0$tvG|@g<q%Rq{n)VBldQjf$UsxJhq&
+z6orQ!i_x4&5Rb<(3}Z@(2udmI^r@5i^L^TGHcDjnAD~*P(BwPhu)#(fL6%nYq#o%+
+z?^p1&rs(9^THU%`k8&s!I&<ckr)P&!yF?G}5)YdgN}-fu`qu`|jla#$Gqa3O470uR
+zJ6~O#p-`wS8~^;ZR4UCaE&ulUH+N#>!aZ0%KbFtJv`mgP26+6`gAAQ}ijUs^gsW56
+znV5J9(`?Y@{Uyp|GGmEEVmg~W_VtO5HU?WY?TvfXyecd63xoqM=SQETxjBSs8hD;~
+z|J6oB<OQwuyM|$$Y{K1$8^%V$l-mK*2q>juO3|dXd+#sm*JcX;?-SDi0000<MNUMn
+GLSTYp0<*CI
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/disk.icns b/im/branding/messenger/disk.icns
+new file mode 100644
+index 0000000000000000000000000000000000000000..327a662f196a293449b0851869ed7699a4ce9ded
+GIT binary patch
+literal 43113
+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
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/dsstore b/im/branding/messenger/dsstore
+new file mode 100755
+index 0000000000000000000000000000000000000000..f5079c58c35136c16e717389f0efb550e14db991
+GIT binary patch
+literal 12292
+zcmeI0O=}cO6o%h65tYQzYa)JJ(7}ZYGTn)|YPc}O5fd&!A;g{FboXS^H#1$sbk8WR
+z2JYtWE(nVHA2eIHV*Y_kb?L(2;6mT}7-x*}19Tze6jOC->YP)3>Z$Ikt_I*O^pbht
+zIDq}kS{|Nau|v{&oxezXT#NSe=noaKc9?&vP9s7H2mv7=1cZPP_}vI_&(>-GSN46Y
+zl~M=@fn7;JuMcHrEvrrrtTamp3v&dZoMf{}tn&b1e9BH%og7$cT-m2RJ$TO5b4Lu%
+zx>H})=9E<@2Uc2lc-9@ByRzp_D4w}G{mRB%jv^L=ltN%f0`}})UTUd0YJGNofB3;9
+z<K@9$`1@+jSxjG#iv?gJ171x~Pwmp>8`mPGTKeha-?iK6+^6m~yoPsgVls`hz6-%v
+z<hNTYYqI6-(5Jtiud6OQIA>eZxT#z(!|xCJX{UD@_lKI3tY5+)Q&}TYMVoq??7CoW
+z3)?TIsbWhfjSJha9)cMNSCgrwEHCO=5vAS4b}=fqHqW;gFJLcQW=c^#-e`7JFH8K6
+z8NkTy2Wzuio5vmxZ8c@!pj*#|t(fvh*U@V#32bdnFH`@AsXu*xmvy^*&Tuh3I~IO8
+z<{OT>G2xbQ3ME9SBgO`r=t7}~3<-R6D4RIMuR&8-Vm(JeyNqRol$HsO;Ll*J^I%)&
+zn89ptL$!MCMjng>gjqX0mi$dG*W)xRRK8wbtbH1=tvpwAFG(7>|Lo4`bTlKCIe*^2
+z=r^*;>Wbg4$9~e*_s+M|gXk|kb4jD$O_F@Wl0H!0<}{h4d0`1ZS7%;OYYAK09%(QZ
+z+<)>v{#$F}*qhhb_wHXno#0q*jSnSU%^Tf3Tx+RrTF=6!O0%_YBaC`!E6Mv=sG@%=
+zV?zq{b;GfS9miNg6{ksmr`f1rj<Yt;e37|9n+jI3!g|}xug@84n;AXHdw<!q>7EMC
+zd5(2%v5Tm2PFGCefeSovfd|9DgKdEaI`H6of%9JQ0^leqmGm91Gt;53+*v-O>!9=b
+zLWG<2cx2Wg>kUu#e}hp9A@H*V^xn;MT)zWc;T|L30Spf*gut#M;7!(6Y6~2)+graF
+zJm1;)t^nL()=Aq9tTZkxw25vvuiccx7k1rNcDkyQ11qUvk`Dm}gA_tQ2nYcoAOwVf
+Z5D)@FKnMr{As_^VfDjM@Lg1GY_y}e49k~Di
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/gtk/blistWindow.png b/im/branding/messenger/gtk/blistWindow.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..093a44c49f8cb3134bd712538e3fd48b4d50ea6e
+GIT binary patch
+literal 1003
+zcmV<H0~Gv;P)<h;3K|Lk000e1NJLTq001BW001Ef1^@s6xF)Gl00009a7bBm000XU
+z000XU0RWnu7ytkO8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?19(Y9
+zK~#9!tXNHG6G0Sylf-D$+MkF*sThA^d$9>xF!<M03Y7|)Lp>?l-aS-`_j>hWdlB{0
+zsz<H%>d7dyf?7@DB{ZlJL!e@sNU7CmS>M~8q`RBl$!?Mdk7YKq^L_KZnfGSGBuN6h
+z_T;^*1s_4(>)6nde+9c^F{=a+G=dNEF#2ATZa>kZ=(9*>x*-G*co-k!0#Fc;nIIP_
+zV@d#lNn)Bs0P3@^=)*`NYV@N+Aa}F@;J}r8!Ii8|fOmX`-VBYkDI*e^5OCQ)=sRVX
+z0Dj~FcD4d|(Koy6A~K?0pk)GlYo*mQ|MCsBdo4ln@5a~eO#nUJ47$5&CP0fbj3i?E
+z5KQR7pTE+AlTmwqL4tP)sa68b9BX3@;Ou?)xT@|&AR<d70sa&#-{*1wiz$FiM)-Lz
+zVp2W<7k@FX{*~grvMQbiDM4#v-yWq+fOqdpu)Ms{r>za(;t+#Cx8V?k87_q&q8Yqs
+zP0L(fDudsi)Pj>y`yP^tCrnlFIk*&>E!VW&8Ub%Blb<y6wKem84<DI^GveU6U1Lq#
+z6c-uohW6dc?DaF(8<C@RVPHXrK~<A&pqB{;J<-GDeDG_{np&xpp$a}C&|>rpC7q!`
+zR-pv72Tn8S+^@8^daM!X=rEj6&?WkaNL-3Ac~_JcCdsZHSXu3&FnEyUA-{1>a9Cka
+zL<m?9UNYKhB0JNkkT5Go1*p?#pI^DmDnO`xZjjuR;7bYt<>U+Mx0Hk^$z+!#S^ivJ
+zy9T_nB1}#~r8N=?A&~&%Sx}N=PO^K%Yox#)FE}H-{K}w-qy*`V_1U-Y0yx~o${Eq7
+zU3c+=2h3sa|CqEtg4<m^Z3`?am*Z=9oU!C5>!%+|LR5}B4=CG|WT$;@lx!#rCgF%<
+zNmjPu;%7K$6`bOK7L!!*H^%L$lIKNfI3<%(l2GWFvLL<Qa`{&dB>iJf$tw8yeg<=M
+zSi)y&J`cdDldv*#Ykh~BK-A@eEx6y0IvAKHr@rG1-oB|1TxFBr=hsK|XF@tOPKmx6
+zyCJT8b_@wHO(x`r#gS^2t&vtCH<3Ukz)T6hzc!%NRanYqA!+AkMCXLr2HX$m6g+Bn
+zS2Qg~{3=C<)th{fTI>OpT+v0<((Rbv8HTx6OIUHP+%y8G8+JW62#@+df;4yA{}KEb
+ZU;usYPgZ|=XGQ=3002ovPDHLkV1h<i#x4K=
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/gtk/blistWindow16.png b/im/branding/messenger/gtk/blistWindow16.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..fe889085c49b13f1f90a31a7adf3f706e4181ec4
+GIT binary patch
+literal 576
+zcmV-G0>Ax<P)<h;3K|Lk000e1NJLTq000mG000pP1^@s6)UPbW00009a7bBm000XU
+z000XU0RWnu7ytkO8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?0nJH7
+zK~#9!gjC-vLva-Ue7RN&ZER6&nIwC$Ny>x#c=JG^=1t;1SYEvP5AcQuc~qm8;>82r
+zC_mPuFlmZqvWcl_)Ymz8*KBvYoI2m{x%ZsUr|<cE@3}%s3B7HcDpuMC$UC%GA$DKq
+zS5#js@(Bp&qHTeE1f}hO+)qTIA_4+WX<!Tfw`n3-%MlQmkGsb&u5N+UyF^31ApetO
+zj7Wkaa8l0wa&MNcU5VJ!Z^dArK(o`3;Fa8^(85QzJinj-%yxb$i9jH*A#r#Fn9abr
+zPr&O@)7+}RjF!>A&bhrKv9}MT(?Bu_EU!o;61ns!6ZCUruK^nB3c>Aef$K;yX(E{m
+zy-I#!uwNj0UnruZ5s2tWY_-2}nV!A65-Qka%03Sd3ADCmW7c4DLcnIr`;h1sLa{i!
+z$6;9{qNxJ#xPdN@Fp}s_IlI8+QAm3A83wnt0GSV=3dvgV37igUoCqBbwJb;kGFl4k
+zb_r~*OH#jZR>I-z&2U@2Jz`bKd}67)L!jP{*_;klz}%cvug=I=*hoaq<j;biw)vle
+z`9*06PQBsbF^(IaQ2jLWOz@C28HuJ%W3c2n>xkH`nn$(&K~P`&Ex-Uq0;zA9+4Nih
+O0000<MNUMnLSTYHI|Xk5
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/gtk/blistWindow48.png b/im/branding/messenger/gtk/blistWindow48.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..3a14f1d68536c0098d47381bc1a5ce329041b481
+GIT binary patch
+literal 2089
+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
+Tj-n}$00000NkvXXu0mjfBt!I9
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/gtk/convWindow.png b/im/branding/messenger/gtk/convWindow.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..b550c92d33106cbb5ce9373ad6380b716dbb199d
+GIT binary patch
+literal 1126
+zcmV-s1eyDZP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800009a7bBm000XU
+z000XU0RWnu7ytkO8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?1M^8l
+zK~#9!v{y}ROi>j6o(@s<Q#1sn6Veiqwi=1SVy2CiSj@sgLa0bcSZIj_3si)Kpc3rR
+zArkQuwP+I}Oc#EN@TR)aK}vsUDASgxYF+2NzW4fO`rf=ZukA@r=FYt{_k8#KeCJ+C
+z2mvQ@>y;;yK7y(ilIA4*q>EH04U<-HDC(D;>?_#;Aj4kzI6}G=smVwF9|5Uy4S<ZZ
+z;lmi2)RC51dBhZe>TY&r0Y*o<R1j6R0LXZuYJ8e;zOxgEGyqLef#1J@XmoIX#tdNQ
+zOdxw6ke4T+AU`RPZHXY_0H`OIjS1F7hH7esZqQEB(}9v=R!JG#fk*_vC-?K1PkHl}
+zz_WUHK4;@QcSy*~H4R5V%LyF-884-e%bM{sl>*W~FE*~*>I%S<*I_(<RfjE`CHQ>9
+z6O#Z0c;GR(zEWEaT@`3;1J)GfVE^_*t^l082nE2++XC6y5^3DBpAXETP&{BfJ;%KA
+ztiWhWE`_0dk2H)Y2!Pk4eks#tBatEF%W?~Gtn9Qaqt|OgxLy-d#+<+$)`X<Y;ffol
+zGM!%U?E0~gmR8g0AbTKS^{2+DjNtAPjG+V=fY)kuO_3jW&OLOQghxp$^zW0*Il=Ey
+zJDV<Cw;Jhu`utJZ$ZZ*F!fcsP1-dYROyh)arKB()OLtE!ZX+w<a!V%b*GZOZp2P{}
+zb-fDm3LJ%C*6K9NHQ!2@5m6ifS)*T#2Q+aSf;8GCV=6G2G(BTze(DrpDK)2WKY*<1
+z)&OG0iD-0)2U<Qi$0d@P;jB5pk|G+LIAMVF<r`LkDFkdqzJ$dK<H^XQw%)^L9^e-1
+z^GQku%MC&&6s6hFhVvHz6EmD8WzR3*(Nlr;4xo6Io)fZ0#rm<2pAd>s?(4>UFy0F~
+zz5>r11&(iji2OzVl&a&({iCRlR%jr$X-OE;?tBLiNJ%$fPz_B2y?=mr?U9trv*UX+
+z-hO}*in+5<t$Bdi@R8F^F5M95`#UlUoSlW1YX=4vC?24$6ebXL#%f3=n(@=S+=bxE
+zy$W>3(4NQx+!0@=ve~^CA;|CRQUVZpH%M&#{pgJYz*i*lLOBi3*lofk#aYcc@P%S(
+zB|m$+@V?FRebQ`oE3UG8gm4mZN!f*<fxNT#f@L=?esF3aJdBFT6Qu+K$v|)hb3LEG
+zyBCuuPD|>6Boa&dG9nOVcHwwQ<it$pQp(8#mE){d$rF4@U9LW@Oogd+Q*e-8Cycj!
+z88O!wi6iLfajJTQd7{)VH@NBa^-*@UiH`0b$gysmBW<OV>Y2E9Uz%5YWz&2>a{4?^
+s025H}5ru|$%4%kZ$$QOC_xmrv00?oW3{)JdtN;K207*qoM6N<$f-q+VE&u=k
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/gtk/convWindow16.png b/im/branding/messenger/gtk/convWindow16.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..b00685591157aa0ae7ed8e5f928ec75d78d67bc1
+GIT binary patch
+literal 637
+zcmV-@0)qXCP)<h;3K|Lk000e1NJLTq000pH000pP1^@s6J8eh$00009a7bBm000XU
+z000XU0RWnu7ytkO8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?0t!h)
+zK~#9!oRrT?8$lGuznjFMr$)q!L~2{CH#Y<imLBxbgIFO7Lg`8Gy$E`gR{wxj{R@ma
+z74?v-P;@I)BUOo1TZ@fG6QhBe#!?B2GQPLYG}(27;Dg7^+su64&xt04fRoIwdwjG6
+zq?zmuUM5jSG&_VY_tP>!s@u+<l8&<yFz*PFo};8~>c?~%sHp*}s&2vh2^6(JB*0+r
+zu^2GFAdo&R-eQQ}47}{rOsJF|1yYc3p@6=zae>zz@5-f))hz?h+85#X|BtAFQ*#lZ
+zfs8)8cPF{H0LCT+$RW!ESvz>tW;u3q@OiMUEF^WD#FzEYNKvhxHkzNf2_vqOHr_`b
+zawZ;SF*&vZ(^IMZ{g=n)PTbrd9POJ$uJ>Dx6d|gO_H?!q8<?J-fVUE;Ankpn!R59M
+z+svAq+Y}mpE0D_pjTF(z3Cw+UEl~FeaN90<E67=khNi~^4PI&<IbfkKngLxeMwH1?
+z6hCyl34L%Z#@yE_9AqL11Ob<XoVK=FCo_{3cUJY=w%9aV%)>$z<~C1SLiTDnE94PR
+zSPQ-J%P`mMpM4zX5La`;d4&no&O@gTbH2IXJ_Mdv3musoEj5i>ub4pHw1nj};+!UQ
+zX-(kguB{syQgp4JwxgfkUyV5Z74T#1mg-aA_fpvYz9Wpup{tK<zZi7$a|sY6dM&^J
+X2WQK{e}VKq00000NkvXXu0mjfp?Mj=
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/gtk/convWindow48.png b/im/branding/messenger/gtk/convWindow48.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..c7591490a3cf3254306b6fc387173ace69428289
+GIT binary patch
+literal 1563
+zcmV+$2ITpPP)<h;3K|Lk000e1NJLTq001!n001!v1^@s6bDTjO00009a7bBm000XU
+z000XU0RWnu7ytkO8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?1*l0x
+zK~#9!)LL(B6J;2GZmT160z**T>|D`I`LveB#EBnP2*v~wY~nB^>NYhoMnB*re$W^<
+z_)1917o#R<H#H#+BAAQ>HPG?_X9ChzKZp}(ZTYL~y0`>0hv)O$y;ttu-d*3jUW-1-
+zo9ngj-95ke`S*L?t0c=Zcr6Ei@P#dY%JlavX1so$R4oWpIDiLII)WpFqf_9r1dce4
+z!w4#Q+d!c5LwKOkSEUYF95EbG1XQdG2&Vj~;EFqyeROZ9V1z+1w~2YM@|9$c0f~AF
+zf~`K?bUD;dj*z>GSfxP#0ImKfbp}B4GzC9CKU9?^7=S^$8_diAOiu&k@-pNvspo})
+zaZXnkKyx!dho3%6@Nk!7_X^u(F-s730B+m>NTmRdpHLNdDg-Fl4ba;w49FIUDF_5W
+z*=NM;g2|&YDz5_ZLdZ(no{_-suQ)ZufD|i&Kmb&<zT_w7^8n+Yx?6b>*|M32R592Q
+zM8p;Z0%#>_zz6Zv6u`tG*|XKRv&yTlNQ%4J$S|LNc@SlBkV*r5_>ns2t(Qk|yyv;{
+zr_LrI^7=;Qv;Tg8cixsN#YaHzRt;P+8{{(&xllcY+;!rh?K77%#!wQU?(--=d;Bw_
+z3!OR}hdukfS3GysNNi6aH4Fy9E_3a`MUQHXSaBz2g^T)GzhLf<?yIjA`1ly!Ve3}A
+z5X7k75<~oqsi|@R+qVqD_RWKyEBw=R3f_$l8@{6gO76UJrR8NB5iNlzOIu_KUOMgz
+z!1{H4b+ZNmu>sLZl!OYPkGWEipTScH&37r2)WQ;`l%_!5VCzz}_(>n@%7o;=<d`!4
+zLlV~9DIj{q6Fq(CPT`tlCzp%Ur-3llii!?TF$h4dik%q<zrP|4Q8KG#KOsQKYAQrM
+z1Q~8XnmE%~G;4T>FHy0(UDEp)z`zTV$kYu!tB#E-X7eE<<?d(;zyod0_XmEvl7-xr
+zj3X;->z9P*`|NH+RWqH|6+0|+Zen83{@pls3C|}BRA91YJ$BZv*wkAFo|lxa&x!b0
+z|IlgH1o8dDfumyz33TI5igjB6mfelVI{_N;$t}xn&H3jh{&p8W6S>^E3lan{u`Fp4
+z2VuG;Vn#d2ubucd2`Rhc9)Pty08LA5T%r+R9vAK01sZBXAt2prC1_u5eI3${IDtsA
+z?GX+{^_huQy**&Byq#q7G-PPM7gNxB36{2$P04DOh?{K+@bRGSPy~bO4h2~%m6DaC
+z8P6i+SG9Q)Czr2dqckbQ)+Z%cwZia|visp9b70jojR(Ere6T6scT1%XaHc@ORqN$`
+zSC?ntsS(ct{#qdeUwt#i1BvUKqQiQZqSYl3PO}8b#T>w~lPZ{R_uljjMEZOJ-h6)}
+zG~EI4Ttw1>ehqbZnh6Xb9PZE=Tg&fc!-Kt&UoWe4ec^B9T4!X~@VJyPw5N<n6`{)g
+zR>~}T5VaDr#!JsiFCvH-U$LWByMDp}c+ChP_>gy9;QU{6aQ;%VWQ`9#moxo6<+Ou9
+zyituc{+u_S?|tpK=P_YLJG7!vWFY=`;^V4cjJ;5C<p)cVHo)~;=bLsm)&)d^Me{x9
+z=4S1yrFt5m#DA=|_Cu_YIF65xzmS!{b5keAzupbw$Al<*3hy1Vvjni08Lr|3^LIV0
+z5EW{QSbS&~2wP-L2f!l_sx@P$MK-ad7PDE=sjd2xif>Qdy4LBm45xprnI(>(J4I~W
+z$;7p2Z^{vecofOu)=j4L*|SYEVM}mU83GsYv&ps6Kg%#P>sZ+=%R*);e;ryQ=@<k9
+z(#nF~adrP=mZ*tJPZk!`KEV*6KKOod5w0@#jcZC`y=i5sKcXY5!}xpD6$lf{M9exv
+z2P;h^E++aHA|0Rrf*7qD1P3V0d^N<fM}XUaNa(sT8gZ}w`}D5>0|2EURzt&&-P8a8
+N002ovPDHLkV1iKg)G7b~
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/gtk/default.png b/im/branding/messenger/gtk/default.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..fae92d073092cf16936d9917e8ddefbb92c223d7
+GIT binary patch
+literal 867
+zcmV-p1DyPcP)<h;3K|Lk000e1NJLTq001BW000;W1^@s6n^XTZ00009a7bBm000XU
+z000XU0RWnu7ytkO8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?0`N&h
+zK~#9!tX4~F6HyfYZr*)qlSairODJNyu(7Bcb<qfl;38z<&V_X$xU=23cH!Rm3(Qt3
+zlDZa*xF`rptG2W#O*9$}YSUC|lbAT3o0$nWGk5Z84jks@GL!E+@52;DK|AvJjU!AC
+zU580e8eS=oE(@BtdaAPB>VH`?0t6bQ$6eAW=|OZZFG%A=B;FAL0_GORNUx(e@`-eo
+zh$LGQAaHJNTxM~p4E)Li*_?vXUpjB8_bwOU_X0zM3?p9kY#|Sb#GEAo0-vSFL*rK)
+zn?Nd~ApNC1bB6|i;3yE9WVN#-EKxl_>I7uq*&OhENx|>k?tOn|iZsNG*Na3TS|^|-
+z+p_3(ZZ!wDl4=Fm`=g%icA#&-ngkC^<RXLH)o?veBw{*&xR`KO;N=pK%K*DO>e(m<
+zd}INs_fT6Tc-aQ+CnEQPqU*W4pFT5#XVbvv4?vNuu2$uimiB-hO3VT!YX2bM6fE8=
+z(s%!Wu|Pc>9@3mmYb<qnyKV;0d<1@eYd`KqGGcR;Kn=O`Ze6V;L86>M(3p6l<bSBz
+zsc<iGuNj4xu^=<H7B8T%)qMr<Trq_**XUuJtcH!*-b)$rvgQN=M|uY)s|LTX;pYk`
+z(9oYJ##v9mJ><ziu<>qU+~nb;O&bse(F0SH-2=Pa!00jHc!(O5L%4SW=T4i9i|MZ<
+z#71<UUM!cDT0^pOE$@6{ez>TrJ^k{I$iX9*Or4MqrnF8VX&k*5&Z?6wwWdg|^dD`{
+zBZ0%f<rx$BineD!ClHo>9HLN+-C<aGqF{|0OR3mdIC$%oBsB*Q>(j6)0WQNdo^IYy
+zW4H7Qc)zN^NgnVC8D85B@)GOK;EUQ~QeV~B!fQLv)zp46o_9~#{J3?EiGycOwwl?R
+zSYObVhr&Krv3cI^t@c8Pws4A|32mcISZu`8%@$N@G~0b{Y%qpL^dI+IZp9RWv{nTT
+tplz(_)7pBDuisI<eWmiU8yEc-U;wC;5=tFXE+zl~002ovPDHLkV1f~Ki825H
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/gtk/default16.png b/im/branding/messenger/gtk/default16.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..b436a77b5256d665852dac863b0925d615fb5dbc
+GIT binary patch
+literal 520
+zcmV+j0{8uiP)<h;3K|Lk000e1NJLTq000mG000aK1^@s6Yv(<I00009a7bBm000XU
+z000XU0RWnu7ytkO8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?0hLKa
+zK~#9!d{RwILQxPsH|=Sul~D=Ohg4v+kO()m(N=9+w9lX5PpE%T|Dd+j!rB&8V79R+
+zp@k4q6oRElnS?LpHS@05_k`-eyqSCNoHOsvTwxdn6b^5kL*x=<Yh*EW<Bsf{Y<qpN
+z`KUI95+HJt+$PyzLkB8VpiHLg27&<rpBM0XI$}E{lI#c&d6(jiS{=yd4CD*=6~QrJ
+zIVv#XH<uSA5*G*8jyNsOxZ3fF0sR|jHG%3I@cAKQ?*QN@vgVRPD@y|5X*1k%(#QOj
+zOjeS==r0QQL~L1=>m*cq0VZZiXcV}l+|amyOGBcE&be_YzRKjMd^g#S=LhMz5ch~M
+z)uRrz-u7Vwf5PFgVoj5t1<a8|=I}50{(J@1Ow~y4L5e33jR@50269(2$xR~*hOEkc
+z9*evh6G}J90wJ~H?goZ|bjCorBD-$~cb;<y?@XpK-m*a4o-`k3>r_CoMB_b`kFEWX
+zj@o4N>PldbuR@zCdQ_qI9{UBi3;i>b(7YbxXgd3pleQQ95nuq_*Ms-&nRs~s0000<
+KMNUMnLSTa0qT@~g
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/gtk/default48.png b/im/branding/messenger/gtk/default48.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..8381428f20e3bdfd3cdedfa63efa369c0eeb4b80
+GIT binary patch
+literal 1178
+zcmV;L1ZDe)P)<h;3K|Lk000e1NJLTq001xm001Ni1^@s6&qcWk00009a7bBm000XU
+z000XU0RWnu7ytkO8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?1Sd&E
+zK~#9!)LBhW6JZdZ-9iER5<f5!kPl5DD$pPo^#C4BJeeN6)4$-=i}(-V4=8#tCYlI%
+zglLITE`WuI0S!<^Fg1cuAe8d4&UD`mrTfly`>`cXGTC%@yF1U!GxN^8t7w`AnaHb&
+zypwqFpmvHQ{jNi;mE1lejsesls{dZwULceAE9n40qsc%ost>glGLv=Geo_R}?<fE?
+zoV?tP+5yf8f$2l-K`_Cr0my;jGU=svB9OJT0SJEgpmxFW2t~waMJ*Np8t)O@tWEZo
+zjV*vbs{kv1HCPVm=azpTy~mvoaHax}Zv9wwPC>N|<SByi*#>~d`-JDqxhL*K0cPh(
+zH8ebZ7uQt-)YmA`*pT$rNvd>-lrjMj#y_z#{NuP5Gd`PAS`5(Mk`#yu#1R03Hh#|Y
+zQ!@Z#QyN5fog+N~xpm!=UIPfgYXTq=HX!3XdHvm}2Em`X%ibH;6liH;FW*NHJ&6FQ
+zOg@wuKR9fU=lgpAVZ1LI0oV*5z2?dTC^`X9jIk{#vj>9cMA2ZXlZV!d7yz-dF39d2
+z9MVh`B~i%O&?3NA*q&i77eGZNR-^M+l?tryB>+rb#43|2e)u@fTNxkS0hpTxn4h+9
+zd@NG?SayE_%uMLOt%RscWm+O#M0*whQHK(ilWlzHx5?BDmq`fo>g$wFKTbZ3v37V>
+zK_64%Qo?f8hKwh#lP9ww5qw^7mcLH6Fj4TTqV+Y&!Xoee#kuSmZwN(_XvK-K!Y8hS
+zD$DOEpRkcFXG*6PfQ?P5LtE99J+<y!?WdxUs;Kav3k#sMB=^P?7W3CmS4bDM5mn5l
+zk}grnIe@A<`FU!^ncgU<iqXx)?D`tLvC5UyT;f}d#)|+2Zt10dgF=388FyN!m1wwv
+zt;Jd1`|Zv0euySD1Aug7qp&qMImdVMdQ+Qqb9bjh;k+N~M)TqTNGGtH*w#j)_6Hd9
+zBz2zKlC^>ibr)hsT9&+tGZ?^d|GNPoX*(U?*wG|L%~!}`E+9JCZI@YEA#Lv7R${X=
+zhYjiDkB<O|9W_>HxS&D&@iWcQoS@d3h8c!7#xUcTO=JPPyKJxD0E}XryBW@21ga|a
+znK;Q#g=u%f7--1*Deo<O{sQpUufYQ5$4(?O0PW2>01J79#&;*4G$_=WPPngLCe>g1
+z1M^~O8G-C-kdKMFvYIeo>_WQRFP58I1^{oS+`Uk(D+ZNqhiSG>Q3izZ?Dk?t5pYmw
+z8@@X}Sy=$wL?#I%g>X%PZOyjD2O3Z_{Q|Ymj^XhU=uBd?Y2QBX`vCpdW5WSb$<K#_
+zQ{}LPC39$X4SMlCQ>i{fc{%RtgTvkDv_3W@e5C<6{8AI21KOu)tq2#Xh^oTy`UZ?V
+sf3W{P)5sBkfY^~s>kG+o%Rd1I0QP0BQ%`-CG5`Po07*qoM6N<$g47Tg^Z)<=
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/instantbird.icns b/im/branding/messenger/instantbird.icns
+new file mode 100644
+index 0000000000000000000000000000000000000000..0843171076ce097029359a04103f98c0f74bc4d6
+GIT binary patch
+literal 21624
+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
+G;Qs)bIk@Kl
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/instantbird.ico b/im/branding/messenger/instantbird.ico
+new file mode 100644
+index 0000000000000000000000000000000000000000..51fed13f752340320417fa83145ad7896b2af839
+GIT binary patch
+literal 7262
+zcmds6O=}ZD7+z-&JvJ9buwq0J1<@dgC>A3MRs<=6f`SsMs92C7NH3Ny_<{IE6hRQw
+zf_m~2FP;P!FM1L36N0}W#~#%2c{VfYY%;Txq?>}KJb7nlciwrPci#EfCJ5Hxue3G5
+zcQKfn2!eG%5NroZz!boG*C+h(p#dxc(^AUdUxVT<VTqQy9!Lw?6o4`iDb!)(6h1xu
+zA|6)0i`wN_JiB^J+&w#)N376C1<?FW>(qkhi$E11&n95DvzI?TmEy*cH0Gv$i+ksO
+ziboe;i6=9=hS7t*$;IC1a=q44!?TS(p6~T%<8SJDeRBzZ7lHDiI?$%S7%uDS<>$NS
+z<Ns#P^cfGLL+Li#=U*O-zwV#;S@4Yqo|y)8o8j!o$1;3zLyBj!QoO86asPZ8x6h<=
+z-^?AB)A2Vsw8$?@12qoC|LuYlGm}yro{(by+BPoj%jVh5TVK2RYb}vSL!)mE(K#uO
+zZC>WAxzi5IALA7w$2=SsT^i7?=4mU#&o897u-DF8YZ#Wl9*5`GWcck}mX4}T1Gq<-
+z{NK;F^WyZ*(ekH`x#LN!GWev{SUku4Z@Hcqh)HMf@$o;oO^Q=HkYB}Ku<iLhQp{q`
+z=y+$?@WUO~IB>o1tV<|YoZPvVn0@&8>pb$=qZ`{=Oy8Dr#+>NPXK=4u`P<g)y!dN<
+z<qg?$p1EY74=p_pz}=cVVtzUud&Vbk{#pm~$`b#i4mn_rZ+qV=TJO~#*!_))KXtg)
+zF83HLf_vG<KQ(8~xQvoN=Y-jpQ4SGL3(wfepZmYjzEd70e~y8zPu98jXM6nrSN_aV
+zJ?HYaT#NFG|C1TFFXn09-0AP^ZfBp4y{v)!FIwh><nzv0Tsa`c!S(rS;C}6jJ?g`+
+zuWj?U&OHG9n>`w^XYd^2^qHpyj_38VyD#KI55M;NN=5OHtoQYq%@r4(V;HxU<Pz62
+zmw#37h&?qWXCPR64nbq`9_8_$>^p<#VD9mZ*T*@|k@w`DdKbX8eGHgKzIQ*Zk2%0|
+z0At#H{yedzUGLgswGY$sUBLcc%kxfApMO*i6;RhZ57?d>veqNB&z#C3a@WC~^;MI*
+zE~CB#P@BCi=R?+<&VxJ7j2UNU@=Dem&AHp+e#OaOkA?X@lLu$|AaD2kijHRk+>$xl
+z&D*?I8r<Wcba0IOo*OQmTpRto$-gh|S_hsl0rvUOonPErc;3bttMh-KZobSro~byG
+zcoy^juR+J0HnrAhjy{Wa1-1oDU#nSW4ov%a`tHL=8HiU|M-BaXbKS??yuS)M7;o}U
+zt?ed<Jj(PBRDlMt(tILk=IDy^WEgGew*WA|BA^b$KohX(;yt1URDsekeVT0!;Q~j{
+zU`#g0Xrn(taEKN^n2jqNDjUGY{2^^Y*-grhciAy@9V)w~?GHc1C4M^=t|I!wCrZBi
+xw1%IU?Qoq~^w;Dy`fn+_L<@euXu%iqATXem<V(hAjthwfW3)=YlyS&-`~^IDi|7CV
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/jar.mn b/im/branding/messenger/jar.mn
+new file mode 100644
+index 0000000..929e7c9
+--- /dev/null
++++ b/im/branding/messenger/jar.mn
+@@ -0,0 +1,14 @@
++# This Source Code Form is subject to the terms of the Mozilla Public
++# License, v. 2.0. If a copy of the MPL was not distributed with this
++# file, You can obtain one at http://mozilla.org/MPL/2.0/.
++
++instantbird.jar:
++% content branding %content/branding/
++ content/branding/about-credits.png (content/about-credits.png)
++ content/branding/about-footer.png (content/about-footer.png)
++ content/branding/about.png (content/about.png)
++ content/branding/icon64.png (content/icon64.png)
++ content/branding/aboutDialog.css (content/aboutDialog.css)
++ content/branding/about-logo.png (content/about-logo.png)
++ content/branding/about-logo(a)2x.png (content/about-logo(a)2x.png)
++ content/branding/about-wordmark.png (content/about-wordmark.png)
+diff --git a/im/branding/messenger/locales/en-US/brand.dtd b/im/branding/messenger/locales/en-US/brand.dtd
+new file mode 100644
+index 0000000..4dc69f2
+--- /dev/null
++++ b/im/branding/messenger/locales/en-US/brand.dtd
+@@ -0,0 +1,10 @@
++<!-- This Source Code Form is subject to the terms of the Mozilla Public
++ - License, v. 2.0. If a copy of the MPL was not distributed with this
++ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
++
++<!-- nightly branding -->
++
++<!ENTITY brandShortName "Tor Messenger">
++<!ENTITY brandFullName "Tor Messenger - Beta">
++<!ENTITY brandMotto "'Cause geeks can also do magic!">
++<!ENTITY vendorShortName "Tor Project">
+diff --git a/im/branding/messenger/locales/en-US/brand.properties b/im/branding/messenger/locales/en-US/brand.properties
+new file mode 100644
+index 0000000..c09000f
+--- /dev/null
++++ b/im/branding/messenger/locales/en-US/brand.properties
+@@ -0,0 +1,7 @@
++# This Source Code Form is subject to the terms of the Mozilla Public
++# License, v. 2.0. If a copy of the MPL was not distributed with this
++# file, You can obtain one at http://mozilla.org/MPL/2.0/.
++
++brandShortName=Tor Messenger
++brandFullName=Tor Messenger - Beta
++vendorShortName=Tor Project
+diff --git a/im/branding/messenger/locales/jar.mn b/im/branding/messenger/locales/jar.mn
+new file mode 100755
+index 0000000..4fb707f
+--- /dev/null
++++ b/im/branding/messenger/locales/jar.mn
+@@ -0,0 +1,10 @@
++#filter substitution
++# This Source Code Form is subject to the terms of the Mozilla Public
++# License, v. 2.0. If a copy of the MPL was not distributed with this
++# file, You can obtain one at http://mozilla.org/MPL/2.0/.
++
++
++@AB_CD@.jar:
++% locale branding @AB_CD@ %locale/@AB_CD@/branding/
++ locale/@AB_CD@/branding/brand.dtd (%brand.dtd)
++ locale/@AB_CD@/branding/brand.properties (%brand.properties)
+diff --git a/im/branding/messenger/locales/moz.build b/im/branding/messenger/locales/moz.build
+new file mode 100644
+index 0000000..e59008d
+--- /dev/null
++++ b/im/branding/messenger/locales/moz.build
+@@ -0,0 +1,8 @@
++# vim: set filetype=python:
++# This Source Code Form is subject to the terms of the Mozilla Public
++# License, v. 2.0. If a copy of the MPL was not distributed with this
++# file, You can obtain one at http://mozilla.org/MPL/2.0/.
++
++JAR_MANIFESTS += ['jar.mn']
++
++DEFINES['MOZ_DISTRIBUTION_ID_UNQUOTED'] = CONFIG['MOZ_DISTRIBUTION_ID']
+diff --git a/im/branding/messenger/moz.build b/im/branding/messenger/moz.build
+new file mode 100644
+index 0000000..bd8ad85
+--- /dev/null
++++ b/im/branding/messenger/moz.build
+@@ -0,0 +1,8 @@
++# vim: set filetype=python:
++# This Source Code Form is subject to the terms of the Mozilla Public
++# License, v. 2.0. If a copy of the MPL was not distributed with this
++# file, You can obtain one at http://mozilla.org/MPL/2.0/.
++
++DIRS += ['locales']
++
++JAR_MANIFESTS += ['jar.mn']
+diff --git a/im/branding/messenger/mozicon128.png b/im/branding/messenger/mozicon128.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..5f94a95e5048b89b1957d2d86ebf22c43ec4b899
+GIT binary patch
+literal 16878
+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
+zsFAIoKE+IaX�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
+zaeT;0mjRz~Lbv0%0A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
+X7r#1Y+t^fI00000NkvXXu0mjfaq#|@
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/mozicon16.xpm b/im/branding/messenger/mozicon16.xpm
+new file mode 100644
+index 0000000..3434739
+--- /dev/null
++++ b/im/branding/messenger/mozicon16.xpm
+@@ -0,0 +1,193 @@
++/* This Source Code Form is subject to the terms of the Mozilla Public
++ * License, v. 2.0. If a copy of the MPL was not distributed with this
++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
++
++/* XPM */
++static char *instantbird___[] = {
++/* columns rows colors chars-per-pixel */
++"16 16 167 2",
++" c black",
++". c #020100",
++"X c #030101",
++"o c #020202",
++"O c gray1",
++"+ c gray2",
++"@ c #060606",
++"# c #070707",
++"$ c #0B0B0B",
++"% c #0C0C0C",
++"& c #15100C",
++"* c #101010",
++"= c #111111",
++"- c gray7",
++"; c #151515",
++": c gray9",
++"> c gray11",
++", c gray12",
++"< c #2A1400",
++"1 c #301E18",
++"2 c #212020",
++"3 c gray13",
++"4 c #232323",
++"5 c #272121",
++"6 c gray14",
++"7 c #252525",
++"8 c gray15",
++"9 c gray16",
++"0 c #2F2F2F",
++"q c #33302D",
++"w c gray20",
++"e c #343434",
++"r c #353535",
++"t c gray22",
++"y c #3A3A3A",
++"u c #46120C",
++"i c #501F15",
++"p c #521E14",
++"a c #4D261A",
++"s c #562217",
++"d c #572318",
++"f c #582418",
++"g c #693200",
++"h c #6A3200",
++"j c #773800",
++"k c #7D3B00",
++"l c #7A3C0F",
++"z c #512E20",
++"x c #5B2F28",
++"c c #423122",
++"v c #553127",
++"b c #543A24",
++"n c #543129",
++"m c #663520",
++"M c #6E3E27",
++"N c #613628",
++"B c #723E29",
++"V c #7F4919",
++"C c #6F432B",
++"Z c #7C4222",
++"A c #794523",
++"S c #74402B",
++"D c #76422C",
++"F c #75452E",
++"G c #78472F",
++"H c #63453C",
++"J c #6F483A",
++"K c #764430",
++"L c #744731",
++"P c #754A31",
++"I c #754B32",
++"U c #774B35",
++"Y c #774C37",
++"T c #794834",
++"R c #474544",
++"E c #464646",
++"W c #494949",
++"Q c #4B4B4B",
++"! c #5B5047",
++"~ c gray37",
++"^ c #714E40",
++"/ c #77574A",
++"( c #7E5E4C",
++") c #8D440F",
++"_ c #914500",
++"` c #964700",
++"' c #984700",
++"] c #9B4900",
++"[ c #994A03",
++"{ c #93470D",
++"} c #924C0E",
++"| c #8A4211",
++" . c #85461C",
++".. c #924B15",
++"X. c #A04C00",
++"o. c #A34F05",
++"O. c #A95000",
++"+. c #AA5000",
++"@. c #AD5200",
++"#. c #A4540E",
++"$. c #BB5800",
++"%. c #A75711",
++"&. c #AB5C15",
++"*. c #AA5C16",
++"=. c #A75C1A",
++"-. c #A4591E",
++";. c #B15E14",
++":. c #834928",
++">. c #914F23",
++",. c #865121",
++"<. c #865224",
++"1. c #8C522F",
++"2. c #935A27",
++"3. c #814D33",
++"4. c #8A5332",
++"5. c #8B5635",
++"6. c #83563A",
++"7. c #86543A",
++"8. c #8D593C",
++"9. c #936134",
++"0. c #B76822",
++"q. c #B96923",
++"w. c #BA6A24",
++"e. c #BF6D24",
++"r. c #BC6E29",
++"t. c #BE6F28",
++"y. c #B97335",
++"u. c #8E6147",
++"i. c #8A634F",
++"p. c #8B644F",
++"a. c #9B6746",
++"s. c #916844",
++"d. c #996A41",
++"f. c #9E6947",
++"g. c #967156",
++"h. c #A06C48",
++"j. c #B07C53",
++"k. c #967C66",
++"l. c #937B69",
++"z. c #A17F65",
++"x. c #B18866",
++"c. c #BB926C",
++"v. c #A78B74",
++"b. c #E79146",
++"n. c #FFA759",
++"m. c #C59F79",
++"M. c #D6A26D",
++"N. c #C5A37F",
++"B. c #CFA87C",
++"V. c #D4A775",
++"C. c #D8A976",
++"Z. c #F8AC67",
++"A. c #FFB36F",
++"S. c #EAB67A",
++"D. c #EEBA7D",
++"F. c #F2BE7F",
++"G. c #FFB97A",
++"H. c #FFBA7D",
++"J. c #FFBB7E",
++"K. c #BDA68B",
++"L. c #C6AC8D",
++"P. c #D6B286",
++"I. c #C9B190",
++"U. c #FFC490",
++"Y. c #F2D09C",
++"T. c #ECD6AA",
++"R. c None",
++/* pixels */
++"R.R.R.R.R.R.R.R.R.R.R.R.9 R.R.R.",
++"R.R.R.R.R.R.8 4 O O + Q W k.R.R.",
++"R.R.R.R.9 y y 7 = ~ $ * : R.",
++"R.G.Z.c t r 6 = : 4 + @ o R.R.",
++"J.n.;.& # - @ @ R.",
++"A.b.O.k < . % > # X R.",
++"H.e.] $.X._ j h g V ,.z H ( U i ",
++"U.%.+.' ) | @.' ` [ &.C L.u.j.P ",
++"R.} o...v.p.{ m L l *.A g.6.I a ",
++"R.b #. .N.c.5.l.z.B.Y n 5 2 3 = ",
++"R., <.&.Z f.T I.x.a.h.v w r e R.",
++"R.R.q 2.=.4.:.>.1.7.x / ^ J N u ",
++"R.R.R.R 9.-.0.q.w.M K.i.Y.C.3.B ",
++"R.R.R.> E s.r.t.t.G T.P.K 8.D.D ",
++"R.R.R.R.R.0 ! d.y.F m.V.M.S.F.S ",
++"R.R.R.R.R.R.R.; : 1 R.R.s d f p "
++};
+diff --git a/im/branding/messenger/mozicon50.xpm b/im/branding/messenger/mozicon50.xpm
+new file mode 100644
+index 0000000..76e799c
+--- /dev/null
++++ b/im/branding/messenger/mozicon50.xpm
+@@ -0,0 +1,314 @@
++/* This Source Code Form is subject to the terms of the Mozilla Public
++ * License, v. 2.0. If a copy of the MPL was not distributed with this
++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
++
++/* XPM */
++static char *instantbird___[] = {
++/* columns rows colors chars-per-pixel */
++"48 48 256 2",
++" c #000000",
++". c #0C0503",
++"X c #0B0B0B",
++"o c #1A0902",
++"O c #141414",
++"+ c #1B1B1B",
++"@ c #1F1515",
++"# c #1C1108",
++"$ c #2A0B0A",
++"% c #350201",
++"& c #3D0B07",
++"* c #380907",
++"= c #371B03",
++"- c #381A00",
++"; c #3E140F",
++": c #231815",
++"> c #381613",
++", c #372414",
++"< c #242424",
++"1 c #2C2C2C",
++"2 c #3A2B2B",
++"3 c #392828",
++"4 c #353535",
++"5 c #3A3A3A",
++"6 c #3E3535",
++"7 c #420E0A",
++"8 c #44120D",
++"9 c #4A160F",
++"0 c #541C0E",
++"q c #451511",
++"w c #481711",
++"e c #4D1B14",
++"r c #461814",
++"t c #501D13",
++"y c #4F270F",
++"u c #552800",
++"i c #5A200C",
++"p c #4B231D",
++"a c #492018",
++"s c #542115",
++"d c #582312",
++"f c #53241B",
++"g c #592519",
++"h c #5B2B1E",
++"j c #572A1D",
++"k c #64280A",
++"l c #702B01",
++"z c #693200",
++"x c #753302",
++"c c #7A3808",
++"v c #632B13",
++"b c #632B18",
++"n c #6C3416",
++"m c #783817",
++"M c #452A28",
++"N c #562C23",
++"B c #5B2D23",
++"V c #5A332A",
++"C c #4B3E3E",
++"Z c #643323",
++"A c #6B3A27",
++"S c #61362A",
++"D c #6C3D2A",
++"F c #693624",
++"G c #723E2A",
++"H c #653D33",
++"J c #534239",
++"K c #6F412E",
++"L c #73462D",
++"P c #79522F",
++"I c #634C38",
++"U c #7C4A33",
++"Y c #744C3A",
++"T c #784A37",
++"R c #6E5137",
++"E c #7C513C",
++"W c #454545",
++"Q c #4C4C4C",
++"! c #484040",
++"~ c #514646",
++"^ c #545353",
++"/ c #5A5A5A",
++"( c #5A524A",
++") c #734F43",
++"_ c #775545",
++"` c #696159",
++"' c #646464",
++"] c #6B6B6A",
++"[ c #727272",
++"{ c #7C726A",
++"} c #8C0000",
++"| c #AE0000",
++" . c #813C01",
++".. c #833907",
++"X. c #E20000",
++"o. c #F80000",
++"O. c #DA2D04",
++"+. c #8C4303",
++"@. c #964700",
++"#. c #974801",
++"$. c #9B4B02",
++"%. c #9D4F09",
++"&. c #90480D",
++"*. c #9F5009",
++"=. c #8C4918",
++"-. c #954C14",
++";. c #8E531E",
++":. c #93541B",
++">. c #9D551B",
++",. c #9D581A",
++"<. c #A44E01",
++"1. c #A14601",
++"2. c #AD5403",
++"3. c #A3530C",
++"4. c #A55105",
++"5. c #B35400",
++"6. c #BD5900",
++"7. c #B85700",
++"8. c #A65710",
++"9. c #AB5C15",
++"0. c #A55A17",
++"q. c #AF6019",
++"w. c #B2631C",
++"e. c #8B563A",
++"r. c #8C5A3C",
++"t. c #855535",
++"y. c #925E3E",
++"u. c #915E31",
++"i. c #8D6037",
++"p. c #97623F",
++"a. c #AC662B",
++"s. c #B66721",
++"d. c #B76925",
++"f. c #BA6B24",
++"g. c #BE6F28",
++"h. c #B56728",
++"j. c #A76D38",
++"k. c #B77337",
++"l. c #C35D00",
++"z. c #C95F00",
++"x. c #CD6100",
++"c. c #D26300",
++"v. c #D36B0F",
++"b. c #D66D10",
++"n. c #C1722B",
++"m. c #815640",
++"M. c #8F5D41",
++"N. c #835E4C",
++"B. c #865C44",
++"V. c #8D654D",
++"C. c #936444",
++"Z. c #9B6D4A",
++"A. c #9A6746",
++"S. c #856B57",
++"D. c #946E53",
++"F. c #977455",
++"G. c #8C7057",
++"H. c #A26E49",
++"J. c #A8754C",
++"K. c #AA7B54",
++"L. c #B37F55",
++"P. c #987866",
++"I. c #EF8323",
++"U. c #FF993E",
++"Y. c #FF973C",
++"T. c #B2865A",
++"R. c #B7875A",
++"E. c #9D8570",
++"W. c #9E856D",
++"Q. c #A5846A",
++"!. c #B88C64",
++"~. c #A78D76",
++"^. c #B1987E",
++"/. c #D68A48",
++"(. c #C78C58",
++"). c #FF9C41",
++"_. c #F39641",
++"`. c #EB9A52",
++"'. c #FFA14D",
++"]. c #FFA555",
++"[. c #FCA659",
++"{. c #FFA95B",
++"}. c #C08F60",
++"|. c #C49262",
++" X c #CB9C69",
++".X c #C99968",
++"XX c #D29F6A",
++"oX c #C29D76",
++"OX c #CFA36D",
++"+X c #D5A46D",
++"@X c #DAA66F",
++"#X c #CCA377",
++"$X c #DDAB73",
++"%X c #D3A776",
++"&X c #DDB07C",
++"*X c #FEAC63",
++"=X c #FFB069",
++"-X c #E2B177",
++";X c #E7B57A",
++":X c #E8B77B",
++">X c #EEBA7D",
++",X c #FFB573",
++"<X c #F2BE7F",
++"1X c #FFB97B",
++"2X c #E8A467",
++"3X c #8B8B8B",
++"4X c #868686",
++"5X c #959595",
++"6X c #9F9F9F",
++"7X c #AE9A83",
++"8X c #B9A186",
++"9X c #B8A991",
++"0X c #BDB398",
++"qX c #AAAAAA",
++"wX c gray63",
++"eX c gray69",
++"rX c #C4A886",
++"tX c #D6AF82",
++"yX c #D8B88A",
++"uX c #D7BE95",
++"iX c #C7B998",
++"pX c #E8BC82",
++"aX c #F6BE82",
++"sX c #CBBEA3",
++"dX c #DBC29B",
++"fX c #EFC68F",
++"gX c #F2C284",
++"hX c #F3C68A",
++"jX c #FFC38D",
++"kX c #F8C68C",
++"lX c #E7C694",
++"zX c #F4CC93",
++"xX c #F5CF98",
++"cX c #FFC490",
++"vX c #F5D29C",
++"bX c #DAC9A7",
++"nX c #DCD2B5",
++"mX c #EDD9AE",
++"MX c #F6D6A2",
++"NX c #F7D9A6",
++"BX c #F7DBA9",
++"VX c #F8DEAD",
++"CX c #E3DCBE",
++"ZX c #E8CFA3",
++"AX c #F9E3B3",
++"SX c #FAE6B8",
++"DX c #FAE9BD",
++"FX c #F3E3BA",
++"GX c #F7EBC3",
++"HX c #FBEEC4",
++"JX c #F4EFCB",
++"KX c #FCF0C7",
++"LX c #FCF3CC",
++"PX c #FBF7D3",
++"IX c #E8E6C6",
++"UX c None",
++/* pixels */
++"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX| } ",
++"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX+ + UXUXUXUXo.X.UXUXUX",
++"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX4 ' eX[ X UXo.UXUXUXUXUX",
++"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXX + + O UXUXUXUXUX5 6X5 qXqXE.O.UXUXUXUXUXUX",
++"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX+ 1 4 5 5 + UX1 wX3XQ / qX(.P.X UXUXUXUXUX",
++"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXO < 5 5 5 5 5 1 X 5X3X] Q O [ 6X5X' . UXUXUXUX",
++"UXUXUXUXUXUXUXUXUXUXUXUXUXUX< 5 5 5 5 5 5 5 1 / 3X] Q 1 X ^ 5X3XO UXUXUXUX",
++"UXUXUXUXUXUXUXUXUXUXUXUXX 4 5 5 5 5 5 5 5 5 5 + X 4X] Q 1 X < Q O UXUXUXUX",
++"UXUXUXUXUXUXUXUXUX1X2X: 5 5 5 5 5 5 5 5 5 5 5 O 4 1 O ] Q 1 X O UXUXUXUX",
++"UXUXUXUXUXjX=X{.].`., 5 5 5 5 5 5 5 5 5 5 5 < X 1 4 + X W 1 X O UXUXUXUXUX",
++"UXUXUXjX=X'.].'.[.y 5 5 5 5 5 5 5 4 + < 5 4 O < < 4 4 + O X X UXUXUXUXUXUX",
++"UXUXjX*XY.*X).*X:. 5 5 1 4 5 5 5 X . < 4 4 X + X UXUXUXUXUXUX",
++"UXcX*X).*X*XU.n.z X 5 4 X + 5 1 X O + UXUXUXUXUX",
++"UX=X].'.=X'._.#. .. O O 1 X UXUXUXUX",
++"jX=X'.].=X].v.@.@.u UXUXUXUX",
++"1X=X].'.=X`.x.$.@.@.- O X UXUXUX",
++",X=X*XY.=Xq.5.l.#.@.@.z o X 4 4 + UXUXUX",
++",X=X=XU.].#.@.l.l.#.@.@.@.z - o 1 4 + . 4 4 4 X . UXUX",
++"aX=X=X{.I.#.@.$.x.l.$.@.@.@.@.@.@.x u - o . < 4 4 4 4 4 4 X . o > > p N N N j s % UX",
++"jX=X=X=Xb.5.@.@.$.z.c.5.@.@.@.@.@.@.@.@.@.@.@.@.+. .x c ;.:.:.>.,.0.y % ) 9XbXFXSXVXvXzX$Xg L 9 ",
++"UX=X=X=X2.c.$.@.@.#.7.c.z.<.@.@.@.@.@.@.@.@.@.@.@.@.@.#.9.9.9.9.9.9.n N N P.GXDXVXMXzX+Xs K.|.e ",
++"UX1X=X=X#.7.x.$.@.@.@.$.l.c.z.2.$.@.@.@.@.@.@.@.@.@.@.@.%.9.9.9.9.9.-.V IXS.N rXNXxX.Xs T.>XXX8 ",
++"UXUX=X*X$.@.l.x.$.@.@.@.@.<...k c.6.<.@.@.@.@.@.@.@.@.@.@.$.8.9.9.9.9.p LXGXrXS T L.g !.<X<X$X7 ",
++"UXUX,X`.$.@.$.x.x.<.@.@.@.l w * c c.c.c.6.2.$.@.@.@.@.@.@.$.9.9.9.9.9.a HXSXVXlXD.F .X<X<X<X-X7 ",
++"UXUXjX/.%.$.$.<.c.c.<.$.x e sXH _ c 5.l.c.c.1.d x @.$.$.$.*.9.9.9.9.9.e FXVXMXzXhX-X<X<X<X<X>X8 ",
++"UXUXUX/.3.$.$.$.4.x.c.l e CXnXH GXZ .$.%.2.k 8 N.j v c $.$.3.w.q.q.q.a dXNXxXhX<X<X;X+X|.L.H.8 ",
++"UXUXUX!.3.%.%.%.%.3.k _ JXLXbXS SXZXs +.%.%.r 7X) KXuXB.e v &.w.w.w.w.f Y D f 8 * * * * $ $ o UX",
++"UXUXUXUX=.3.3.3.3.3.v 8XKXDXdXS BXMXtX0 %..._ JXN bXAXVXvX!.f p J I R V 3 : @ + + + + + + O X UX",
++"UXUXUXUX, 0.3.3.3.3.%.t mXAXyXB vXzXhXR.i d nXLXW.Y VXMXvXzXgX(.h M ! Q 4 < < < < < < < < O X UX",
++"UXUXUXUXO P 8.8.8.8.8.c m.MXtXB hXgX<X<Xy.N LXHXmXe uXvXzXgX<X<X<XA.% M 1 < < < < < < < < X O UX",
++"UXUXUXUXO ! ;.9.9.9.9.8.0 #X%X7 G y.K..XM.7XHXDXAXD.E zXhX<XXXC.s A 8 4 1 1 1 1 1 1 1 1 1 . UXUX",
++"UXUXUXUXUX< ( 0.9.9.9.9.-.d :XOXR.Z.t.D q GXDXAXBXlXq A.A e F C. X}.a 4 4 4 4 4 4 4 4 5 < X UXUX",
++"UXUXUXUXUXX ^ I 9.9.9.9.9.m e.<X<X<X>X XZ B rXVXMXxXF.C.T.+X-X>X<XF 2 5 5 5 5 5 5 Q ^ Q O O UXUX",
++"UXUXUXUXUXO 4 W L w.w.w.w.q.v R.<X<X<X<Xe.v m b !.hXpX<X<XZ.M.C.r.r 3 3 3 3 2 2 C ~ ~ 6 . UXUXUX",
++"UXUXUXUXUXUXO 5 W P w.w.w.w.9.0 +X<X$XF m g.n.g.=.n H.>X<Xf q ~.9X8X^.~.Q.P.D.V.B.m.T K A b % UX",
++"UXUXUXUXUXUXO + Q Q t.w.w.w.w.>.d H.d >.w.w.g.n.n.g.=.b p.e 9XN sXLXHXDXAXVXNXvXxXzXhXaX@Xg h UX",
++"UXUXUXUXUXUXUXX 1 Q Q u.s.s.s.s.=.m s.s.s.s.s.g.n.n.f.s.=.8 PX0XN 8XDXAXVXNXvXxXzXhXgX|.e Z.A.UX",
++"UXUXUXUXUXUXUXUXX 5 ^ ^ i.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.w PXKXiXV Q.VXNXvXxXzXhXgXJ.9 K.;XA.UX",
++"UXUXUXUXUXUXUXUX+ X Q / / _ d.f.f.f.f.f.f.f.f.f.f.f.f.f.f.w LXHXDXuXH V.vXvXzXhXaXe.t T.:X<Xy.UX",
++"UXUXUXUXUXUXUXUXUXO X Q / / ` a.g.g.g.g.g.g.g.g.g.g.g.g.f.w HXDXAXVXuXY T fXhX:XA A |.>X<X<Xe.UX",
++"UXUXUXUXUXUXUXUXUXUX+ X W ' ' ` j.g.g.g.g.g.g.g.g.g.g.g.f.e DXSXVXBXMXyXB.Z Xg r.+X<X<X<X<Xt.UX",
++"UXUXUXUXUXUXUXUXUXUXUX+ X 5 ' ' ' S.j.n.n.n.n.n.n.n.n.n.d.f SXAXBXMXvXzXpXC.t K.$X<X<X<X<X<XU UX",
++"UXUXUXUXUXUXUXUXUXUXUXUX+ X O Q ] ] ] S.k.n.n.n.n.n.n.n.h.N AXBXMXvXzXhXgX;X X:X<X<X<X<X<X<XL UX",
++"UXUXUXUXUXUXUXUXUXUXUXUXUXUX+ X + Q ] ] ] G.k.n.n.n.n.n.h.V BXMXvXzXhXgX<X<X<X<X<X<X<X<X<X<XD UX",
++"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX+ X X < Q ' [ { G.J.k.n.a.f oX#X%X&X;X>X<X<X<X<X<X<X<X<X<X<XF UX",
++"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX+ + X X . X O + O # = $ > > ; 8 7 & & & 7 8 e g Z G U e.9 UX",
++"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX+ + + + + + + + UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
++"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX"
++};
+diff --git a/im/branding/messenger/windows/blistWindow.ico b/im/branding/messenger/windows/blistWindow.ico
+new file mode 100644
+index 0000000000000000000000000000000000000000..83dfe4415cbff4b4a642bd9d1dfa3c8e28b92999
+GIT binary patch
+literal 9662
+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
+Q?WWjKu`9ikQq=DM0qh`X{r~^~
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/windows/convWindow.ico b/im/branding/messenger/windows/convWindow.ico
+new file mode 100644
+index 0000000000000000000000000000000000000000..a22977ca8e9d1f0ad31da2508341a0aca8c11093
+GIT binary patch
+literal 10058
+zcmd5?O^X~w7_O~8>@j;$Jn0Y*Q4rh>3Mz!`svr`?CCGw^GEq@9s6zq<(U1;VL4qH<
+zU{FDfilP#P@ggW5nxN=KS??Yi`~!RRpq9^5(=}6DUHwr#wH+tC`*wXl&-+nT-9(55
+z{99QO_&X4H91`MsA;c{ZREZ}ctgrehr9=!#e!a2^Ng-oM2FW4H64p_+AVbI?#=7&)
+zQD7lv8*9ijd8Q$J<f;3XAVWyn6+hNnD%RbF4#BIEAKp{R=Vz6C`za;gcw7O;UU~U}
+zUr;xOj3CPfBc2UzwwW;_(;lLMnK2NK{mQ127dFh=Avy=<%))JtopNl$0k~=V3=(Gd
+zZ?}~^yKb)=>v^{gZqo<2mm$HnmzU4P!t0x7Z16Q{VDA(=^4;h4x@(tCsSr81`Irx{
+zudY=t6!^nphp{%kI9(Gq3i_S@?vv@*iX1TQLrh$ICUlJ-j8pQ=gJzu|{OlaSVW*A*
+za4>&^<Dd8w?mx4=Z@-@_&q!bi-+zkz%H%;$JXU?a0Dk6hcn%m2&bh_-i1o|<_}%qu
+zi36~AkD>n$hjbnvaI70kA^U1m-@|V`)5Z_o^4N~OzH%CSA8a;6oC+f>&+7v--rido
+z!?9%h>en+r;0(ojnZZwu^4MU|`pef<a{0Axxjn}j2P~DpX-?AzKYwPh4KP6aVh?`C
+z#y9UMdG~cn-g~2xqlcRLeE+^mz*}AzPUOYO{g`J~EIIK7&VS<P{e2d{`p$v!s#P~_
+z*Z9f9h|TB6Pc<*{lgAFt`k21dkKR7>eT;LjjGtKb-4EKkAIWE7OB+*{=VLc3dGg5o
+zTyX9rS3jEC*RpxeSRxmzZr1P3=jP`?-bZdw^7yUYxZr&+!8?c-UlC6Qhs@i@<b-Aa
+zgU1i6wUg_?!g1QC_anbHZc}o2r;<<Kwbwr{ttt8H!}^Tjz01nmS`NU@T*$o~z|+l%
+z^B-QU+&AhPIIeA6CYMe(VRqZe!L6H?-JIxy1Gxt7>(v~v_qcwTJC>}ttn~}_z=V5W
+zjeV^)a`4|V;M3Z5+T!WjkLOZ*4w<j7-us>PyT(#ouCOip?WeN6+WUfj@N;-%r8IA^
+z9ALkec`*Qo)awVw2aGH3tK<<|PHetVvX_oy++BRw>^itnpggqe%=0zP1!KQv4*Kp2
+z%=ATxua5)m#n_E4+h2Xq)ekBCQ21iU<>9-_^_~yS=iRc!p_CK8eW`ChB)rpmVx*|k
+z_dSb4IiC1FVB+#x=qK)}!_T&999cX*b~#JTWAo^9U*bEJi^nMs40fZ@UiJliY2P<`
+z%ZFDsn(%KK+^z<Xk}r797+>_l0cWdYZ@0|5(UObZl-UL;-=BDQ;=Aa6=LK`1`K~uI
+zc&juxtV3MxlkWtc`$sfh&F2|0jjM3G_2`>=d4QY#b`jGjv_0M#tJbsXcko;pLoNrF
+z(Z8G<#y|8o<EyJ*XanA@oA(~Wjq$zg!`W0<%fs;DIYd6#OY~ms`&Pp}n%_wnFYR&9
+zjo<KV#l!H4uNgm`>~HWJjd_L;`qS8^4?V_uLGf?!R%y&PfMh-Jpshw#IAYXee)=Te
+zCoWr<H>&OHI2T-E_=WaJ`^4_@!rFs^59613+T==xe#9LmUtLTw%D}c-A*H)!jP;bt
+z7nMo{jx}-aALze?So{-u7yoN3fzAq@78*({rsCg1|4og47^XFcv21i+lrx`RNJYwe
+zS5Ioupj)Hp$xOw1m{*srbu+9&99jc^&a%<qtN9!#cp80EDm4G2g+0!}UK~ezW|)pT
+Xhq<U>paaw}+)-+kEllhVFQWV(oC5s(
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/windows/default.ico b/im/branding/messenger/windows/default.ico
+new file mode 100644
+index 0000000000000000000000000000000000000000..51fed13f752340320417fa83145ad7896b2af839
+GIT binary patch
+literal 7262
+zcmds6O=}ZD7+z-&JvJ9buwq0J1<@dgC>A3MRs<=6f`SsMs92C7NH3Ny_<{IE6hRQw
+zf_m~2FP;P!FM1L36N0}W#~#%2c{VfYY%;Txq?>}KJb7nlciwrPci#EfCJ5Hxue3G5
+zcQKfn2!eG%5NroZz!boG*C+h(p#dxc(^AUdUxVT<VTqQy9!Lw?6o4`iDb!)(6h1xu
+zA|6)0i`wN_JiB^J+&w#)N376C1<?FW>(qkhi$E11&n95DvzI?TmEy*cH0Gv$i+ksO
+ziboe;i6=9=hS7t*$;IC1a=q44!?TS(p6~T%<8SJDeRBzZ7lHDiI?$%S7%uDS<>$NS
+z<Ns#P^cfGLL+Li#=U*O-zwV#;S@4Yqo|y)8o8j!o$1;3zLyBj!QoO86asPZ8x6h<=
+z-^?AB)A2Vsw8$?@12qoC|LuYlGm}yro{(by+BPoj%jVh5TVK2RYb}vSL!)mE(K#uO
+zZC>WAxzi5IALA7w$2=SsT^i7?=4mU#&o897u-DF8YZ#Wl9*5`GWcck}mX4}T1Gq<-
+z{NK;F^WyZ*(ekH`x#LN!GWev{SUku4Z@Hcqh)HMf@$o;oO^Q=HkYB}Ku<iLhQp{q`
+z=y+$?@WUO~IB>o1tV<|YoZPvVn0@&8>pb$=qZ`{=Oy8Dr#+>NPXK=4u`P<g)y!dN<
+z<qg?$p1EY74=p_pz}=cVVtzUud&Vbk{#pm~$`b#i4mn_rZ+qV=TJO~#*!_))KXtg)
+zF83HLf_vG<KQ(8~xQvoN=Y-jpQ4SGL3(wfepZmYjzEd70e~y8zPu98jXM6nrSN_aV
+zJ?HYaT#NFG|C1TFFXn09-0AP^ZfBp4y{v)!FIwh><nzv0Tsa`c!S(rS;C}6jJ?g`+
+zuWj?U&OHG9n>`w^XYd^2^qHpyj_38VyD#KI55M;NN=5OHtoQYq%@r4(V;HxU<Pz62
+zmw#37h&?qWXCPR64nbq`9_8_$>^p<#VD9mZ*T*@|k@w`DdKbX8eGHgKzIQ*Zk2%0|
+z0At#H{yedzUGLgswGY$sUBLcc%kxfApMO*i6;RhZ57?d>veqNB&z#C3a@WC~^;MI*
+zE~CB#P@BCi=R?+<&VxJ7j2UNU@=Dem&AHp+e#OaOkA?X@lLu$|AaD2kijHRk+>$xl
+z&D*?I8r<Wcba0IOo*OQmTpRto$-gh|S_hsl0rvUOonPErc;3bttMh-KZobSro~byG
+zcoy^juR+J0HnrAhjy{Wa1-1oDU#nSW4ov%a`tHL=8HiU|M-BaXbKS??yuS)M7;o}U
+zt?ed<Jj(PBRDlMt(tILk=IDy^WEgGew*WA|BA^b$KohX(;yt1URDsekeVT0!;Q~j{
+zU`#g0Xrn(taEKN^n2jqNDjUGY{2^^Y*-grhciAy@9V)w~?GHc1C4M^=t|I!wCrZBi
+xw1%IU?Qoq~^w;Dy`fn+_L<@euXu%iqATXem<V(hAjthwfW3)=YlyS&-`~^IDi|7CV
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/wizHeader.bmp b/im/branding/messenger/wizHeader.bmp
+new file mode 100644
+index 0000000000000000000000000000000000000000..7fbaa640c6e7d06647f2f665f415c516b30d2bf3
+GIT binary patch
+literal 25818
+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
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/wizHeaderRTL.bmp b/im/branding/messenger/wizHeaderRTL.bmp
+new file mode 100644
+index 0000000000000000000000000000000000000000..2c882095562c025edf6b2db2de264f586fea16cf
+GIT binary patch
+literal 25818
+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%0D=?=i`tXyrr#>2arOL_A
+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
+S4u@dz*$fF*)PJ!Wg8U1LdkXge
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/wizWatermark.bmp b/im/branding/messenger/wizWatermark.bmp
+new file mode 100644
+index 0000000000000000000000000000000000000000..03352038cfaf2532ee6cc997680807a3abcd5d5b
+GIT binary patch
+literal 154542
+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
+M8kRGe!I94Y0Z~OtP5=M^
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/content/aboutDialog-appUpdater.js b/im/content/aboutDialog-appUpdater.js
+new file mode 100644
+index 0000000..f223f06
+--- /dev/null
++++ b/im/content/aboutDialog-appUpdater.js
+@@ -0,0 +1,576 @@
++/* This Source Code Form is subject to the terms of the Mozilla Public
++ * License, v. 2.0. If a copy of the MPL was not distributed with this
++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
++
++// Note: this file is included in aboutDialog.xul if MOZ_UPDATER is defined.
++
++Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
++Components.utils.import("resource://gre/modules/DownloadUtils.jsm");
++Components.utils.import("resource://gre/modules/AddonManager.jsm");
++
++XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils",
++ "resource://gre/modules/UpdateUtils.jsm");
++
++var gAppUpdater;
++
++function onUnload(aEvent) {
++ if (gAppUpdater.isChecking)
++ gAppUpdater.checker.stopChecking(Components.interfaces.nsIUpdateChecker.CURRENT_CHECK);
++ // Safe to call even when there isn't a download in progress.
++ gAppUpdater.removeDownloadListener();
++ gAppUpdater = null;
++}
++
++
++function appUpdater()
++{
++ this.updateDeck = document.getElementById("updateDeck");
++
++ // Hide the update deck when there is already an update window open to avoid
++ // syncing issues between them.
++ if (Services.wm.getMostRecentWindow("Update:Wizard")) {
++ this.updateDeck.hidden = true;
++ return;
++ }
++
++ XPCOMUtils.defineLazyServiceGetter(this, "aus",
++ "@mozilla.org/updates/update-service;1",
++ "nsIApplicationUpdateService");
++ XPCOMUtils.defineLazyServiceGetter(this, "checker",
++ "@mozilla.org/updates/update-checker;1",
++ "nsIUpdateChecker");
++ XPCOMUtils.defineLazyServiceGetter(this, "um",
++ "@mozilla.org/updates/update-manager;1",
++ "nsIUpdateManager");
++
++ this.bundle = Services.strings.
++ createBundle("chrome://browser/locale/browser.properties");
++
++ let manualURL = Services.urlFormatter.formatURLPref("app.update.url.manual");
++ let manualLink = document.getElementById("manualLink");
++ manualLink.value = manualURL;
++ manualLink.href = manualURL;
++ document.getElementById("failedLink").href = manualURL;
++
++ if (this.updateDisabledAndLocked) {
++ this.selectPanel("adminDisabled");
++ return;
++ }
++
++ if (this.isPending || this.isApplied) {
++ this.selectPanel("apply");
++ return;
++ }
++
++ if (this.aus.isOtherInstanceHandlingUpdates) {
++ this.selectPanel("otherInstanceHandlingUpdates");
++ return;
++ }
++
++ if (this.isDownloading) {
++ this.startDownload();
++ // selectPanel("downloading") is called from setupDownloadingUI().
++ return;
++ }
++
++ // Honor the "Never check for updates" option by not only disabling background
++ // update checks, but also in the About dialog, by presenting a
++ // "Check for updates" button.
++ // If updates are found, the user is then asked if he wants to "Update to <version>".
++ if (!this.updateEnabled) {
++ this.selectPanel("checkForUpdates");
++ return;
++ }
++
++ // That leaves the options
++ // "Check for updates, but let me choose whether to install them", and
++ // "Automatically install updates".
++ // In both cases, we check for updates without asking.
++ // In the "let me choose" case, we ask before downloading though, in onCheckComplete.
++ this.checkForUpdates();
++}
++
++appUpdater.prototype =
++{
++ // true when there is an update check in progress.
++ isChecking: false,
++
++ // true when there is an update already staged / ready to be applied.
++ get isPending() {
++ if (this.update) {
++ return this.update.state == "pending" ||
++ this.update.state == "pending-service";
++ }
++ return this.um.activeUpdate &&
++ (this.um.activeUpdate.state == "pending" ||
++ this.um.activeUpdate.state == "pending-service");
++ },
++
++ // true when there is an update already installed in the background.
++ get isApplied() {
++ if (this.update)
++ return this.update.state == "applied" ||
++ this.update.state == "applied-service";
++ return this.um.activeUpdate &&
++ (this.um.activeUpdate.state == "applied" ||
++ this.um.activeUpdate.state == "applied-service");
++ },
++
++ // true when there is an update download in progress.
++ get isDownloading() {
++ if (this.update)
++ return this.update.state == "downloading";
++ return this.um.activeUpdate &&
++ this.um.activeUpdate.state == "downloading";
++ },
++
++ // true when updating is disabled by an administrator.
++ get updateDisabledAndLocked() {
++ return !this.updateEnabled &&
++ Services.prefs.prefIsLocked("app.update.enabled");
++ },
++
++ // true when updating is enabled.
++ get updateEnabled() {
++ try {
++ return Services.prefs.getBoolPref("app.update.enabled");
++ }
++ catch (e) { }
++ return true; // Firefox default is true
++ },
++
++ // true when updating in background is enabled.
++ get backgroundUpdateEnabled() {
++ return this.updateEnabled &&
++ gAppUpdater.aus.canStageUpdates;
++ },
++
++ // true when updating is automatic.
++ get updateAuto() {
++ try {
++ return Services.prefs.getBoolPref("app.update.auto");
++ }
++ catch (e) { }
++ return true; // Firefox default is true
++ },
++
++ /**
++ * Sets the panel of the updateDeck.
++ *
++ * @param aChildID
++ * The id of the deck's child to select, e.g. "apply".
++ */
++ selectPanel: function(aChildID) {
++ let panel = document.getElementById(aChildID);
++
++ let button = panel.querySelector("button");
++ if (button) {
++ if (aChildID == "downloadAndInstall") {
++ let updateVersion = gAppUpdater.update.displayVersion;
++ button.label = this.bundle.formatStringFromName("update.downloadAndInstallButton.label", [updateVersion], 1);
++ button.accessKey = this.bundle.GetStringFromName("update.downloadAndInstallButton.accesskey");
++ }
++ this.updateDeck.selectedPanel = panel;
++ if (!document.commandDispatcher.focusedElement || // don't steal the focus
++ document.commandDispatcher.focusedElement.localName == "button") // except from the other buttons
++ button.focus();
++
++ } else {
++ this.updateDeck.selectedPanel = panel;
++ }
++ },
++
++ /**
++ * Check for updates
++ */
++ checkForUpdates: function() {
++ this.selectPanel("checkingForUpdates");
++ this.isChecking = true;
++ this.checker.checkForUpdates(this.updateCheckListener, true);
++ // after checking, onCheckComplete() is called
++ },
++
++ /**
++ * Check for addon compat, or start the download right away
++ */
++ doUpdate: function() {
++ // skip the compatibility check if the update doesn't provide appVersion,
++ // or the appVersion is unchanged, e.g. nightly update
++#ifdef TOR_BROWSER_UPDATE
++ let pkgVersion = TOR_BROWSER_VERSION;
++#else
++ let pkgVersion = Services.appinfo.version;
++#endif
++ if (!this.update.appVersion ||
++ Services.vc.compare(gAppUpdater.update.appVersion, pkgVersion) == 0) {
++ this.startDownload();
++ } else {
++ this.checkAddonCompatibility();
++ }
++ },
++
++ /**
++ * Handles oncommand for the "Restart to Update" button
++ * which is presented after the download has been downloaded.
++ */
++ buttonRestartAfterDownload: function() {
++ if (!this.isPending && !this.isApplied)
++ return;
++
++ // Notify all windows that an application quit has been requested.
++ let cancelQuit = Components.classes["@mozilla.org/supports-PRBool;1"].
++ createInstance(Components.interfaces.nsISupportsPRBool);
++ Services.obs.notifyObservers(cancelQuit, "quit-application-requested", "restart");
++
++ // Something aborted the quit process.
++ if (cancelQuit.data)
++ return;
++
++ let appStartup = Components.classes["@mozilla.org/toolkit/app-startup;1"].
++ getService(Components.interfaces.nsIAppStartup);
++
++ // If already in safe mode restart in safe mode (bug 327119)
++ if (Services.appinfo.inSafeMode) {
++ appStartup.restartInSafeMode(Components.interfaces.nsIAppStartup.eAttemptQuit);
++ return;
++ }
++
++ appStartup.quit(Components.interfaces.nsIAppStartup.eAttemptQuit |
++ Components.interfaces.nsIAppStartup.eRestart);
++ },
++
++ /**
++ * Handles oncommand for the "Apply Update…" button
++ * which is presented if we need to show the billboard or license.
++ */
++ buttonApplyBillboard: function() {
++ const URI_UPDATE_PROMPT_DIALOG = "chrome://mozapps/content/update/updates.xul";
++ var ary = null;
++ ary = Components.classes["@mozilla.org/supports-array;1"].
++ createInstance(Components.interfaces.nsISupportsArray);
++ ary.AppendElement(this.update);
++ var openFeatures = "chrome,centerscreen,dialog=no,resizable=no,titlebar,toolbar=no";
++ Services.ww.openWindow(null, URI_UPDATE_PROMPT_DIALOG, "", openFeatures, ary);
++ window.close(); // close the "About" window; updates.xul takes over.
++ },
++
++ /**
++ * Implements nsIUpdateCheckListener. The methods implemented by
++ * nsIUpdateCheckListener are in a different scope from nsIIncrementalDownload
++ * to make it clear which are used by each interface.
++ */
++ updateCheckListener: {
++ /**
++ * See nsIUpdateService.idl
++ */
++ onCheckComplete: function(aRequest, aUpdates, aUpdateCount) {
++ gAppUpdater.isChecking = false;
++ gAppUpdater.update = gAppUpdater.aus.
++ selectUpdate(aUpdates, aUpdates.length);
++ if (!gAppUpdater.update) {
++ gAppUpdater.selectPanel("noUpdatesFound");
++ return;
++ }
++
++ if (gAppUpdater.update.unsupported) {
++ if (gAppUpdater.update.detailsURL) {
++ let unsupportedLink = document.getElementById("unsupportedLink");
++ unsupportedLink.href = gAppUpdater.update.detailsURL;
++ }
++ gAppUpdater.selectPanel("unsupportedSystem");
++ return;
++ }
++
++ if (!gAppUpdater.aus.canApplyUpdates) {
++ gAppUpdater.selectPanel("manualUpdate");
++ return;
++ }
++
++ // Firefox no longer displays a license for updates and the licenseURL
++ // check is just in case a distibution does.
++ if (gAppUpdater.update.billboardURL || gAppUpdater.update.licenseURL) {
++ gAppUpdater.selectPanel("applyBillboard");
++ return;
++ }
++
++ if (gAppUpdater.updateAuto) // automatically download and install
++ gAppUpdater.doUpdate();
++ else // ask
++ gAppUpdater.selectPanel("downloadAndInstall");
++ },
++
++ /**
++ * See nsIUpdateService.idl
++ */
++ onError: function(aRequest, aUpdate) {
++ // Errors in the update check are treated as no updates found. If the
++ // update check fails repeatedly without a success the user will be
++ // notified with the normal app update user interface so this is safe.
++ gAppUpdater.isChecking = false;
++ gAppUpdater.selectPanel("noUpdatesFound");
++ },
++
++ /**
++ * See nsISupports.idl
++ */
++ QueryInterface: function(aIID) {
++ if (!aIID.equals(Components.interfaces.nsIUpdateCheckListener) &&
++ !aIID.equals(Components.interfaces.nsISupports))
++ throw Components.results.NS_ERROR_NO_INTERFACE;
++ return this;
++ }
++ },
++
++ /**
++ * Checks the compatibility of add-ons for the application update.
++ */
++ checkAddonCompatibility: function() {
++ try {
++ var hotfixID = Services.prefs.getCharPref(PREF_EM_HOTFIX_ID);
++ }
++ catch (e) { }
++
++ var self = this;
++ AddonManager.getAllAddons(function(aAddons) {
++ self.addons = [];
++ self.addonsCheckedCount = 0;
++ aAddons.forEach(function(aAddon) {
++ // Protect against code that overrides the add-ons manager and doesn't
++ // implement the isCompatibleWith or the findUpdates method.
++ if (!("isCompatibleWith" in aAddon) || !("findUpdates" in aAddon)) {
++ let errMsg = "Add-on doesn't implement either the isCompatibleWith " +
++ "or the findUpdates method!";
++ if (aAddon.id)
++ errMsg += " Add-on ID: " + aAddon.id;
++ Components.utils.reportError(errMsg);
++ return;
++ }
++
++ // If an add-on isn't appDisabled and isn't userDisabled then it is
++ // either active now or the user expects it to be active after the
++ // restart. If that is the case and the add-on is not installed by the
++ // application and is not compatible with the new application version
++ // then the user should be warned that the add-on will become
++ // incompatible. If an addon's type equals plugin it is skipped since
++ // checking plugins compatibility information isn't supported and
++ // getting the scope property of a plugin breaks in some environments
++ // (see bug 566787). The hotfix add-on is also ignored as it shouldn't
++ // block the user from upgrading.
++ try {
++#ifdef TOR_BROWSER_UPDATE
++ let compatVersion = self.update.platformVersion;
++#else
++ let compatVersion = self.update.appVersion;
++#endif
++ if (aAddon.type != "plugin" && aAddon.id != hotfixID &&
++ !aAddon.appDisabled && !aAddon.userDisabled &&
++ aAddon.scope != AddonManager.SCOPE_APPLICATION &&
++ aAddon.isCompatible &&
++ !aAddon.isCompatibleWith(compatVersion,
++ self.update.platformVersion))
++ self.addons.push(aAddon);
++ }
++ catch (e) {
++ Components.utils.reportError(e);
++ }
++ });
++ self.addonsTotalCount = self.addons.length;
++ if (self.addonsTotalCount == 0) {
++ self.startDownload();
++ return;
++ }
++
++ self.checkAddonsForUpdates();
++ });
++ },
++
++ /**
++ * Checks if there are updates for add-ons that are incompatible with the
++ * application update.
++ */
++ checkAddonsForUpdates: function() {
++ this.addons.forEach(function(aAddon) {
++#ifdef TOR_BROWSER_UPDATE
++ let compatVersion = this.update.platformVersion;
++#else
++ let compatVersion = this.update.appVersion;
++#endif
++ aAddon.findUpdates(this, AddonManager.UPDATE_WHEN_NEW_APP_DETECTED,
++ compatVersion,
++ this.update.platformVersion);
++ }, this);
++ },
++
++ /**
++ * See XPIProvider.jsm
++ */
++ onCompatibilityUpdateAvailable: function(aAddon) {
++ for (var i = 0; i < this.addons.length; ++i) {
++ if (this.addons[i].id == aAddon.id) {
++ this.addons.splice(i, 1);
++ break;
++ }
++ }
++ },
++
++ /**
++ * See XPIProvider.jsm
++ */
++ onUpdateAvailable: function(aAddon, aInstall) {
++#ifdef TOR_BROWSER_UPDATE
++ let compatVersion = this.update.platformVersion;
++#else
++ let compatVersion = this.update.appVersion;
++#endif
++ if (!Services.blocklist.isAddonBlocklisted(aAddon,
++ compatVersion,
++ this.update.platformVersion)) {
++ // Compatibility or new version updates mean the same thing here.
++ this.onCompatibilityUpdateAvailable(aAddon);
++ }
++ },
++
++ /**
++ * See XPIProvider.jsm
++ */
++ onUpdateFinished: function(aAddon) {
++ ++this.addonsCheckedCount;
++
++ if (this.addonsCheckedCount < this.addonsTotalCount)
++ return;
++
++ if (this.addons.length == 0) {
++ // Compatibility updates or new version updates were found for all add-ons
++ this.startDownload();
++ return;
++ }
++
++ this.selectPanel("applyBillboard");
++ },
++
++ /**
++ * Starts the download of an update mar.
++ */
++ startDownload: function() {
++ if (!this.update)
++ this.update = this.um.activeUpdate;
++ this.update.QueryInterface(Components.interfaces.nsIWritablePropertyBag);
++ this.update.setProperty("foregroundDownload", "true");
++
++ this.aus.pauseDownload();
++ let state = this.aus.downloadUpdate(this.update, false);
++ if (state == "failed") {
++ this.selectPanel("downloadFailed");
++ return;
++ }
++
++ this.setupDownloadingUI();
++ },
++
++ /**
++ * Switches to the UI responsible for tracking the download.
++ */
++ setupDownloadingUI: function() {
++ this.downloadStatus = document.getElementById("downloadStatus");
++ this.downloadStatus.value =
++ DownloadUtils.getTransferTotal(0, this.update.selectedPatch.size);
++ this.selectPanel("downloading");
++ this.aus.addDownloadListener(this);
++ },
++
++ removeDownloadListener: function() {
++ if (this.aus) {
++ this.aus.removeDownloadListener(this);
++ }
++ },
++
++ /**
++ * See nsIRequestObserver.idl
++ */
++ onStartRequest: function(aRequest, aContext) {
++ },
++
++ /**
++ * See nsIRequestObserver.idl
++ */
++ onStopRequest: function(aRequest, aContext, aStatusCode) {
++ switch (aStatusCode) {
++ case Components.results.NS_ERROR_UNEXPECTED:
++ if (this.update.selectedPatch.state == "download-failed" &&
++ (this.update.isCompleteUpdate || this.update.patchCount != 2)) {
++ // Verification error of complete patch, informational text is held in
++ // the update object.
++ this.removeDownloadListener();
++ this.selectPanel("downloadFailed");
++ break;
++ }
++ // Verification failed for a partial patch, complete patch is now
++ // downloading so return early and do NOT remove the download listener!
++ break;
++ case Components.results.NS_BINDING_ABORTED:
++ // Do not remove UI listener since the user may resume downloading again.
++ break;
++ case Components.results.NS_OK:
++ this.removeDownloadListener();
++ if (this.backgroundUpdateEnabled) {
++ this.selectPanel("applying");
++ let update = this.um.activeUpdate;
++ let self = this;
++ Services.obs.addObserver(function (aSubject, aTopic, aData) {
++ // Update the UI when the background updater is finished
++ let status = aData;
++ if (status == "applied" || status == "applied-service" ||
++ status == "pending" || status == "pending-service") {
++ // If the update is successfully applied, or if the updater has
++ // fallen back to non-staged updates, show the "Restart to Update"
++ // button.
++ self.selectPanel("apply");
++ } else if (status == "failed") {
++ // Background update has failed, let's show the UI responsible for
++ // prompting the user to update manually.
++ self.selectPanel("downloadFailed");
++ } else if (status == "downloading") {
++ // We've fallen back to downloading the full update because the
++ // partial update failed to get staged in the background.
++ // Therefore we need to keep our observer.
++ self.setupDownloadingUI();
++ return;
++ }
++ Services.obs.removeObserver(arguments.callee, "update-staged");
++ }, "update-staged", false);
++ } else {
++ this.selectPanel("apply");
++ }
++ break;
++ default:
++ this.removeDownloadListener();
++ this.selectPanel("downloadFailed");
++ break;
++ }
++ },
++
++ /**
++ * See nsIProgressEventSink.idl
++ */
++ onStatus: function(aRequest, aContext, aStatus, aStatusArg) {
++ },
++
++ /**
++ * See nsIProgressEventSink.idl
++ */
++ onProgress: function(aRequest, aContext, aProgress, aProgressMax) {
++ this.downloadStatus.value =
++ DownloadUtils.getTransferTotal(aProgress, aProgressMax);
++ },
++
++ /**
++ * See nsISupports.idl
++ */
++ QueryInterface: function(aIID) {
++ if (!aIID.equals(Components.interfaces.nsIProgressEventSink) &&
++ !aIID.equals(Components.interfaces.nsIRequestObserver) &&
++ !aIID.equals(Components.interfaces.nsISupports))
++ throw Components.results.NS_ERROR_NO_INTERFACE;
++ return this;
++ }
++};
+diff --git a/im/content/aboutDialog.css b/im/content/aboutDialog.css
+index 2507060..a065c8e 100644
+--- a/im/content/aboutDialog.css
++++ b/im/content/aboutDialog.css
+@@ -1,66 +1,91 @@
++/* This Source Code Form is subject to the terms of the Mozilla Public
++ * License, v. 2.0. If a copy of the MPL was not distributed with this
++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
++
+ #aboutDialog {
+- padding: 0px 0px 10px 0px;
++ width: 620px;
+ }
+
+-#modes {
+- min-height: 380px;
++#rightBox {
++ background-image: url("chrome://branding/content/about-wordmark.png");
++ background-position: left top;
++ background-repeat: no-repeat;
++ /* padding-top creates room for the wordmark */
++ padding-top: 38px;
++ margin-top:20px;
+ }
+
+-#clientBox {
+- background-color: #FFFFFF;
+- background-image: url("chrome://branding/content/about.png");
+- background-repeat: no-repeat;
+- padding-top: 220px;
+- color: #000000;
++#rightBox:-moz-locale-dir(rtl) {
++ background-position: 100% 0;
+ }
+
+-#versionWrapper {
+- margin: 0px 0px 3px 20px;
++#bottomBox > hbox:not(#newBottom) {
++ display: none;
+ }
+
+-#versionField {
+- background-color: #FFFFFF;
+- -moz-appearance: none;
+- border: none;
++#version {
+ font-weight: bold;
+- color: #909090;
++ margin-top: 10px;
++ -moz-margin-start: 0;
++ -moz-user-select: text;
++ -moz-user-focus: normal;
++ cursor: text;
+ }
+
+-#geckoVersionField,
+-#libpurpleVersionField {
+- background-color: #FFFFFF;
+- -moz-appearance: none;
+- border: none;
+- color: #909090;
+- padding-top: 3px !important;
+- padding-left: 10px !important;
++#version:-moz-locale-dir(rtl) {
++ direction: ltr;
++ text-align: right;
++ margin-right: 0;
+ }
+
+-#copyright {
+- margin: 10px 20px 3px 20px;
++#distribution,
++#distributionId {
++ display: none;
++ margin-top: 0;
++ margin-bottom: 0;
+ }
+
+-#userAgentField {
+- margin: 0px 0px 3px 20px !important;
+- background-color: #FFFFFF;
+- -moz-appearance: none;
+- border: none;
++.text-blurb {
++ margin-bottom: 10px;
++ -moz-margin-start: 0;
++ -moz-padding-start: 0;
+ }
+
+-#groove {
+- margin-top: 0px;
++#updateButton,
++#updateDeck > hbox > label {
++ -moz-margin-start: 0;
++ -moz-padding-start: 0;
+ }
+
+-#creditsIframe {
+- cursor: default;
+- -moz-user-select: none;
++.update-throbber {
++ width: 16px;
++ min-height: 16px;
++ -moz-margin-end: 3px;
++ list-style-image: url("chrome://global/skin/icons/loading_16.png");
+ }
+
+-button[dlgtype="extra2"] {
+- margin-left: 13px;
++.text-link,
++.text-link:focus {
++ margin: 0px;
++ padding: 0px;
+ }
+
+-button[dlgtype="accept"] {
+- margin-right: 13px;
++.bottom-link,
++.bottom-link:focus {
++ text-align: center;
++ margin: 0 40px;
+ }
+
++#currentChannel {
++ margin: 0;
++ padding: 0;
++ font-weight: bold;
++}
++
++#trademarkTor {
++ font-size: xx-small;
++ text-align: center;
++ color: #999999;
++ margin-top: 10px;
++ margin-bottom: 10px;
++}
+diff --git a/im/content/aboutDialog.js b/im/content/aboutDialog.js
+new file mode 100644
+index 0000000..b3ae0de
+--- /dev/null
++++ b/im/content/aboutDialog.js
+@@ -0,0 +1,79 @@
++/* This Source Code Form is subject to the terms of the Mozilla Public
++ * License, v. 2.0. If a copy of the MPL was not distributed with this
++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
++
++// Services = object with smart getters for common XPCOM services
++Components.utils.import("resource://gre/modules/Services.jsm");
++Components.utils.import("resource://gre/modules/AppConstants.jsm");
++
++const PREF_EM_HOTFIX_ID = "extensions.hotfix.id";
++
++#ifdef TOR_BROWSER_VERSION
++# Add double-quotes back on (stripped by JarMaker.py).
++#expand const TOR_BROWSER_VERSION = "__TOR_BROWSER_VERSION__";
++#endif
++
++function init(aEvent)
++{
++ if (aEvent.target != document)
++ return;
++
++ try {
++ var distroId = Services.prefs.getCharPref("distribution.id");
++ if (distroId) {
++ var distroVersion = Services.prefs.getCharPref("distribution.version");
++
++ var distroIdField = document.getElementById("distributionId");
++ distroIdField.value = distroId + " - " + distroVersion;
++ distroIdField.style.display = "block";
++
++ try {
++ // This is in its own try catch due to bug 895473 and bug 900925.
++ var distroAbout = Services.prefs.getComplexValue("distribution.about",
++ Components.interfaces.nsISupportsString);
++ var distroField = document.getElementById("distribution");
++ distroField.value = distroAbout;
++ distroField.style.display = "block";
++ }
++ catch (ex) {
++ // Pref is unset
++ Components.utils.reportError(ex);
++ }
++ }
++ }
++ catch (e) {
++ // Pref is unset
++ }
++
++ // Include the build ID and display warning if this is an "a#" (nightly or aurora) build
++ let version = Services.appinfo.version;
++ if (/a\d+$/.test(version)) {
++ document.getElementById("experimental").hidden = false;
++ document.getElementById("communityDesc").hidden = true;
++ }
++
++#ifdef TOR_BROWSER_VERSION
++ let versionElem = document.getElementById("version");
++ if (versionElem) {
++ versionElem.textContent = TOR_BROWSER_VERSION +
++ " (based on Instantbird Nightly)";
++ }
++#endif
++
++ if (AppConstants.MOZ_UPDATER) {
++ gAppUpdater = new appUpdater();
++
++ let defaults = Services.prefs.getDefaultBranch("");
++ let channelLabel = document.getElementById("currentChannel");
++ let currentChannelText = document.getElementById("currentChannelText");
++ channelLabel.value = UpdateUtils.UpdateChannel;
++ if (/^release($|\-)/.test(channelLabel.value))
++ currentChannelText.hidden = true;
++ }
++
++ if (AppConstants.platform == "macosx") {
++ // it may not be sized at this point, and we need its width to calculate its position
++ window.sizeToContent();
++ window.moveTo((screen.availWidth / 2) - (window.outerWidth / 2), screen.availHeight / 5);
++ }
++}
+diff --git a/im/content/aboutDialog.xul b/im/content/aboutDialog.xul
+index aa3b80e..ba924b9 100644
+--- a/im/content/aboutDialog.xul
++++ b/im/content/aboutDialog.xul
+@@ -1,130 +1,173 @@
+ <?xml version="1.0"?> <!-- -*- Mode: HTML -*- -->
++
+ # This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+ <?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+ <?xml-stylesheet href="chrome://instantbird/content/aboutDialog.css" type="text/css"?>
+-#ifdef XP_MACOSX
+-<?xul-overlay href="chrome://instantbird/content/menus.xul"?>
+-#endif
++<?xml-stylesheet href="chrome://branding/content/aboutDialog.css" type="text/css"?>
+
+ <!DOCTYPE window [
+ <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
+ %brandDTD;
+ <!ENTITY % aboutDialogDTD SYSTEM "chrome://instantbird/locale/aboutDialog.dtd" >
+ %aboutDialogDTD;
+-<!ENTITY copyrightYear "2015">
++]>
++
+ #ifdef XP_MACOSX
+- <!ENTITY % instantbirdDTD SYSTEM "chrome://instantbird/locale/instantbird.dtd">
+- %instantbirdDTD;
++<?xul-overlay href="chrome://instantbird/content/macBrowserOverlay.xul"?>
+ #endif
+-]>
+
+-<dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
++<window xmlns:html="http://www.w3.org/1999/xhtml"
++ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ id="aboutDialog"
+- windowtype="Messenger:About"
+- buttons="accept,extra2"
+- onload="onLoad();"
+- title="&aboutDialog.title;" creditslabel="&credits.label;" creditsaccesskey="&credits.accesskey;"
+- aboutlabel="&aboutLink.label;" aboutaccesskey="&aboutLink.accesskey;" versionlabel="&aboutVersion;"
+- style="width: 299px; height: 330px;">
+-
++ windowtype="Browser:About"
++ onload="init(event);"
++#ifdef MOZ_UPDATER
++ onunload="onUnload(event);"
++#endif
+ #ifdef XP_MACOSX
+-#include menus.xul.inc
++ inwindowmenu="false"
++#else
++ title="&aboutDialog.title;"
+ #endif
++ role="dialog"
++ aria-describedby="version distribution distributionId communityDesc contributeDesc trademark"
++ >
+
+- <script type="application/x-javascript">
+- <![CDATA[
+- var gSelectedPage;
+-
+- function onLoad() {
+- var xai = Components.classes["@mozilla.org/xre/app-info;1"]
+- .getService(Components.interfaces.nsIXULAppInfo);
+-
+- var versionField = document.getElementById("versionField");
+- versionField.value = versionField.value + xai.version
+- + ' (' + xai.appBuildID + ')';
+-
+- versionField = document.getElementById("geckoVersionField");
+- versionField.value = versionField.value + xai.platformVersion
+- + ' (' + xai.platformBuildID + ')';
+-
+- versionField = document.getElementById("libpurpleVersionField");
+- if ("@instantbird.org/libpurple/core;1" in Components.classes) {
+- var pcs = Components.classes["@instantbird.org/libpurple/core;1"]
+- .getService(Components.interfaces.purpleICoreService);
+- versionField.value = versionField.value + pcs.version;
+- }
+- else {
+- versionField.hidden = true;
+- }
+-
+- versionField = document.getElementById("userAgentField");
+- versionField.value = navigator.userAgent;
+-
+- var button = document.documentElement.getButton("extra2");
+- button.setAttribute("label", document.documentElement.getAttribute("creditslabel"));
+- button.setAttribute("accesskey", document.documentElement.getAttribute("creditsaccesskey"));
+- gSelectedPage = 0;
+- button.addEventListener("command", switchPage);
+- document.documentElement.getButton("accept").focus();
+- }
+-
+- function uninit(aEvent)
+- {
+- if (aEvent.target != document)
+- return;
+- var iframe = document.getElementById("creditsIframe");
+- iframe.setAttribute("src", "");
+- }
+-
+- function switchPage(aEvent)
+- {
+- var button = aEvent.target;
+- if (button.localName != "button")
+- return;
+-
+- var iframe = document.getElementById("creditsIframe");
+- if (gSelectedPage == 0) {
+- iframe.setAttribute("src", "chrome://instantbird/content/credits.xhtml");
+- button.setAttribute("label", document.documentElement.getAttribute("aboutlabel"));
+- button.setAttribute("accesskey", document.documentElement.getAttribute("aboutaccesskey"));
+- gSelectedPage = 1;
+- }
+- else {
+- iframe.setAttribute("src", "");
+- button.setAttribute("label", document.documentElement.getAttribute("creditslabel"));
+- button.setAttribute("accesskey", document.documentElement.getAttribute("creditsaccesskey"));
+- gSelectedPage = 0;
+- }
+- var modes = document.getElementById("modes");
+- modes.setAttribute("selectedIndex", gSelectedPage);
+- }
+- ]]>
+- </script>
+-
+- <deck id="modes" flex="1">
+- <vbox flex="1" id="clientBox">
+- <vbox id="versionWrapper" flex="1">
+- <textbox id="versionField" readonly="true" class="plain" tabindex="2"
+- value="&aboutVersion; "/>
+- <textbox id="geckoVersionField" readonly="true" class="plain"
+- tabindex="3" value="&geckoVersion; "/>
+- <textbox id="libpurpleVersionField" readonly="true" class="plain"
+- tabindex="4" value="&libpurpleVersion; "/>
++ <script type="application/javascript" src="chrome://instantbird/content/aboutDialog.js"/>
++#ifdef MOZ_UPDATER
++ <script type="application/javascript" src="chrome://instantbird/content/aboutDialog-appUpdater.js"/>
++#endif
++ <vbox id="aboutDialogContainer">
++ <hbox id="clientBox">
++ <vbox id="leftBox" flex="1"/>
++ <vbox id="rightBox" flex="1">
++#expand <label id="version">__MOZ_APP_VERSION_DISPLAY__</label>
++ <label id="distribution" class="text-blurb"/>
++ <label id="distributionId" class="text-blurb"/>
++
++ <vbox id="detailsBox">
++ <vbox id="updateBox">
++#ifdef MOZ_UPDATER
++ <deck id="updateDeck" orient="vertical">
++ <hbox id="checkForUpdates" align="center">
++ <button id="checkForUpdatesButton" align="start"
++ label="&update.checkForUpdatesButton.label;"
++ accesskey="&update.checkForUpdatesButton.accesskey;"
++ oncommand="gAppUpdater.checkForUpdates();"/>
++ <spacer flex="1"/>
++ </hbox>
++ <hbox id="downloadAndInstall" align="center">
++ <button id="downloadAndInstallButton" align="start"
++ oncommand="gAppUpdater.doUpdate();"/>
++ <!-- label and accesskey will be filled by JS -->
++ <spacer flex="1"/>
++ </hbox>
++ <hbox id="apply" align="center">
++ <button id="updateButton" align="start"
++ label="&update.updateButton.label2;"
++ accesskey="&update.updateButton.accesskey;"
++ oncommand="gAppUpdater.buttonRestartAfterDownload();"/>
++ <spacer flex="1"/>
++ </hbox>
++ <hbox id="applyBillboard" align="center">
++ <button id="applyButtonBillboard" align="start"
++ label="&update.applyButtonBillboard.label;"
++ accesskey="&update.applyButtonBillboard.accesskey;"
++ oncommand="gAppUpdater.buttonApplyBillboard();"/>
++ <spacer flex="1"/>
++ </hbox>
++ <hbox id="checkingForUpdates" align="center">
++ <image class="update-throbber"/><label>&update.checkingForUpdates;</label>
++ </hbox>
++ <hbox id="downloading" align="center">
++ <image class="update-throbber"/><label>&update.downloading.start;</label><label id="downloadStatus"/><label>&update.downloading.end;</label>
++ </hbox>
++ <hbox id="applying" align="center">
++ <image class="update-throbber"/><label>&update.applying;</label>
++ </hbox>
++ <hbox id="downloadFailed" align="center">
++ <label>&update.failed.start;</label><label id="failedLink" class="text-link">&update.failed.linkText;</label><label>&update.failed.end;</label>
++ </hbox>
++ <hbox id="adminDisabled" align="center">
++ <label>&update.adminDisabled;</label>
++ </hbox>
++ <hbox id="noUpdatesFound" align="center">
++ <label>&update.noUpdatesFound;</label>
++ </hbox>
++ <hbox id="otherInstanceHandlingUpdates" align="center">
++ <label>&update.otherInstanceHandlingUpdates;</label>
++ </hbox>
++ <hbox id="manualUpdate" align="center">
++ <label>&update.manual.start;</label><label id="manualLink" class="text-link"/><label>&update.manual.end;</label>
++ </hbox>
++ <hbox id="unsupportedSystem" align="center">
++ <label>&update.unsupported.start;</label><label id="unsupportedLink" class="text-link">&update.unsupported.linkText;</label><label>&update.unsupported.end;</label>
++ </hbox>
++ </deck>
++#endif
++ <description class="text-blurb" id="projectDesc">
++ &project.start;
++ &project.tpoLink;&project.end;
++ </description>
++ <description class="text-blurb" id="helpDesc">
++ &help.donate;
++ <textbox flex="1" class="plain" readonly="true" size="36"
++ value="&help.donateLink;" />
++ </description>
++ <description class="text-blurb" id="getInvolvedLinkDesc">
++ &help.getInvolved;
++ <textbox flex="1" class="plain" readonly="true" size="36"
++ value="&help.getInvolvedLink;" />
++ </description>
++ </vbox>
++
++#ifdef MOZ_UPDATER
++ <description class="text-blurb" id="currentChannelText">
++ &channel.description.start;<label id="currentChannel"/>&channel.description.end;
++ </description>
++#endif
++ <vbox id="experimental" hidden="true">
++ <description class="text-blurb" id="warningDesc">
++ &warningDesc.version;
++#ifdef MOZ_TELEMETRY_ON_BY_DEFAULT
++ &warningDesc.telemetryDesc;
++#endif
++ </description>
++ <description class="text-blurb" id="communityExperimentalDesc">
++ &community.exp.start;<label class="text-link" href="http://www.mozilla.org/">&community.exp.mozillaLink;</label>&community.exp.middle;<label class="text-link" href="about:credits">&community.exp.creditsLink;</label>&community.exp.end;
++ </description>
++ </vbox>
++ <description class="text-blurb" id="communityDesc">
++ &community.start2;<label class="text-link" href="http://www.mozilla.org/">&community.mozillaLink;</label>&community.middle2;<label class="text-link" href="about:credits">&community.creditsLink;</label>&community.end3;
++ </description>
++ <description class="text-blurb" id="contributeDesc">
++ &helpus.start;<label class="text-link" href="https://sendto.mozilla.org/page/contribute/Give-Now?source=mozillaorg_defau…">&helpus.donateLink;</label>&helpus.middle;<label class="text-link" href="http://www.mozilla.org/contribute/">&helpus.getInvolvedLink;</label>&helpus.end;
++ </description>
+ </vbox>
+- <description id="copyright" flex="1">©rightText2;</description>
+- <separator/>
+- <textbox id="userAgentField" readonly="true" class="plain"
+- tabindex="5" multiline="true"/>
+- </vbox>
+-
+- <vbox flex="1" id="creditsBox">
+- <iframe id="creditsIframe" flex="1"/>
+ </vbox>
+- </deck>
++ </hbox>
++ <vbox id="bottomBox">
++ <hbox pack="center">
++ <label class="text-link bottom-link" href="about:license">&bottomLinks.license;</label>
++ <label class="text-link bottom-link" href="about:rights">&bottomLinks.rights;</label>
++ <label class="text-link bottom-link" href="https://www.mozilla.org/privacy/">&bottomLinks.privacy;</label>
++ </hbox>
++ <description id="trademark"></description>
++ </vbox>
++ <description id="trademarkTor" insertafter="trademark">
++ &tor.TrademarkStatement;
++ </description>
++
++ </vbox>
++
++ <keyset>
++ <key keycode="VK_ESCAPE" oncommand="window.close();"/>
++ </keyset>
+
+- <separator class="groove" id="groove"/>
+-
+-</dialog>
++#ifdef XP_MACOSX
++#include browserMountPoints.inc
++#endif
++</window>
+diff --git a/im/content/browserMountPoints.inc b/im/content/browserMountPoints.inc
+new file mode 100644
+index 0000000..e4315b0
+--- /dev/null
++++ b/im/content/browserMountPoints.inc
+@@ -0,0 +1,12 @@
++<stringbundleset id="stringbundleset"/>
++
++<commandset id="mainCommandSet"/>
++<commandset id="baseMenuCommandSet"/>
++<commandset id="placesCommands"/>
++
++<broadcasterset id="mainBroadcasterSet"/>
++
++<keyset id="mainKeyset"/>
++<keyset id="baseMenuKeyset"/>
++
++<menubar id="main-menubar"/>
+\ No newline at end of file
+diff --git a/im/content/jar.mn b/im/content/jar.mn
+index 20ea9dc..b3d9e49 100644
+--- a/im/content/jar.mn
++++ b/im/content/jar.mn
+@@ -10,7 +10,8 @@ instantbird.jar:
+ #endif
+ content/instantbird/aboutDialog.css
+ * content/instantbird/aboutDialog.xul
+- content/instantbird/aboutPanel.xml
++* content/instantbird/aboutDialog.js
++* content/instantbird/aboutDialog-appUpdater.js
+ content/instantbird/account.js
+ content/instantbird/accounts.css
+ content/instantbird/accounts.js
+diff --git a/im/locales/en-US/chrome/instantbird/aboutDialog.dtd b/im/locales/en-US/chrome/instantbird/aboutDialog.dtd
+index ecd8d9d..187cf5c 100644
+--- a/im/locales/en-US/chrome/instantbird/aboutDialog.dtd
++++ b/im/locales/en-US/chrome/instantbird/aboutDialog.dtd
+@@ -1,10 +1,129 @@
+-<!ENTITY aboutDialog.title "About &brandFullName;">
+-<!ENTITY credits.label "Credits">
+-<!ENTITY credits.accesskey "C">
+-<!ENTITY aboutLink.label "< About &brandShortName;">
+-<!ENTITY aboutLink.accesskey "A">
+-<!ENTITY aboutVersion "version">
+-<!ENTITY geckoVersion "Gecko">
+-<!ENTITY libpurpleVersion "libpurple">
+-<!-- Use the ©rightYear; entity to place the current year. -->
+-<!ENTITY copyrightText2 "©2007-©rightYear; Contributors. This program is free software; you can redistribute it and/or modify it under the terms of the GNU GPL license version 2.0 or later.">
++<!-- This Source Code Form is subject to the terms of the Mozilla Public
++ - License, v. 2.0. If a copy of the MPL was not distributed with this
++ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
++<!ENTITY aboutDialog.title "About &brandFullName;">
++
++<!-- LOCALIZATION NOTE (update.checkForUpdatesButton.*, update.updateButton.*, update.applyButtonBillboard.*):
++# Only one button is present at a time.
++# The button when displayed is located directly under the Firefox version in
++# the about dialog (see bug 596813 for screenshots).
++-->
++<!ENTITY update.checkForUpdatesButton.label "Check for updates">
++<!ENTITY update.checkForUpdatesButton.accesskey "C">
++<!ENTITY update.updateButton.label2 "Restart &brandShortName; to Update">
++<!ENTITY update.updateButton.accesskey "R">
++<!ENTITY update.applyButtonBillboard.label "Apply Update…">
++<!ENTITY update.applyButtonBillboard.accesskey "A">
++
++
++<!-- LOCALIZATION NOTE (warningDesc.version): This is a warning about the experimental nature of Nightly and Aurora builds. It is only shown in those versions. -->
++<!ENTITY warningDesc.version "&brandShortName; is experimental and may be unstable.">
++<!-- LOCALIZATION NOTE (warningDesc.telemetryDesc): This is a notification that Nightly/Aurora builds automatically send Telemetry data back to Mozilla. It is only shown in those versions. "It" refers to brandShortName. -->
++<!ENTITY warningDesc.telemetryDesc "It automatically sends information about performance, hardware, usage and customizations back to &vendorShortName; to help make &brandShortName; better.">
++
++<!-- LOCALIZATION NOTE (community.exp.*) This paragraph is shown in "experimental" builds, i.e. Nightly and Aurora builds, instead of the other "community.*" strings below. -->
++<!ENTITY community.exp.start "">
++<!-- LOCALIZATION NOTE (community.exp.mozillaLink): This is a link title that links to http://www.mozilla.org/. -->
++<!ENTITY community.exp.mozillaLink "&vendorShortName;">
++<!ENTITY community.exp.middle " is a ">
++<!-- LOCALIZATION NOTE (community.exp.creditslink): This is a link title that links to about:credits. -->
++<!ENTITY community.exp.creditsLink "global community">
++<!ENTITY community.exp.end " working together to keep the Web open, public and accessible to all.">
++
++<!ENTITY community.start2 "&brandShortName; is designed by ">
++<!-- LOCALIZATION NOTE (community.mozillaLink): This is a link title that links to http://www.mozilla.org/. -->
++<!ENTITY community.mozillaLink "&vendorShortName;">
++<!ENTITY community.middle2 ", a ">
++<!-- LOCALIZATION NOTE (community.creditsLink): This is a link title that links to about:credits. -->
++<!ENTITY community.creditsLink "global community">
++<!ENTITY community.end3 " working together to keep the Web open, public and accessible to all.">
++
++<!ENTITY helpus.start "Want to help? ">
++<!-- LOCALIZATION NOTE (helpus.donateLink): This is a link title that links to https://sendto.mozilla.org/page/contribute/Give-Now?source=mozillaorg_defau…. -->
++<!ENTITY helpus.donateLink "Make a donation">
++<!ENTITY helpus.middle " or ">
++<!-- LOCALIZATION NOTE (helpus.getInvolvedLink): This is a link title that links to http://www.mozilla.org/contribute/. -->
++<!ENTITY helpus.getInvolvedLink "get involved!">
++<!ENTITY helpus.end "">
++
++<!-- LOCALIZATION NOTE (bottomLinks.license): This is a link title that links to about:license. -->
++<!ENTITY bottomLinks.license "Licensing Information">
++
++<!-- LOCALIZATION NOTE (bottomLinks.rights): This is a link title that links to about:rights. -->
++<!ENTITY bottomLinks.rights "End-User Rights">
++
++<!-- LOCALIZATION NOTE (bottomLinks.privacy): This is a link title that links to https://www.mozilla.org/legal/privacy/. -->
++<!ENTITY bottomLinks.privacy "Privacy Policy">
++
++<!-- LOCALIZATION NOTE (update.checkingForUpdates): try to make the localized text short (see bug 596813 for screenshots). -->
++<!ENTITY update.checkingForUpdates "Checking for updates…">
++<!-- LOCALIZATION NOTE (update.noUpdatesFound): try to make the localized text short (see bug 596813 for screenshots). -->
++<!ENTITY update.noUpdatesFound "&brandShortName; is up to date">
++<!-- LOCALIZATION NOTE (update.adminDisabled): try to make the localized text short (see bug 596813 for screenshots). -->
++<!ENTITY update.adminDisabled "Updates disabled by your system administrator">
++<!-- LOCALIZATION NOTE (update.otherInstanceHandlingUpdates): try to make the localized text short -->
++<!ENTITY update.otherInstanceHandlingUpdates "&brandShortName; is being updated by another instance">
++
++<!-- LOCALIZATION NOTE (update.failed.start,update.failed.linkText,update.failed.end):
++ update.failed.start, update.failed.linkText, and update.failed.end all go into
++ one line with linkText being wrapped in an anchor that links to a site to download
++ the latest version of Firefox (e.g. http://www.firefox.com) As this is all in
++ one line, try to make the localized text short (see bug 596813 for screenshots). -->
++<!ENTITY update.failed.start "Update failed. ">
++<!ENTITY update.failed.linkText "Download the latest version">
++<!ENTITY update.failed.end "">
++
++<!-- LOCALIZATION NOTE (update.manual.start,update.manual.end): update.manual.start and update.manual.end
++ all go into one line and have an anchor in between with text that is the same as the link to a site
++ to download the latest version of Firefox (e.g. http://www.firefox.com) As this is all in one line,
++ try to make the localized text short (see bug 596813 for screenshots). -->
++<!ENTITY update.manual.start "Updates available at ">
++<!ENTITY update.manual.end "">
++
++<!-- LOCALIZATION NOTE (update.unsupported.start,update.unsupported.linkText,update.unsupported.end):
++ update.unsupported.start, update.unsupported.linkText, and
++ update.unsupported.end all go into one line with linkText being wrapped in
++ an anchor that links to a site to provide additional information regarding
++ why the system is no longer supported. As this is all in one line, try to
++ make the localized text short (see bug 843497 for screenshots). -->
++<!ENTITY update.unsupported.start "You can not perform further updates on this system. ">
++<!ENTITY update.unsupported.linkText "Learn more">
++<!ENTITY update.unsupported.end "">
++
++<!-- LOCALIZATION NOTE (update.downloading.start,update.downloading.end): update.downloading.start and
++ update.downloading.end all go into one line, with the amount downloaded inserted in between. As this
++ is all in one line, try to make the localized text short (see bug 596813 for screenshots). The — is
++ the "em dash" (long dash).
++ example: Downloading update — 111 KB of 13 MB -->
++<!ENTITY update.downloading.start "Downloading update — ">
++<!ENTITY update.downloading.end "">
++
++<!ENTITY update.applying "Applying update…">
++
++<!-- LOCALIZATION NOTE (channel.description.start,channel.description.end): channel.description.start and
++ channel.description.end create one sentence, with the current channel label inserted in between.
++ example: You are currently on the _Stable_ update channel. -->
++<!ENTITY channel.description.start "You are currently on the ">
++<!ENTITY channel.description.end " update channel. ">
++
++<!ENTITY project.start "&brandShortName; is developed by">
++<!-- LOCALIZATION NOTE (project.tpoLink): This is a link title that links to https://www.torproject.org -->
++<!ENTITY project.tpoLink "the &vendorShortName;">
++<!ENTITY project.end ", a nonprofit working to defend your privacy and freedom online.">
++
++<!ENTITY help.start "Want to help? ">
++<!-- LOCALIZATION NOTE (help.donate): This is a link title that links to https://www.torproject.org/donate/donate.html.en -->
++<!ENTITY help.donate "Donate:">
++<!ENTITY help.donateLink "https://www.torproject.org/donate">
++<!ENTITY help.or " or ">
++<!-- LOCALIZATION NOTE (help.getInvolvedLink): This is a link title that links to https://www.torproject.org/getinvolved/volunteer.html.en -->
++<!ENTITY help.getInvolved "Get Involved:">
++<!ENTITY help.getInvolvedLink "https://www.torproject.org/volunteer">
++<!ENTITY help.end "!">
++<!-- LOCALIZATION NOTE (bottom.questions): This is a link title that links to https://www.torproject.org/docs/trademark-faq.html.en -->
++<!ENTITY bottomLinks.questions "Questions?">
++<!-- LOCALIZATION NOTE (bottom.questions): This is a link title that links to https://www.torproject.org/getinvolved/relays -->
++<!ENTITY bottomLinks.grow "Help the Tor Network Grow!">
++<!-- LOCALIZATION NOTE (bottom.questions): This is a link title that links to about:license -->
++<!ENTITY bottomLinks.license "Licensing Information">
++<!ENTITY tor.TrademarkStatement "'Tor' and the 'Onion Logo' are registered trademarks of the Tor Project, Inc.">
+diff --git a/im/locales/en-US/updater/updater.ini b/im/locales/en-US/updater/updater.ini
+index 15ec569..4a2d35d 100644
+--- a/im/locales/en-US/updater/updater.ini
++++ b/im/locales/en-US/updater/updater.ini
+@@ -5,4 +5,4 @@
+ ; This file is in the UTF-8 encoding
+ [Strings]
+ Title=Software Update
+-Info=Instantbird is installing your updates and will start in a few moments…
++Info=Tor Messenger is installing your updates and will start in a few moments…
+--
+2.10.1
+
diff --git a/projects/instantbird/0012-Account-picture.patch b/projects/instantbird/0012-Account-picture.patch
new file mode 100644
index 0000000..1ba2aa3
--- /dev/null
+++ b/projects/instantbird/0012-Account-picture.patch
@@ -0,0 +1,26 @@
+From 378d544200db0ef0c4800117826a988f54f88c88 Mon Sep 17 00:00:00 2001
+From: Sukhbir Singh <sukhbir(a)torproject.org>
+Date: Mon, 10 Oct 2016 19:24:09 -0700
+Subject: [PATCH 12/20] Account picture
+
+---
+ im/content/blist.xul | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/im/content/blist.xul b/im/content/blist.xul
+index b90fdda..f29a48b 100644
+--- a/im/content/blist.xul
++++ b/im/content/blist.xul
+@@ -114,8 +114,7 @@
+ <stack id="statusImageStack">
+ <!-- The box around the user icon is a workaround for bug 955673. -->
+ <box id="userIconHolder">
+- <image id="userIcon" role="button" popup="changeUserIconPanel"
+- aria-label="&userIcon.label;" tooltiptext="&userIcon.label;"/>
++ <image id="userIcon" role="button"/>
+ </box>
+ <panel id="changeUserIconPanel"
+ type="arrow" align="center"
+--
+2.10.1
+
diff --git a/projects/instantbird/0013-Modify-protocol-defaults.patch b/projects/instantbird/0013-Modify-protocol-defaults.patch
new file mode 100644
index 0000000..9f4870e
--- /dev/null
+++ b/projects/instantbird/0013-Modify-protocol-defaults.patch
@@ -0,0 +1,48 @@
+From db0abd7e21663ed4cf92495bf7502b02c882c007 Mon Sep 17 00:00:00 2001
+From: Sukhbir Singh <sukhbir(a)torproject.org>
+Date: Mon, 10 Oct 2016 19:25:34 -0700
+Subject: [PATCH 13/20] Modify protocol defaults
+
+ * Top protocols
+
+ * Hide get protocols
+---
+ im/content/accountWizard.xul | 2 +-
+ im/locales/en-US/chrome/instantbird/accountWizard.properties | 4 +++-
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/im/content/accountWizard.xul b/im/content/accountWizard.xul
+index 759f42b..a306906 100644
+--- a/im/content/accountWizard.xul
++++ b/im/content/accountWizard.xul
+@@ -50,7 +50,7 @@
+ <listbox flex="1" id="protolist"
+ ondblclick="document.getElementById('accountWizard').advance();"/>
+ <hbox pack="end">
+- <label id="getMoreProtocols" class="text-link" value="&accountProtocolGetMore.label;"
++ <label id="getMoreProtocols" class="text-link" value=""
+ onclick="if (event.button == 0) { accountWizard.openURL(this.getAttribute('getMoreURL')); }"/>
+ </hbox>
+ </wizardpage>
+diff --git a/im/locales/en-US/chrome/instantbird/accountWizard.properties b/im/locales/en-US/chrome/instantbird/accountWizard.properties
+index d552a23..7d371bd 100644
+--- a/im/locales/en-US/chrome/instantbird/accountWizard.properties
++++ b/im/locales/en-US/chrome/instantbird/accountWizard.properties
+@@ -8,11 +8,13 @@
+ # Exceeding 4 protocols may cause scrolling. A list of the
+ # available protocols can be found at
+ # https://wiki.instantbird.org/Protocol_Identifiers
+-topProtocol.list=prpl-gtalk,prpl-twitter,prpl-aim,prpl-yahoo,prpl-irc
++topProtocol.list=prpl-irc,prpl-jabber,prpl-twitter,prpl-gtalk
+
+ # LOCALIZATION NOTE
+ # These are the descriptions of the top protocols specified above.
+ # A description should be provided for each protocol ID listed above.
++topProtocol.prpl-irc.description=Connect to your favourite IRC network
++topProtocol.prpl-jabber.description=Chat with friends using XMPP
+ topProtocol.prpl-gtalk.description=Talk to your Gmail contacts
+ topProtocol.prpl-twitter.description=Stay up to date with your Twitter timeline
+ topProtocol.prpl-aim.description=Chat with your buddies on AOL Instant Messenger
+--
+2.10.1
+
diff --git a/projects/instantbird/0014-Modify-IRC-defaults.patch b/projects/instantbird/0014-Modify-IRC-defaults.patch
new file mode 100644
index 0000000..5d010db
--- /dev/null
+++ b/projects/instantbird/0014-Modify-IRC-defaults.patch
@@ -0,0 +1,65 @@
+From f5c55c3d901d8d2174da47078d85622ca6885f9c Mon Sep 17 00:00:00 2001
+From: Sukhbir Singh <sukhbir(a)torproject.org>
+Date: Mon, 10 Oct 2016 19:31:58 -0700
+Subject: [PATCH 14/20] Modify IRC defaults
+
+ * ctcp ping
+
+ * ctcp time
+
+ * irc default server
+---
+ chat/protocols/irc/irc.js | 2 +-
+ chat/protocols/irc/ircCTCP.jsm | 16 ++--------------
+ 2 files changed, 3 insertions(+), 15 deletions(-)
+
+diff --git a/chat/protocols/irc/irc.js b/chat/protocols/irc/irc.js
+index 35165e9..c2167a5 100644
+--- a/chat/protocols/irc/irc.js
++++ b/chat/protocols/irc/irc.js
+@@ -1931,7 +1931,7 @@ ircProtocol.prototype = {
+
+ usernameSplits: [
+ {get label() { return _("options.server"); }, separator: "@",
+- defaultValue: "chat.freenode.net", reverse: true}
++ defaultValue: "", reverse: true}
+ ],
+
+ options: {
+diff --git a/chat/protocols/irc/ircCTCP.jsm b/chat/protocols/irc/ircCTCP.jsm
+index 28eb374..120be10 100644
+--- a/chat/protocols/irc/ircCTCP.jsm
++++ b/chat/protocols/irc/ircCTCP.jsm
+@@ -167,19 +167,7 @@ var ctcpBase = {
+ },
+
+ // Used to measure the delay of the IRC network between clients.
+- "PING": function(aMessage) {
+- // PING timestamp
+- if (aMessage.command == "PRIVMSG") {
+- // Received PING request, send PING response.
+- this.LOG("Received PING request from " + aMessage.origin +
+- ". Sending PING response: \"" + aMessage.ctcp.param + "\".");
+- this.sendCTCPMessage(aMessage.origin, true, "PING",
+- aMessage.ctcp.param);
+- return true;
+- }
+- else
+- return this.handlePingReply(aMessage.origin, aMessage.ctcp.param);
+- },
++ // "PING": function(aMessage) {
+
+ // These are commented out since CLIENTINFO automatically returns the
+ // supported CTCP parameters and this is not supported.
+@@ -195,7 +183,7 @@ var ctcpBase = {
+ if (aMessage.command == "PRIVMSG") {
+ // TIME
+ // Received a TIME request, send a human readable response.
+- let now = (new Date()).toString();
++ let now = (new Date()).toUTCString();
+ this.LOG("Received TIME request from " + aMessage.origin +
+ ". Sending TIME response: \"" + now + "\".");
+ this.sendCTCPMessage(aMessage.origin, true, "TIME", ":" + now);
+--
+2.10.1
+
diff --git a/projects/instantbird/0015-Modify-themes.patch b/projects/instantbird/0015-Modify-themes.patch
new file mode 100644
index 0000000..451eb9d
--- /dev/null
+++ b/projects/instantbird/0015-Modify-themes.patch
@@ -0,0 +1,78 @@
+From 278bce580b808cc6881a3ba5cacee69b8ecb7a13 Mon Sep 17 00:00:00 2001
+From: Sukhbir Singh <sukhbir(a)torproject.org>
+Date: Mon, 10 Oct 2016 19:36:38 -0700
+Subject: [PATCH 15/20] Modify themes
+
+ * theme extension updateh
+
+ * themes remove links
+---
+ .../{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf | 2 ++
+ im/content/preferences/themes.js | 15 ---------------
+ im/content/preferences/themes.xul | 4 ----
+ 3 files changed, 2 insertions(+), 19 deletions(-)
+
+diff --git a/im/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf b/im/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf
+index a7e38bb..c5c781a 100644
+--- a/im/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf
++++ b/im/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf
+@@ -26,6 +26,8 @@
+ <!-- Front End MetaData -->
+ <em:name>Instantbird (default)</em:name>
+ <em:description>The default theme.</em:description>
++ <em:updateURL>data:text/plain,</em:updateURL>
++ <em:updateKey>-</em:updateKey>
+
+ <!-- EXTENSION AUTHORS!
+ DO NOT COPY THIS PROPERTY INTO YOUR INSTALL RDF FILES
+diff --git a/im/content/preferences/themes.js b/im/content/preferences/themes.js
+index 5c5d594..4a9d6af 100644
+--- a/im/content/preferences/themes.js
++++ b/im/content/preferences/themes.js
+@@ -31,21 +31,6 @@ var gThemePane = {
+ default:
+ return;
+ }
+-
+- var getMore = document.getElementById("getMore" + aType);
+- var showGetMore = false;
+- const nsIPrefBranch2 = Components.interfaces.nsIPrefBranch2;
+- if (Services.prefs.getPrefType(prefURL) != nsIPrefBranch2.PREF_INVALID) {
+- try {
+- var getMoreURL = Components.classes["@mozilla.org/toolkit/URLFormatterService;1"]
+- .getService(Components.interfaces.nsIURLFormatter)
+- .formatURLPref(prefURL);
+- getMore.setAttribute("getMoreURL", getMoreURL);
+- showGetMore = getMoreURL != "about:blank";
+- }
+- catch (e) { }
+- }
+- getMore.hidden = !showGetMore;
+ },
+
+ /* Create the drop down list for emoticons and messagestyles;
+diff --git a/im/content/preferences/themes.xul b/im/content/preferences/themes.xul
+index 454e366..18ba1f9 100644
+--- a/im/content/preferences/themes.xul
++++ b/im/content/preferences/themes.xul
+@@ -65,8 +65,6 @@
+ </menupopup>
+ </menulist>
+ <separator orient="vertical" class="thin"/>
+- <label id="getMoreMessageStyles" class="text-link" value="&messageStyleGetMore.label;"
+- onclick="if (event.button == 0) { gThemePane.openURL(this.getAttribute('getMoreURL')); }"/>
+ </hbox>
+ <separator class="thin"/>
+ <label value="&messageStylePreview.label;"/>
+@@ -115,8 +113,6 @@
+ </menupopup>
+ </menulist>
+ <separator orient="vertical" class="thin"/>
+- <label id="getMoreEmoticons" class="text-link" value="&emoticonsGetMore.label;"
+- onclick="if (event.button == 0) { gThemePane.openURL(this.getAttribute('getMoreURL')); }"/>
+ </hbox>
+ <separator class="thin"/>
+ <description>&emoticonsPreview.description;</description>
+--
+2.10.1
+
diff --git a/projects/instantbird/0016-Modify-XMPP-defaults.patch b/projects/instantbird/0016-Modify-XMPP-defaults.patch
new file mode 100644
index 0000000..ac58b3a
--- /dev/null
+++ b/projects/instantbird/0016-Modify-XMPP-defaults.patch
@@ -0,0 +1,48 @@
+From 4199685bb157c9248701353d1da77d43b507f45c Mon Sep 17 00:00:00 2001
+From: Sukhbir Singh <sukhbir(a)torproject.org>
+Date: Mon, 10 Oct 2016 19:38:49 -0700
+Subject: [PATCH 16/20] Modify XMPP defaults
+
+ * xmpp-default-domain
+
+ * xmpp-gtalk-resource
+---
+ chat/protocols/gtalk/gtalk.js | 2 +-
+ chat/protocols/xmpp/xmpp.js | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/chat/protocols/gtalk/gtalk.js b/chat/protocols/gtalk/gtalk.js
+index 8bce0c9..642f456 100644
+--- a/chat/protocols/gtalk/gtalk.js
++++ b/chat/protocols/gtalk/gtalk.js
+@@ -96,7 +96,7 @@ GTalkProtocol.prototype = {
+ getAccount: function(aImAccount) { return new GTalkAccount(this, aImAccount); },
+ options: {
+ resource: {get label() { return _("options.resource"); },
+- get default() { return XMPPDefaultResource; }}
++ default: "Instantbird"},
+ },
+ get chatHasTopic() { return true; },
+ classID: Components.ID("{38a224c1-6748-49a9-8ab2-efc362b1000d}")
+diff --git a/chat/protocols/xmpp/xmpp.js b/chat/protocols/xmpp/xmpp.js
+index 265445a..a5635ca 100644
+--- a/chat/protocols/xmpp/xmpp.js
++++ b/chat/protocols/xmpp/xmpp.js
+@@ -31,12 +31,12 @@ XMPPProtocol.prototype = {
+
+ usernameSplits: [
+ {get label() { return _("options.domain"); }, separator: "@",
+- defaultValue: "jabber.org", reverse: true}
++ defaultValue: "", reverse: true}
+ ],
+
+ options: {
+ resource: {get label() { return _("options.resource"); },
+- get default() { return XMPPDefaultResource; }},
++ default: "Instantbird"},
+ priority: {get label() { return _("options.priority"); }, default: 0},
+ connection_security: {
+ get label() { return _("options.connectionSecurity"); },
+--
+2.10.1
+
diff --git a/projects/instantbird/0017-Remove-logging-UI.patch b/projects/instantbird/0017-Remove-logging-UI.patch
new file mode 100644
index 0000000..a217b9b
--- /dev/null
+++ b/projects/instantbird/0017-Remove-logging-UI.patch
@@ -0,0 +1,43 @@
+From e2f35f7b0b8eba6fcfeee629e6bc37f50c9ee153 Mon Sep 17 00:00:00 2001
+From: Sukhbir Singh <sukhbir(a)torproject.org>
+Date: Mon, 10 Oct 2016 19:50:48 -0700
+Subject: [PATCH 17/20] Remove logging UI
+
+---
+ im/content/preferences/privacy.xul | 20 --------------------
+ 1 file changed, 20 deletions(-)
+
+diff --git a/im/content/preferences/privacy.xul b/im/content/preferences/privacy.xul
+index 7c9db1c..2d7b270 100644
+--- a/im/content/preferences/privacy.xul
++++ b/im/content/preferences/privacy.xul
+@@ -66,26 +66,6 @@
+ preference="purple.conversations.im.send_typing"/>
+ </groupbox>
+
+- <!-- Logs -->
+- <groupbox id="logsGroup">
+- <caption label="&logsGroup.label;"/>
+- <checkbox id="logConversations" label="&logConversations.label;"
+- accesskey="&logConversations.accesskey;"
+- preference="purple.logging.log_ims"
+- onsynctopreference="document.getElementById('purple.logging.log_chats').value = this.checked;"/>
+- <checkbox id="logSystem" label="&logSystem.label;"
+- accesskey="&logSystem.accesskey;"
+- preference="purple.logging.log_system"/>
+- <separator class="thin"/>
+- <hbox align="center">
+- <description control="openLogFolder"
+- flex="1">&logShowFolder.description;</description>
+- <button id="openLogFolder" label="&logShowFolderButton.label;"
+- accesskey="&logShowFolderButton.accesskey;"
+- oncommand="gPrivacyPane.openLogFolder();"/>
+- </hbox>
+- </groupbox>
+-
+ <!-- Passwords -->
+ <groupbox id="passwordsGroup" orient="vertical">
+ <caption label="&passwords.label;"/>
+--
+2.10.1
+
diff --git a/projects/instantbird/0018-Cert-override.patch b/projects/instantbird/0018-Cert-override.patch
new file mode 100644
index 0000000..e995a9d
--- /dev/null
+++ b/projects/instantbird/0018-Cert-override.patch
@@ -0,0 +1,64 @@
+From d97d6ee26187ae8c682a5b25a8772741fae19be2 Mon Sep 17 00:00:00 2001
+From: Sukhbir Singh <sukhbir(a)torproject.org>
+Date: Mon, 10 Oct 2016 19:56:46 -0700
+Subject: [PATCH 18/20] Cert override
+
+---
+ im/app/profile/cert_override.txt | 3 +++
+ im/app/profile/moz.build | 1 +
+ im/installer/Makefile.in | 4 +++-
+ im/installer/package-manifest.in | 1 +
+ 4 files changed, 8 insertions(+), 1 deletion(-)
+ create mode 100644 im/app/profile/cert_override.txt
+
+diff --git a/im/app/profile/cert_override.txt b/im/app/profile/cert_override.txt
+new file mode 100644
+index 0000000..4e616f6
+--- /dev/null
++++ b/im/app/profile/cert_override.txt
+@@ -0,0 +1,3 @@
++# PSM Certificate Override Settings file
++# This is a generated file! Do not edit.
++jabber.ccc.de:5222 OID.2.16.840.1.101.3.4.2.1 59:2F:46:18:35:27:AB:40:83:88:82:AB:4C:B4:AE:F4:E2:CF:91:60:74:AB:01:F9:BC:24:39:31:CA:5C:4E:D1 U AAAAAAAAAAAAAAADAAAAexFL3TB5MRAwDgYDVQQKEwdSb290IENBMR4wHAYDVQQL ExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNBIENlcnQgU2lnbmlu ZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRAY2FjZXJ0Lm9yZw==
+diff --git a/im/app/profile/moz.build b/im/app/profile/moz.build
+index 46bc16b..b7d4ebd 100644
+--- a/im/app/profile/moz.build
++++ b/im/app/profile/moz.build
+@@ -9,6 +9,7 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('gtk2', 'gtk3', 'mac', 'cocoa'):
+ DEFINES['HAVE_SHELL_SERVICE'] = 1
+
+ FINAL_TARGET_FILES.defaults.profile += [
++ 'cert_override.txt',
+ 'localstore.rdf',
+ 'mimeTypes.rdf',
+ ]
+diff --git a/im/installer/Makefile.in b/im/installer/Makefile.in
+index 25dd676..5f06e78 100644
+--- a/im/installer/Makefile.in
++++ b/im/installer/Makefile.in
+@@ -109,7 +109,9 @@ MOZ_PKG_MAC_ICON=branding/disk.icns
+ MOZ_PKG_MAC_EXTRA=--symlink "/Applications:/ "
+ endif
+
+-NON_OMNIJAR_FILES =
++NON_OMNIJAR_FILES = \
++ defaults/profile/cert_override.txt \
++ $(NULL)
+
+ INSTALL_SDK = 1
+
+diff --git a/im/installer/package-manifest.in b/im/installer/package-manifest.in
+index 1174b3d..3e35a2e 100644
+--- a/im/installer/package-manifest.in
++++ b/im/installer/package-manifest.in
+@@ -160,6 +160,7 @@
+ @RESPATH@/defaults/profile/localstore.rdf
+ @RESPATH@/defaults/profile/prefs.js
+ @RESPATH@/defaults/profile/mimeTypes.rdf
++@RESPATH@/defaults/profile/cert_override.txt
+
+ #ifdef XP_MACOSX
+ @RESPATH@/components/ibDockBadge.js
+--
+2.10.1
+
diff --git a/projects/instantbird/0019-Display-all-traffic-over-Tor.patch b/projects/instantbird/0019-Display-all-traffic-over-Tor.patch
new file mode 100644
index 0000000..ef68228
--- /dev/null
+++ b/projects/instantbird/0019-Display-all-traffic-over-Tor.patch
@@ -0,0 +1,38 @@
+From 21ee6198dcd40ce7af5e0baa44c0740114dcfaf4 Mon Sep 17 00:00:00 2001
+From: Sukhbir Singh <sukhbir(a)torproject.org>
+Date: Mon, 10 Oct 2016 19:58:31 -0700
+Subject: [PATCH 19/20] Display all traffic over Tor
+
+---
+ im/content/accountWizard.xul | 2 ++
+ im/locales/en-US/chrome/instantbird/accountWizard.dtd | 1 +
+ 2 files changed, 3 insertions(+)
+
+diff --git a/im/content/accountWizard.xul b/im/content/accountWizard.xul
+index a306906..3c3a417 100644
+--- a/im/content/accountWizard.xul
++++ b/im/content/accountWizard.xul
+@@ -39,6 +39,8 @@
+ <description class="top-proto-description" value="&accountProtocolShowMore.description;"/>
+ </richlistitem>
+ </richlistbox>
++ <separator class="thin"/>
++ <description>&accountProtocolInfo.label3;</description>
+ </wizardpage>
+
+ <wizardpage id="accountprotocol" pageid="accountprotocol" next="accountusername"
+diff --git a/im/locales/en-US/chrome/instantbird/accountWizard.dtd b/im/locales/en-US/chrome/instantbird/accountWizard.dtd
+index c46fb2f..6b49c84 100644
+--- a/im/locales/en-US/chrome/instantbird/accountWizard.dtd
++++ b/im/locales/en-US/chrome/instantbird/accountWizard.dtd
+@@ -6,6 +6,7 @@
+
+ <!ENTITY accountProtocolTitle.label "Protocol">
+ <!ENTITY accountProtocolInfo.label2 "Please choose the protocol of your IM account.">
++<!ENTITY accountProtocolInfo.label3 "All traffic will be routed over the Tor network.">
+ <!ENTITY accountProtocolGetMore.label "Get more…">
+ <!ENTITY accountProtocolShowMore.label "Show all protocols">
+ <!ENTITY accountProtocolShowMore.description "Choose from the full list of protocols">
+--
+2.10.1
+
diff --git a/projects/instantbird/0020-Trac-17480-Content-sink.patch b/projects/instantbird/0020-Trac-17480-Content-sink.patch
new file mode 100644
index 0000000..8279ed5
--- /dev/null
+++ b/projects/instantbird/0020-Trac-17480-Content-sink.patch
@@ -0,0 +1,101 @@
+From fe0c48901086991eb1ba35b1ee391284547cb4dd Mon Sep 17 00:00:00 2001
+From: Arlo Breault <arlolra(a)gmail.com>
+Date: Wed, 5 Oct 2016 11:09:25 -0700
+Subject: [PATCH 20/20] Trac 17480: Content sink
+
+---
+ chat/modules/imContentSink.jsm | 30 +++++-------------------------
+ im/content/preferences/content.xul | 2 +-
+ 2 files changed, 6 insertions(+), 26 deletions(-)
+
+diff --git a/chat/modules/imContentSink.jsm b/chat/modules/imContentSink.jsm
+index ee067af..534f1ef 100644
+--- a/chat/modules/imContentSink.jsm
++++ b/chat/modules/imContentSink.jsm
+@@ -59,10 +59,6 @@ var kStrictMode = {
+ attrs: { },
+
+ tags: {
+- 'a': {
+- 'title': true,
+- 'href': kAllowedURLs
+- },
+ 'br': true,
+ 'p': true
+ },
+@@ -72,12 +68,9 @@ var kStrictMode = {
+
+ // standard mode allows basic formattings (bold, italic, underlined)
+ var kStandardMode = {
+- attrs: {
+- 'style': true
+- },
++ attrs: { },
+
+ tags: {
+- 'div': true,
+ 'a': {
+ 'title': true,
+ 'href': kAllowedURLs
+@@ -87,24 +80,11 @@ var kStandardMode = {
+ 'b': true,
+ 'i': true,
+ 'u': true,
+- 'span': {
+- 'class': kAllowedMozClasses
+- },
+ 'br': true,
+- 'code': true,
+- 'ul': true,
+- 'li': true,
+- 'ol': true,
+- 'cite': true,
+- 'blockquote': true,
+ 'p': true
+ },
+
+- styles: {
+- 'font-style': true,
+- 'font-weight': true,
+- 'text-decoration-line': true
+- }
++ styles: { }
+ };
+
+ // permissive mode allows about anything that isn't going to mess up the chat window
+@@ -158,7 +138,7 @@ var kPermissiveMode = {
+ };
+
+ var kModePref = "messenger.options.filterMode";
+-var kModes = [kStrictMode, kStandardMode, kPermissiveMode];
++var kModes = [kStrictMode, kStandardMode];
+
+ var gGlobalRuleset = null;
+
+@@ -184,8 +164,8 @@ var styleObserver = {
+ function getModePref()
+ {
+ let baseNum = Services.prefs.getIntPref(kModePref);
+- if (baseNum < 0 || baseNum > 2)
+- baseNum = 1;
++ if (baseNum < 0 || baseNum > 1)
++ baseNum = 0;
+
+ return kModes[baseNum];
+ }
+diff --git a/im/content/preferences/content.xul b/im/content/preferences/content.xul
+index 3b8ccfa..ba41da7 100644
+--- a/im/content/preferences/content.xul
++++ b/im/content/preferences/content.xul
+@@ -35,7 +35,7 @@
+ <label control="filterLevel" accesskey="&filterLevel.accesskey;">&filterLevel.label;</label>
+ <menulist id="filterLevel" preference="messenger.options.filterMode">
+ <menupopup>
+- <menuitem value="2" label="&filterLevelAll;"/>
++ <!-- <menuitem value="2" label="&filterLevelAll;"/> -->
+ <menuitem value="1" label="&filterLevelBasic;"/>
+ <menuitem value="0" label="&filterLevelNone;"/>
+ </menupopup>
+--
+2.10.1
+
diff --git a/projects/instantbird/about-logo.png b/projects/instantbird/about-logo.png
deleted file mode 100644
index c6e4c49..0000000
Binary files a/projects/instantbird/about-logo.png and /dev/null differ
diff --git a/projects/instantbird/about-logo(a)2x.png b/projects/instantbird/about-logo(a)2x.png
deleted file mode 100644
index 99d626e..0000000
Binary files a/projects/instantbird/about-logo(a)2x.png and /dev/null differ
diff --git a/projects/instantbird/about-wordmark.png b/projects/instantbird/about-wordmark.png
deleted file mode 100644
index 52923b6..0000000
Binary files a/projects/instantbird/about-wordmark.png and /dev/null differ
diff --git a/projects/instantbird/aboutDialog-appUpdater.js b/projects/instantbird/aboutDialog-appUpdater.js
deleted file mode 100644
index f223f06..0000000
--- a/projects/instantbird/aboutDialog-appUpdater.js
+++ /dev/null
@@ -1,576 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// Note: this file is included in aboutDialog.xul if MOZ_UPDATER is defined.
-
-Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-Components.utils.import("resource://gre/modules/DownloadUtils.jsm");
-Components.utils.import("resource://gre/modules/AddonManager.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils",
- "resource://gre/modules/UpdateUtils.jsm");
-
-var gAppUpdater;
-
-function onUnload(aEvent) {
- if (gAppUpdater.isChecking)
- gAppUpdater.checker.stopChecking(Components.interfaces.nsIUpdateChecker.CURRENT_CHECK);
- // Safe to call even when there isn't a download in progress.
- gAppUpdater.removeDownloadListener();
- gAppUpdater = null;
-}
-
-
-function appUpdater()
-{
- this.updateDeck = document.getElementById("updateDeck");
-
- // Hide the update deck when there is already an update window open to avoid
- // syncing issues between them.
- if (Services.wm.getMostRecentWindow("Update:Wizard")) {
- this.updateDeck.hidden = true;
- return;
- }
-
- XPCOMUtils.defineLazyServiceGetter(this, "aus",
- "@mozilla.org/updates/update-service;1",
- "nsIApplicationUpdateService");
- XPCOMUtils.defineLazyServiceGetter(this, "checker",
- "@mozilla.org/updates/update-checker;1",
- "nsIUpdateChecker");
- XPCOMUtils.defineLazyServiceGetter(this, "um",
- "@mozilla.org/updates/update-manager;1",
- "nsIUpdateManager");
-
- this.bundle = Services.strings.
- createBundle("chrome://browser/locale/browser.properties");
-
- let manualURL = Services.urlFormatter.formatURLPref("app.update.url.manual");
- let manualLink = document.getElementById("manualLink");
- manualLink.value = manualURL;
- manualLink.href = manualURL;
- document.getElementById("failedLink").href = manualURL;
-
- if (this.updateDisabledAndLocked) {
- this.selectPanel("adminDisabled");
- return;
- }
-
- if (this.isPending || this.isApplied) {
- this.selectPanel("apply");
- return;
- }
-
- if (this.aus.isOtherInstanceHandlingUpdates) {
- this.selectPanel("otherInstanceHandlingUpdates");
- return;
- }
-
- if (this.isDownloading) {
- this.startDownload();
- // selectPanel("downloading") is called from setupDownloadingUI().
- return;
- }
-
- // Honor the "Never check for updates" option by not only disabling background
- // update checks, but also in the About dialog, by presenting a
- // "Check for updates" button.
- // If updates are found, the user is then asked if he wants to "Update to <version>".
- if (!this.updateEnabled) {
- this.selectPanel("checkForUpdates");
- return;
- }
-
- // That leaves the options
- // "Check for updates, but let me choose whether to install them", and
- // "Automatically install updates".
- // In both cases, we check for updates without asking.
- // In the "let me choose" case, we ask before downloading though, in onCheckComplete.
- this.checkForUpdates();
-}
-
-appUpdater.prototype =
-{
- // true when there is an update check in progress.
- isChecking: false,
-
- // true when there is an update already staged / ready to be applied.
- get isPending() {
- if (this.update) {
- return this.update.state == "pending" ||
- this.update.state == "pending-service";
- }
- return this.um.activeUpdate &&
- (this.um.activeUpdate.state == "pending" ||
- this.um.activeUpdate.state == "pending-service");
- },
-
- // true when there is an update already installed in the background.
- get isApplied() {
- if (this.update)
- return this.update.state == "applied" ||
- this.update.state == "applied-service";
- return this.um.activeUpdate &&
- (this.um.activeUpdate.state == "applied" ||
- this.um.activeUpdate.state == "applied-service");
- },
-
- // true when there is an update download in progress.
- get isDownloading() {
- if (this.update)
- return this.update.state == "downloading";
- return this.um.activeUpdate &&
- this.um.activeUpdate.state == "downloading";
- },
-
- // true when updating is disabled by an administrator.
- get updateDisabledAndLocked() {
- return !this.updateEnabled &&
- Services.prefs.prefIsLocked("app.update.enabled");
- },
-
- // true when updating is enabled.
- get updateEnabled() {
- try {
- return Services.prefs.getBoolPref("app.update.enabled");
- }
- catch (e) { }
- return true; // Firefox default is true
- },
-
- // true when updating in background is enabled.
- get backgroundUpdateEnabled() {
- return this.updateEnabled &&
- gAppUpdater.aus.canStageUpdates;
- },
-
- // true when updating is automatic.
- get updateAuto() {
- try {
- return Services.prefs.getBoolPref("app.update.auto");
- }
- catch (e) { }
- return true; // Firefox default is true
- },
-
- /**
- * Sets the panel of the updateDeck.
- *
- * @param aChildID
- * The id of the deck's child to select, e.g. "apply".
- */
- selectPanel: function(aChildID) {
- let panel = document.getElementById(aChildID);
-
- let button = panel.querySelector("button");
- if (button) {
- if (aChildID == "downloadAndInstall") {
- let updateVersion = gAppUpdater.update.displayVersion;
- button.label = this.bundle.formatStringFromName("update.downloadAndInstallButton.label", [updateVersion], 1);
- button.accessKey = this.bundle.GetStringFromName("update.downloadAndInstallButton.accesskey");
- }
- this.updateDeck.selectedPanel = panel;
- if (!document.commandDispatcher.focusedElement || // don't steal the focus
- document.commandDispatcher.focusedElement.localName == "button") // except from the other buttons
- button.focus();
-
- } else {
- this.updateDeck.selectedPanel = panel;
- }
- },
-
- /**
- * Check for updates
- */
- checkForUpdates: function() {
- this.selectPanel("checkingForUpdates");
- this.isChecking = true;
- this.checker.checkForUpdates(this.updateCheckListener, true);
- // after checking, onCheckComplete() is called
- },
-
- /**
- * Check for addon compat, or start the download right away
- */
- doUpdate: function() {
- // skip the compatibility check if the update doesn't provide appVersion,
- // or the appVersion is unchanged, e.g. nightly update
-#ifdef TOR_BROWSER_UPDATE
- let pkgVersion = TOR_BROWSER_VERSION;
-#else
- let pkgVersion = Services.appinfo.version;
-#endif
- if (!this.update.appVersion ||
- Services.vc.compare(gAppUpdater.update.appVersion, pkgVersion) == 0) {
- this.startDownload();
- } else {
- this.checkAddonCompatibility();
- }
- },
-
- /**
- * Handles oncommand for the "Restart to Update" button
- * which is presented after the download has been downloaded.
- */
- buttonRestartAfterDownload: function() {
- if (!this.isPending && !this.isApplied)
- return;
-
- // Notify all windows that an application quit has been requested.
- let cancelQuit = Components.classes["@mozilla.org/supports-PRBool;1"].
- createInstance(Components.interfaces.nsISupportsPRBool);
- Services.obs.notifyObservers(cancelQuit, "quit-application-requested", "restart");
-
- // Something aborted the quit process.
- if (cancelQuit.data)
- return;
-
- let appStartup = Components.classes["@mozilla.org/toolkit/app-startup;1"].
- getService(Components.interfaces.nsIAppStartup);
-
- // If already in safe mode restart in safe mode (bug 327119)
- if (Services.appinfo.inSafeMode) {
- appStartup.restartInSafeMode(Components.interfaces.nsIAppStartup.eAttemptQuit);
- return;
- }
-
- appStartup.quit(Components.interfaces.nsIAppStartup.eAttemptQuit |
- Components.interfaces.nsIAppStartup.eRestart);
- },
-
- /**
- * Handles oncommand for the "Apply Update…" button
- * which is presented if we need to show the billboard or license.
- */
- buttonApplyBillboard: function() {
- const URI_UPDATE_PROMPT_DIALOG = "chrome://mozapps/content/update/updates.xul";
- var ary = null;
- ary = Components.classes["@mozilla.org/supports-array;1"].
- createInstance(Components.interfaces.nsISupportsArray);
- ary.AppendElement(this.update);
- var openFeatures = "chrome,centerscreen,dialog=no,resizable=no,titlebar,toolbar=no";
- Services.ww.openWindow(null, URI_UPDATE_PROMPT_DIALOG, "", openFeatures, ary);
- window.close(); // close the "About" window; updates.xul takes over.
- },
-
- /**
- * Implements nsIUpdateCheckListener. The methods implemented by
- * nsIUpdateCheckListener are in a different scope from nsIIncrementalDownload
- * to make it clear which are used by each interface.
- */
- updateCheckListener: {
- /**
- * See nsIUpdateService.idl
- */
- onCheckComplete: function(aRequest, aUpdates, aUpdateCount) {
- gAppUpdater.isChecking = false;
- gAppUpdater.update = gAppUpdater.aus.
- selectUpdate(aUpdates, aUpdates.length);
- if (!gAppUpdater.update) {
- gAppUpdater.selectPanel("noUpdatesFound");
- return;
- }
-
- if (gAppUpdater.update.unsupported) {
- if (gAppUpdater.update.detailsURL) {
- let unsupportedLink = document.getElementById("unsupportedLink");
- unsupportedLink.href = gAppUpdater.update.detailsURL;
- }
- gAppUpdater.selectPanel("unsupportedSystem");
- return;
- }
-
- if (!gAppUpdater.aus.canApplyUpdates) {
- gAppUpdater.selectPanel("manualUpdate");
- return;
- }
-
- // Firefox no longer displays a license for updates and the licenseURL
- // check is just in case a distibution does.
- if (gAppUpdater.update.billboardURL || gAppUpdater.update.licenseURL) {
- gAppUpdater.selectPanel("applyBillboard");
- return;
- }
-
- if (gAppUpdater.updateAuto) // automatically download and install
- gAppUpdater.doUpdate();
- else // ask
- gAppUpdater.selectPanel("downloadAndInstall");
- },
-
- /**
- * See nsIUpdateService.idl
- */
- onError: function(aRequest, aUpdate) {
- // Errors in the update check are treated as no updates found. If the
- // update check fails repeatedly without a success the user will be
- // notified with the normal app update user interface so this is safe.
- gAppUpdater.isChecking = false;
- gAppUpdater.selectPanel("noUpdatesFound");
- },
-
- /**
- * See nsISupports.idl
- */
- QueryInterface: function(aIID) {
- if (!aIID.equals(Components.interfaces.nsIUpdateCheckListener) &&
- !aIID.equals(Components.interfaces.nsISupports))
- throw Components.results.NS_ERROR_NO_INTERFACE;
- return this;
- }
- },
-
- /**
- * Checks the compatibility of add-ons for the application update.
- */
- checkAddonCompatibility: function() {
- try {
- var hotfixID = Services.prefs.getCharPref(PREF_EM_HOTFIX_ID);
- }
- catch (e) { }
-
- var self = this;
- AddonManager.getAllAddons(function(aAddons) {
- self.addons = [];
- self.addonsCheckedCount = 0;
- aAddons.forEach(function(aAddon) {
- // Protect against code that overrides the add-ons manager and doesn't
- // implement the isCompatibleWith or the findUpdates method.
- if (!("isCompatibleWith" in aAddon) || !("findUpdates" in aAddon)) {
- let errMsg = "Add-on doesn't implement either the isCompatibleWith " +
- "or the findUpdates method!";
- if (aAddon.id)
- errMsg += " Add-on ID: " + aAddon.id;
- Components.utils.reportError(errMsg);
- return;
- }
-
- // If an add-on isn't appDisabled and isn't userDisabled then it is
- // either active now or the user expects it to be active after the
- // restart. If that is the case and the add-on is not installed by the
- // application and is not compatible with the new application version
- // then the user should be warned that the add-on will become
- // incompatible. If an addon's type equals plugin it is skipped since
- // checking plugins compatibility information isn't supported and
- // getting the scope property of a plugin breaks in some environments
- // (see bug 566787). The hotfix add-on is also ignored as it shouldn't
- // block the user from upgrading.
- try {
-#ifdef TOR_BROWSER_UPDATE
- let compatVersion = self.update.platformVersion;
-#else
- let compatVersion = self.update.appVersion;
-#endif
- if (aAddon.type != "plugin" && aAddon.id != hotfixID &&
- !aAddon.appDisabled && !aAddon.userDisabled &&
- aAddon.scope != AddonManager.SCOPE_APPLICATION &&
- aAddon.isCompatible &&
- !aAddon.isCompatibleWith(compatVersion,
- self.update.platformVersion))
- self.addons.push(aAddon);
- }
- catch (e) {
- Components.utils.reportError(e);
- }
- });
- self.addonsTotalCount = self.addons.length;
- if (self.addonsTotalCount == 0) {
- self.startDownload();
- return;
- }
-
- self.checkAddonsForUpdates();
- });
- },
-
- /**
- * Checks if there are updates for add-ons that are incompatible with the
- * application update.
- */
- checkAddonsForUpdates: function() {
- this.addons.forEach(function(aAddon) {
-#ifdef TOR_BROWSER_UPDATE
- let compatVersion = this.update.platformVersion;
-#else
- let compatVersion = this.update.appVersion;
-#endif
- aAddon.findUpdates(this, AddonManager.UPDATE_WHEN_NEW_APP_DETECTED,
- compatVersion,
- this.update.platformVersion);
- }, this);
- },
-
- /**
- * See XPIProvider.jsm
- */
- onCompatibilityUpdateAvailable: function(aAddon) {
- for (var i = 0; i < this.addons.length; ++i) {
- if (this.addons[i].id == aAddon.id) {
- this.addons.splice(i, 1);
- break;
- }
- }
- },
-
- /**
- * See XPIProvider.jsm
- */
- onUpdateAvailable: function(aAddon, aInstall) {
-#ifdef TOR_BROWSER_UPDATE
- let compatVersion = this.update.platformVersion;
-#else
- let compatVersion = this.update.appVersion;
-#endif
- if (!Services.blocklist.isAddonBlocklisted(aAddon,
- compatVersion,
- this.update.platformVersion)) {
- // Compatibility or new version updates mean the same thing here.
- this.onCompatibilityUpdateAvailable(aAddon);
- }
- },
-
- /**
- * See XPIProvider.jsm
- */
- onUpdateFinished: function(aAddon) {
- ++this.addonsCheckedCount;
-
- if (this.addonsCheckedCount < this.addonsTotalCount)
- return;
-
- if (this.addons.length == 0) {
- // Compatibility updates or new version updates were found for all add-ons
- this.startDownload();
- return;
- }
-
- this.selectPanel("applyBillboard");
- },
-
- /**
- * Starts the download of an update mar.
- */
- startDownload: function() {
- if (!this.update)
- this.update = this.um.activeUpdate;
- this.update.QueryInterface(Components.interfaces.nsIWritablePropertyBag);
- this.update.setProperty("foregroundDownload", "true");
-
- this.aus.pauseDownload();
- let state = this.aus.downloadUpdate(this.update, false);
- if (state == "failed") {
- this.selectPanel("downloadFailed");
- return;
- }
-
- this.setupDownloadingUI();
- },
-
- /**
- * Switches to the UI responsible for tracking the download.
- */
- setupDownloadingUI: function() {
- this.downloadStatus = document.getElementById("downloadStatus");
- this.downloadStatus.value =
- DownloadUtils.getTransferTotal(0, this.update.selectedPatch.size);
- this.selectPanel("downloading");
- this.aus.addDownloadListener(this);
- },
-
- removeDownloadListener: function() {
- if (this.aus) {
- this.aus.removeDownloadListener(this);
- }
- },
-
- /**
- * See nsIRequestObserver.idl
- */
- onStartRequest: function(aRequest, aContext) {
- },
-
- /**
- * See nsIRequestObserver.idl
- */
- onStopRequest: function(aRequest, aContext, aStatusCode) {
- switch (aStatusCode) {
- case Components.results.NS_ERROR_UNEXPECTED:
- if (this.update.selectedPatch.state == "download-failed" &&
- (this.update.isCompleteUpdate || this.update.patchCount != 2)) {
- // Verification error of complete patch, informational text is held in
- // the update object.
- this.removeDownloadListener();
- this.selectPanel("downloadFailed");
- break;
- }
- // Verification failed for a partial patch, complete patch is now
- // downloading so return early and do NOT remove the download listener!
- break;
- case Components.results.NS_BINDING_ABORTED:
- // Do not remove UI listener since the user may resume downloading again.
- break;
- case Components.results.NS_OK:
- this.removeDownloadListener();
- if (this.backgroundUpdateEnabled) {
- this.selectPanel("applying");
- let update = this.um.activeUpdate;
- let self = this;
- Services.obs.addObserver(function (aSubject, aTopic, aData) {
- // Update the UI when the background updater is finished
- let status = aData;
- if (status == "applied" || status == "applied-service" ||
- status == "pending" || status == "pending-service") {
- // If the update is successfully applied, or if the updater has
- // fallen back to non-staged updates, show the "Restart to Update"
- // button.
- self.selectPanel("apply");
- } else if (status == "failed") {
- // Background update has failed, let's show the UI responsible for
- // prompting the user to update manually.
- self.selectPanel("downloadFailed");
- } else if (status == "downloading") {
- // We've fallen back to downloading the full update because the
- // partial update failed to get staged in the background.
- // Therefore we need to keep our observer.
- self.setupDownloadingUI();
- return;
- }
- Services.obs.removeObserver(arguments.callee, "update-staged");
- }, "update-staged", false);
- } else {
- this.selectPanel("apply");
- }
- break;
- default:
- this.removeDownloadListener();
- this.selectPanel("downloadFailed");
- break;
- }
- },
-
- /**
- * See nsIProgressEventSink.idl
- */
- onStatus: function(aRequest, aContext, aStatus, aStatusArg) {
- },
-
- /**
- * See nsIProgressEventSink.idl
- */
- onProgress: function(aRequest, aContext, aProgress, aProgressMax) {
- this.downloadStatus.value =
- DownloadUtils.getTransferTotal(aProgress, aProgressMax);
- },
-
- /**
- * See nsISupports.idl
- */
- QueryInterface: function(aIID) {
- if (!aIID.equals(Components.interfaces.nsIProgressEventSink) &&
- !aIID.equals(Components.interfaces.nsIRequestObserver) &&
- !aIID.equals(Components.interfaces.nsISupports))
- throw Components.results.NS_ERROR_NO_INTERFACE;
- return this;
- }
-};
diff --git a/projects/instantbird/aboutDialog-jar.patch b/projects/instantbird/aboutDialog-jar.patch
deleted file mode 100644
index 96a1498..0000000
--- a/projects/instantbird/aboutDialog-jar.patch
+++ /dev/null
@@ -1,15 +0,0 @@
-diff --git a/im/content/jar.mn b/im/content/jar.mn
---- a/im/content/jar.mn
-+++ b/im/content/jar.mn
-@@ -9,8 +9,9 @@
- % overlay chrome://mozapps/content/update/updates.xul chrome://instantbird/content/softwareUpdateOverlay.xul
- #endif
- content/instantbird/aboutDialog.css
--* content/instantbird/aboutDialog.xul
-- content/instantbird/aboutPanel.xml
-+* content/instantbird/aboutDialog.xul
-+* content/instantbird/aboutDialog.js
-+* content/instantbird/aboutDialog-appUpdater.js
- content/instantbird/account.js
- content/instantbird/accounts.css
- content/instantbird/accounts.js
diff --git a/projects/instantbird/aboutDialog.css b/projects/instantbird/aboutDialog.css
deleted file mode 100644
index a065c8e..0000000
--- a/projects/instantbird/aboutDialog.css
+++ /dev/null
@@ -1,91 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#aboutDialog {
- width: 620px;
-}
-
-#rightBox {
- background-image: url("chrome://branding/content/about-wordmark.png");
- background-position: left top;
- background-repeat: no-repeat;
- /* padding-top creates room for the wordmark */
- padding-top: 38px;
- margin-top:20px;
-}
-
-#rightBox:-moz-locale-dir(rtl) {
- background-position: 100% 0;
-}
-
-#bottomBox > hbox:not(#newBottom) {
- display: none;
-}
-
-#version {
- font-weight: bold;
- margin-top: 10px;
- -moz-margin-start: 0;
- -moz-user-select: text;
- -moz-user-focus: normal;
- cursor: text;
-}
-
-#version:-moz-locale-dir(rtl) {
- direction: ltr;
- text-align: right;
- margin-right: 0;
-}
-
-#distribution,
-#distributionId {
- display: none;
- margin-top: 0;
- margin-bottom: 0;
-}
-
-.text-blurb {
- margin-bottom: 10px;
- -moz-margin-start: 0;
- -moz-padding-start: 0;
-}
-
-#updateButton,
-#updateDeck > hbox > label {
- -moz-margin-start: 0;
- -moz-padding-start: 0;
-}
-
-.update-throbber {
- width: 16px;
- min-height: 16px;
- -moz-margin-end: 3px;
- list-style-image: url("chrome://global/skin/icons/loading_16.png");
-}
-
-.text-link,
-.text-link:focus {
- margin: 0px;
- padding: 0px;
-}
-
-.bottom-link,
-.bottom-link:focus {
- text-align: center;
- margin: 0 40px;
-}
-
-#currentChannel {
- margin: 0;
- padding: 0;
- font-weight: bold;
-}
-
-#trademarkTor {
- font-size: xx-small;
- text-align: center;
- color: #999999;
- margin-top: 10px;
- margin-bottom: 10px;
-}
diff --git a/projects/instantbird/aboutDialog.dtd b/projects/instantbird/aboutDialog.dtd
deleted file mode 100644
index 187cf5c..0000000
--- a/projects/instantbird/aboutDialog.dtd
+++ /dev/null
@@ -1,129 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-<!ENTITY aboutDialog.title "About &brandFullName;">
-
-<!-- LOCALIZATION NOTE (update.checkForUpdatesButton.*, update.updateButton.*, update.applyButtonBillboard.*):
-# Only one button is present at a time.
-# The button when displayed is located directly under the Firefox version in
-# the about dialog (see bug 596813 for screenshots).
--->
-<!ENTITY update.checkForUpdatesButton.label "Check for updates">
-<!ENTITY update.checkForUpdatesButton.accesskey "C">
-<!ENTITY update.updateButton.label2 "Restart &brandShortName; to Update">
-<!ENTITY update.updateButton.accesskey "R">
-<!ENTITY update.applyButtonBillboard.label "Apply Update…">
-<!ENTITY update.applyButtonBillboard.accesskey "A">
-
-
-<!-- LOCALIZATION NOTE (warningDesc.version): This is a warning about the experimental nature of Nightly and Aurora builds. It is only shown in those versions. -->
-<!ENTITY warningDesc.version "&brandShortName; is experimental and may be unstable.">
-<!-- LOCALIZATION NOTE (warningDesc.telemetryDesc): This is a notification that Nightly/Aurora builds automatically send Telemetry data back to Mozilla. It is only shown in those versions. "It" refers to brandShortName. -->
-<!ENTITY warningDesc.telemetryDesc "It automatically sends information about performance, hardware, usage and customizations back to &vendorShortName; to help make &brandShortName; better.">
-
-<!-- LOCALIZATION NOTE (community.exp.*) This paragraph is shown in "experimental" builds, i.e. Nightly and Aurora builds, instead of the other "community.*" strings below. -->
-<!ENTITY community.exp.start "">
-<!-- LOCALIZATION NOTE (community.exp.mozillaLink): This is a link title that links to http://www.mozilla.org/. -->
-<!ENTITY community.exp.mozillaLink "&vendorShortName;">
-<!ENTITY community.exp.middle " is a ">
-<!-- LOCALIZATION NOTE (community.exp.creditslink): This is a link title that links to about:credits. -->
-<!ENTITY community.exp.creditsLink "global community">
-<!ENTITY community.exp.end " working together to keep the Web open, public and accessible to all.">
-
-<!ENTITY community.start2 "&brandShortName; is designed by ">
-<!-- LOCALIZATION NOTE (community.mozillaLink): This is a link title that links to http://www.mozilla.org/. -->
-<!ENTITY community.mozillaLink "&vendorShortName;">
-<!ENTITY community.middle2 ", a ">
-<!-- LOCALIZATION NOTE (community.creditsLink): This is a link title that links to about:credits. -->
-<!ENTITY community.creditsLink "global community">
-<!ENTITY community.end3 " working together to keep the Web open, public and accessible to all.">
-
-<!ENTITY helpus.start "Want to help? ">
-<!-- LOCALIZATION NOTE (helpus.donateLink): This is a link title that links to https://sendto.mozilla.org/page/contribute/Give-Now?source=mozillaorg_defau…. -->
-<!ENTITY helpus.donateLink "Make a donation">
-<!ENTITY helpus.middle " or ">
-<!-- LOCALIZATION NOTE (helpus.getInvolvedLink): This is a link title that links to http://www.mozilla.org/contribute/. -->
-<!ENTITY helpus.getInvolvedLink "get involved!">
-<!ENTITY helpus.end "">
-
-<!-- LOCALIZATION NOTE (bottomLinks.license): This is a link title that links to about:license. -->
-<!ENTITY bottomLinks.license "Licensing Information">
-
-<!-- LOCALIZATION NOTE (bottomLinks.rights): This is a link title that links to about:rights. -->
-<!ENTITY bottomLinks.rights "End-User Rights">
-
-<!-- LOCALIZATION NOTE (bottomLinks.privacy): This is a link title that links to https://www.mozilla.org/legal/privacy/. -->
-<!ENTITY bottomLinks.privacy "Privacy Policy">
-
-<!-- LOCALIZATION NOTE (update.checkingForUpdates): try to make the localized text short (see bug 596813 for screenshots). -->
-<!ENTITY update.checkingForUpdates "Checking for updates…">
-<!-- LOCALIZATION NOTE (update.noUpdatesFound): try to make the localized text short (see bug 596813 for screenshots). -->
-<!ENTITY update.noUpdatesFound "&brandShortName; is up to date">
-<!-- LOCALIZATION NOTE (update.adminDisabled): try to make the localized text short (see bug 596813 for screenshots). -->
-<!ENTITY update.adminDisabled "Updates disabled by your system administrator">
-<!-- LOCALIZATION NOTE (update.otherInstanceHandlingUpdates): try to make the localized text short -->
-<!ENTITY update.otherInstanceHandlingUpdates "&brandShortName; is being updated by another instance">
-
-<!-- LOCALIZATION NOTE (update.failed.start,update.failed.linkText,update.failed.end):
- update.failed.start, update.failed.linkText, and update.failed.end all go into
- one line with linkText being wrapped in an anchor that links to a site to download
- the latest version of Firefox (e.g. http://www.firefox.com) As this is all in
- one line, try to make the localized text short (see bug 596813 for screenshots). -->
-<!ENTITY update.failed.start "Update failed. ">
-<!ENTITY update.failed.linkText "Download the latest version">
-<!ENTITY update.failed.end "">
-
-<!-- LOCALIZATION NOTE (update.manual.start,update.manual.end): update.manual.start and update.manual.end
- all go into one line and have an anchor in between with text that is the same as the link to a site
- to download the latest version of Firefox (e.g. http://www.firefox.com) As this is all in one line,
- try to make the localized text short (see bug 596813 for screenshots). -->
-<!ENTITY update.manual.start "Updates available at ">
-<!ENTITY update.manual.end "">
-
-<!-- LOCALIZATION NOTE (update.unsupported.start,update.unsupported.linkText,update.unsupported.end):
- update.unsupported.start, update.unsupported.linkText, and
- update.unsupported.end all go into one line with linkText being wrapped in
- an anchor that links to a site to provide additional information regarding
- why the system is no longer supported. As this is all in one line, try to
- make the localized text short (see bug 843497 for screenshots). -->
-<!ENTITY update.unsupported.start "You can not perform further updates on this system. ">
-<!ENTITY update.unsupported.linkText "Learn more">
-<!ENTITY update.unsupported.end "">
-
-<!-- LOCALIZATION NOTE (update.downloading.start,update.downloading.end): update.downloading.start and
- update.downloading.end all go into one line, with the amount downloaded inserted in between. As this
- is all in one line, try to make the localized text short (see bug 596813 for screenshots). The — is
- the "em dash" (long dash).
- example: Downloading update — 111 KB of 13 MB -->
-<!ENTITY update.downloading.start "Downloading update — ">
-<!ENTITY update.downloading.end "">
-
-<!ENTITY update.applying "Applying update…">
-
-<!-- LOCALIZATION NOTE (channel.description.start,channel.description.end): channel.description.start and
- channel.description.end create one sentence, with the current channel label inserted in between.
- example: You are currently on the _Stable_ update channel. -->
-<!ENTITY channel.description.start "You are currently on the ">
-<!ENTITY channel.description.end " update channel. ">
-
-<!ENTITY project.start "&brandShortName; is developed by">
-<!-- LOCALIZATION NOTE (project.tpoLink): This is a link title that links to https://www.torproject.org -->
-<!ENTITY project.tpoLink "the &vendorShortName;">
-<!ENTITY project.end ", a nonprofit working to defend your privacy and freedom online.">
-
-<!ENTITY help.start "Want to help? ">
-<!-- LOCALIZATION NOTE (help.donate): This is a link title that links to https://www.torproject.org/donate/donate.html.en -->
-<!ENTITY help.donate "Donate:">
-<!ENTITY help.donateLink "https://www.torproject.org/donate">
-<!ENTITY help.or " or ">
-<!-- LOCALIZATION NOTE (help.getInvolvedLink): This is a link title that links to https://www.torproject.org/getinvolved/volunteer.html.en -->
-<!ENTITY help.getInvolved "Get Involved:">
-<!ENTITY help.getInvolvedLink "https://www.torproject.org/volunteer">
-<!ENTITY help.end "!">
-<!-- LOCALIZATION NOTE (bottom.questions): This is a link title that links to https://www.torproject.org/docs/trademark-faq.html.en -->
-<!ENTITY bottomLinks.questions "Questions?">
-<!-- LOCALIZATION NOTE (bottom.questions): This is a link title that links to https://www.torproject.org/getinvolved/relays -->
-<!ENTITY bottomLinks.grow "Help the Tor Network Grow!">
-<!-- LOCALIZATION NOTE (bottom.questions): This is a link title that links to about:license -->
-<!ENTITY bottomLinks.license "Licensing Information">
-<!ENTITY tor.TrademarkStatement "'Tor' and the 'Onion Logo' are registered trademarks of the Tor Project, Inc.">
diff --git a/projects/instantbird/aboutDialog.js b/projects/instantbird/aboutDialog.js
deleted file mode 100644
index b3ae0de..0000000
--- a/projects/instantbird/aboutDialog.js
+++ /dev/null
@@ -1,79 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// Services = object with smart getters for common XPCOM services
-Components.utils.import("resource://gre/modules/Services.jsm");
-Components.utils.import("resource://gre/modules/AppConstants.jsm");
-
-const PREF_EM_HOTFIX_ID = "extensions.hotfix.id";
-
-#ifdef TOR_BROWSER_VERSION
-# Add double-quotes back on (stripped by JarMaker.py).
-#expand const TOR_BROWSER_VERSION = "__TOR_BROWSER_VERSION__";
-#endif
-
-function init(aEvent)
-{
- if (aEvent.target != document)
- return;
-
- try {
- var distroId = Services.prefs.getCharPref("distribution.id");
- if (distroId) {
- var distroVersion = Services.prefs.getCharPref("distribution.version");
-
- var distroIdField = document.getElementById("distributionId");
- distroIdField.value = distroId + " - " + distroVersion;
- distroIdField.style.display = "block";
-
- try {
- // This is in its own try catch due to bug 895473 and bug 900925.
- var distroAbout = Services.prefs.getComplexValue("distribution.about",
- Components.interfaces.nsISupportsString);
- var distroField = document.getElementById("distribution");
- distroField.value = distroAbout;
- distroField.style.display = "block";
- }
- catch (ex) {
- // Pref is unset
- Components.utils.reportError(ex);
- }
- }
- }
- catch (e) {
- // Pref is unset
- }
-
- // Include the build ID and display warning if this is an "a#" (nightly or aurora) build
- let version = Services.appinfo.version;
- if (/a\d+$/.test(version)) {
- document.getElementById("experimental").hidden = false;
- document.getElementById("communityDesc").hidden = true;
- }
-
-#ifdef TOR_BROWSER_VERSION
- let versionElem = document.getElementById("version");
- if (versionElem) {
- versionElem.textContent = TOR_BROWSER_VERSION +
- " (based on Instantbird Nightly)";
- }
-#endif
-
- if (AppConstants.MOZ_UPDATER) {
- gAppUpdater = new appUpdater();
-
- let defaults = Services.prefs.getDefaultBranch("");
- let channelLabel = document.getElementById("currentChannel");
- let currentChannelText = document.getElementById("currentChannelText");
- channelLabel.value = UpdateUtils.UpdateChannel;
- if (/^release($|\-)/.test(channelLabel.value))
- currentChannelText.hidden = true;
- }
-
- if (AppConstants.platform == "macosx") {
- // it may not be sized at this point, and we need its width to calculate its position
- window.sizeToContent();
- window.moveTo((screen.availWidth / 2) - (window.outerWidth / 2), screen.availHeight / 5);
- }
-}
diff --git a/projects/instantbird/aboutDialog.xul b/projects/instantbird/aboutDialog.xul
deleted file mode 100644
index ba924b9..0000000
--- a/projects/instantbird/aboutDialog.xul
+++ /dev/null
@@ -1,173 +0,0 @@
-<?xml version="1.0"?> <!-- -*- Mode: HTML -*- -->
-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
-<?xml-stylesheet href="chrome://instantbird/content/aboutDialog.css" type="text/css"?>
-<?xml-stylesheet href="chrome://branding/content/aboutDialog.css" type="text/css"?>
-
-<!DOCTYPE window [
-<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
-%brandDTD;
-<!ENTITY % aboutDialogDTD SYSTEM "chrome://instantbird/locale/aboutDialog.dtd" >
-%aboutDialogDTD;
-]>
-
-#ifdef XP_MACOSX
-<?xul-overlay href="chrome://instantbird/content/macBrowserOverlay.xul"?>
-#endif
-
-<window xmlns:html="http://www.w3.org/1999/xhtml"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- id="aboutDialog"
- windowtype="Browser:About"
- onload="init(event);"
-#ifdef MOZ_UPDATER
- onunload="onUnload(event);"
-#endif
-#ifdef XP_MACOSX
- inwindowmenu="false"
-#else
- title="&aboutDialog.title;"
-#endif
- role="dialog"
- aria-describedby="version distribution distributionId communityDesc contributeDesc trademark"
- >
-
- <script type="application/javascript" src="chrome://instantbird/content/aboutDialog.js"/>
-#ifdef MOZ_UPDATER
- <script type="application/javascript" src="chrome://instantbird/content/aboutDialog-appUpdater.js"/>
-#endif
- <vbox id="aboutDialogContainer">
- <hbox id="clientBox">
- <vbox id="leftBox" flex="1"/>
- <vbox id="rightBox" flex="1">
-#expand <label id="version">__MOZ_APP_VERSION_DISPLAY__</label>
- <label id="distribution" class="text-blurb"/>
- <label id="distributionId" class="text-blurb"/>
-
- <vbox id="detailsBox">
- <vbox id="updateBox">
-#ifdef MOZ_UPDATER
- <deck id="updateDeck" orient="vertical">
- <hbox id="checkForUpdates" align="center">
- <button id="checkForUpdatesButton" align="start"
- label="&update.checkForUpdatesButton.label;"
- accesskey="&update.checkForUpdatesButton.accesskey;"
- oncommand="gAppUpdater.checkForUpdates();"/>
- <spacer flex="1"/>
- </hbox>
- <hbox id="downloadAndInstall" align="center">
- <button id="downloadAndInstallButton" align="start"
- oncommand="gAppUpdater.doUpdate();"/>
- <!-- label and accesskey will be filled by JS -->
- <spacer flex="1"/>
- </hbox>
- <hbox id="apply" align="center">
- <button id="updateButton" align="start"
- label="&update.updateButton.label2;"
- accesskey="&update.updateButton.accesskey;"
- oncommand="gAppUpdater.buttonRestartAfterDownload();"/>
- <spacer flex="1"/>
- </hbox>
- <hbox id="applyBillboard" align="center">
- <button id="applyButtonBillboard" align="start"
- label="&update.applyButtonBillboard.label;"
- accesskey="&update.applyButtonBillboard.accesskey;"
- oncommand="gAppUpdater.buttonApplyBillboard();"/>
- <spacer flex="1"/>
- </hbox>
- <hbox id="checkingForUpdates" align="center">
- <image class="update-throbber"/><label>&update.checkingForUpdates;</label>
- </hbox>
- <hbox id="downloading" align="center">
- <image class="update-throbber"/><label>&update.downloading.start;</label><label id="downloadStatus"/><label>&update.downloading.end;</label>
- </hbox>
- <hbox id="applying" align="center">
- <image class="update-throbber"/><label>&update.applying;</label>
- </hbox>
- <hbox id="downloadFailed" align="center">
- <label>&update.failed.start;</label><label id="failedLink" class="text-link">&update.failed.linkText;</label><label>&update.failed.end;</label>
- </hbox>
- <hbox id="adminDisabled" align="center">
- <label>&update.adminDisabled;</label>
- </hbox>
- <hbox id="noUpdatesFound" align="center">
- <label>&update.noUpdatesFound;</label>
- </hbox>
- <hbox id="otherInstanceHandlingUpdates" align="center">
- <label>&update.otherInstanceHandlingUpdates;</label>
- </hbox>
- <hbox id="manualUpdate" align="center">
- <label>&update.manual.start;</label><label id="manualLink" class="text-link"/><label>&update.manual.end;</label>
- </hbox>
- <hbox id="unsupportedSystem" align="center">
- <label>&update.unsupported.start;</label><label id="unsupportedLink" class="text-link">&update.unsupported.linkText;</label><label>&update.unsupported.end;</label>
- </hbox>
- </deck>
-#endif
- <description class="text-blurb" id="projectDesc">
- &project.start;
- &project.tpoLink;&project.end;
- </description>
- <description class="text-blurb" id="helpDesc">
- &help.donate;
- <textbox flex="1" class="plain" readonly="true" size="36"
- value="&help.donateLink;" />
- </description>
- <description class="text-blurb" id="getInvolvedLinkDesc">
- &help.getInvolved;
- <textbox flex="1" class="plain" readonly="true" size="36"
- value="&help.getInvolvedLink;" />
- </description>
- </vbox>
-
-#ifdef MOZ_UPDATER
- <description class="text-blurb" id="currentChannelText">
- &channel.description.start;<label id="currentChannel"/>&channel.description.end;
- </description>
-#endif
- <vbox id="experimental" hidden="true">
- <description class="text-blurb" id="warningDesc">
- &warningDesc.version;
-#ifdef MOZ_TELEMETRY_ON_BY_DEFAULT
- &warningDesc.telemetryDesc;
-#endif
- </description>
- <description class="text-blurb" id="communityExperimentalDesc">
- &community.exp.start;<label class="text-link" href="http://www.mozilla.org/">&community.exp.mozillaLink;</label>&community.exp.middle;<label class="text-link" href="about:credits">&community.exp.creditsLink;</label>&community.exp.end;
- </description>
- </vbox>
- <description class="text-blurb" id="communityDesc">
- &community.start2;<label class="text-link" href="http://www.mozilla.org/">&community.mozillaLink;</label>&community.middle2;<label class="text-link" href="about:credits">&community.creditsLink;</label>&community.end3;
- </description>
- <description class="text-blurb" id="contributeDesc">
- &helpus.start;<label class="text-link" href="https://sendto.mozilla.org/page/contribute/Give-Now?source=mozillaorg_defau…">&helpus.donateLink;</label>&helpus.middle;<label class="text-link" href="http://www.mozilla.org/contribute/">&helpus.getInvolvedLink;</label>&helpus.end;
- </description>
- </vbox>
- </vbox>
- </hbox>
- <vbox id="bottomBox">
- <hbox pack="center">
- <label class="text-link bottom-link" href="about:license">&bottomLinks.license;</label>
- <label class="text-link bottom-link" href="about:rights">&bottomLinks.rights;</label>
- <label class="text-link bottom-link" href="https://www.mozilla.org/privacy/">&bottomLinks.privacy;</label>
- </hbox>
- <description id="trademark"></description>
- </vbox>
- <description id="trademarkTor" insertafter="trademark">
- &tor.TrademarkStatement;
- </description>
-
- </vbox>
-
- <keyset>
- <key keycode="VK_ESCAPE" oncommand="window.close();"/>
- </keyset>
-
-#ifdef XP_MACOSX
-#include browserMountPoints.inc
-#endif
-</window>
diff --git a/projects/instantbird/account-picture.patch b/projects/instantbird/account-picture.patch
deleted file mode 100644
index 77274d1..0000000
--- a/projects/instantbird/account-picture.patch
+++ /dev/null
@@ -1,13 +0,0 @@
-diff --git a/im/content/blist.xul b/im/content/blist.xul
---- a/im/content/blist.xul
-+++ b/im/content/blist.xul
-@@ -114,8 +114,7 @@
- <stack id="statusImageStack">
- <!-- The box around the user icon is a workaround for bug 955673. -->
- <box id="userIconHolder">
-- <image id="userIcon" role="button" popup="changeUserIconPanel"
-- aria-label="&userIcon.label;" tooltiptext="&userIcon.label;"/>
-+ <image id="userIcon" role="button"/>
- </box>
- <panel id="changeUserIconPanel"
- type="arrow" align="center"
diff --git a/projects/instantbird/branding-aboutDialog.css b/projects/instantbird/branding-aboutDialog.css
deleted file mode 100644
index 9a3c04e..0000000
--- a/projects/instantbird/branding-aboutDialog.css
+++ /dev/null
@@ -1,48 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#clientBox {
- background-color: #F7F7F7;
- color: #222222;
-}
-
-#leftBox {
- background-image: url("chrome://branding/content/about-logo.png");
- background-position: right top;
- background-repeat: no-repeat;
- background-size: 180px;
- /* min-width and min-height create room for the logo */
- min-width: 210px;
- min-height: 210px;
- margin-top: 20px;
- -moz-margin-start: 30px;
-}
-
-
-@media (min-resolution: 2dppx) {
- #leftBox {
- background-image: url("chrome://branding/content/about-logo@2x.png");
- }
-}
-
-#rightBox {
- margin-left: 30px;
- margin-right: 30px;
-}
-
-#updateDeck > hbox > label:not([class="text-link"]) {
- color: #909090;
-}
-
-#trademark {
- display: none;
-}
-
-#contributeDesc {
- display: none;
-}
-
-#communityDesc {
- display: none;
-}
diff --git a/projects/instantbird/branding/about.png b/projects/instantbird/branding/about.png
deleted file mode 100644
index 5d7f579..0000000
Binary files a/projects/instantbird/branding/about.png and /dev/null differ
diff --git a/projects/instantbird/branding/blistWindow.ico b/projects/instantbird/branding/blistWindow.ico
deleted file mode 100644
index 83dfe44..0000000
Binary files a/projects/instantbird/branding/blistWindow.ico and /dev/null differ
diff --git a/projects/instantbird/branding/blistWindow.png b/projects/instantbird/branding/blistWindow.png
deleted file mode 100644
index 093a44c..0000000
Binary files a/projects/instantbird/branding/blistWindow.png and /dev/null differ
diff --git a/projects/instantbird/branding/blistWindow16.png b/projects/instantbird/branding/blistWindow16.png
deleted file mode 100644
index fe88908..0000000
Binary files a/projects/instantbird/branding/blistWindow16.png and /dev/null differ
diff --git a/projects/instantbird/branding/blistWindow48.png b/projects/instantbird/branding/blistWindow48.png
deleted file mode 100644
index 3a14f1d..0000000
Binary files a/projects/instantbird/branding/blistWindow48.png and /dev/null differ
diff --git a/projects/instantbird/branding/convWindow.ico b/projects/instantbird/branding/convWindow.ico
deleted file mode 100644
index a22977c..0000000
Binary files a/projects/instantbird/branding/convWindow.ico and /dev/null differ
diff --git a/projects/instantbird/branding/convWindow.png b/projects/instantbird/branding/convWindow.png
deleted file mode 100644
index b550c92..0000000
Binary files a/projects/instantbird/branding/convWindow.png and /dev/null differ
diff --git a/projects/instantbird/branding/convWindow16.png b/projects/instantbird/branding/convWindow16.png
deleted file mode 100644
index b006855..0000000
Binary files a/projects/instantbird/branding/convWindow16.png and /dev/null differ
diff --git a/projects/instantbird/branding/convWindow48.png b/projects/instantbird/branding/convWindow48.png
deleted file mode 100644
index c759149..0000000
Binary files a/projects/instantbird/branding/convWindow48.png and /dev/null differ
diff --git a/projects/instantbird/branding/default.ico b/projects/instantbird/branding/default.ico
deleted file mode 100644
index 51fed13..0000000
Binary files a/projects/instantbird/branding/default.ico and /dev/null differ
diff --git a/projects/instantbird/branding/default.png b/projects/instantbird/branding/default.png
deleted file mode 100644
index fae92d0..0000000
Binary files a/projects/instantbird/branding/default.png and /dev/null differ
diff --git a/projects/instantbird/branding/default16.png b/projects/instantbird/branding/default16.png
deleted file mode 100644
index b436a77..0000000
Binary files a/projects/instantbird/branding/default16.png and /dev/null differ
diff --git a/projects/instantbird/branding/default48.png b/projects/instantbird/branding/default48.png
deleted file mode 100644
index 8381428..0000000
Binary files a/projects/instantbird/branding/default48.png and /dev/null differ
diff --git a/projects/instantbird/branding/instantbird.icns b/projects/instantbird/branding/instantbird.icns
deleted file mode 100644
index 0843171..0000000
Binary files a/projects/instantbird/branding/instantbird.icns and /dev/null differ
diff --git a/projects/instantbird/branding/instantbird.ico b/projects/instantbird/branding/instantbird.ico
deleted file mode 100644
index 51fed13..0000000
Binary files a/projects/instantbird/branding/instantbird.ico and /dev/null differ
diff --git a/projects/instantbird/branding/jar.patch b/projects/instantbird/branding/jar.patch
deleted file mode 100644
index a9648c7..0000000
--- a/projects/instantbird/branding/jar.patch
+++ /dev/null
@@ -1,11 +0,0 @@
-diff --git a/im/branding/messenger/jar.mn b/im/branding/messenger/jar.mn
---- a/im/branding/messenger/jar.mn
-+++ b/im/branding/messenger/jar.mn
-@@ -8,3 +8,7 @@
- content/branding/about-footer.png (content/about-footer.png)
- content/branding/about.png (content/about.png)
- content/branding/icon64.png (content/icon64.png)
-+ content/branding/aboutDialog.css (content/aboutDialog.css)
-+ content/branding/about-logo.png (content/about-logo.png)
-+ content/branding/about-logo(a)2x.png (content/about-logo(a)2x.png)
-+ content/branding/about-wordmark.png (content/about-wordmark.png)
diff --git a/projects/instantbird/branding/name.patch b/projects/instantbird/branding/name.patch
deleted file mode 100644
index 57d3d94..0000000
--- a/projects/instantbird/branding/name.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-diff --git a/im/branding/messenger/branding.nsi b/im/branding/messenger/branding.nsi
-index e5b5348..276722b 100755
---- a/im/branding/messenger/branding.nsi
-+++ b/im/branding/messenger/branding.nsi
-@@ -6,8 +6,8 @@
-
- # BrandFullNameInternal is used for some registry and file system values that
- # should not contain release that may be in the BrandFullName (e.g. Beta 1, etc.)
--!define BrandFullNameInternal "Instantbird"
--!define CompanyName "Instantbird"
--!define URLInfoAbout "http://www.instantbird.com/"
--!define URLUpdateInfo "http://www.instantbird.com/"
-+!define BrandFullNameInternal "Tor Messenger"
-+!define CompanyName "Tor Project"
-+!define URLInfoAbout "https://www.torproject.org"
-+!define URLUpdateInfo "https://www.torproject.org"
-
-diff --git a/im/branding/messenger/locales/en-US/brand.dtd b/im/branding/messenger/locales/en-US/brand.dtd
-index c569ebb..2d6a5d8 100644
---- a/im/branding/messenger/locales/en-US/brand.dtd
-+++ b/im/branding/messenger/locales/en-US/brand.dtd
-@@ -4,7 +4,7 @@
-
- <!-- nightly branding -->
-
--<!ENTITY brandShortName "Instantbird">
--<!ENTITY brandFullName "Instantbird - Nightly">
-+<!ENTITY brandShortName "Tor Messenger">
-+<!ENTITY brandFullName "Tor Messenger - Beta">
- <!ENTITY brandMotto "'Cause geeks can also do magic!">
--<!ENTITY vendorShortName "Instantbird">
-+<!ENTITY vendorShortName "Tor Project">
-diff --git a/im/branding/messenger/locales/en-US/brand.properties b/im/branding/messenger/locales/en-US/brand.properties
-index f949ced..93528a3 100644
---- a/im/branding/messenger/locales/en-US/brand.properties
-+++ b/im/branding/messenger/locales/en-US/brand.properties
-@@ -2,6 +2,6 @@
- # License, v. 2.0. If a copy of the MPL was not distributed with this
- # file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
--brandShortName=Instantbird
--brandFullName=Instantbird - Nightly
--vendorShortName=Instantbird
-+brandShortName=Tor Messenger
-+brandFullName=Tor Messenger - Beta
-+vendorShortName=Tor Project
diff --git a/projects/instantbird/branding/osx.patch b/projects/instantbird/branding/osx.patch
deleted file mode 100644
index 196d671..0000000
--- a/projects/instantbird/branding/osx.patch
+++ /dev/null
@@ -1,9 +0,0 @@
-diff --git a/im/branding/messenger/configure.sh b/im/branding/messenger/configure.sh
---- a/im/branding/messenger/configure.sh
-+++ b/im/branding/messenger/configure.sh
-@@ -2,4 +2,4 @@
- # License, v. 2.0. If a copy of the MPL was not distributed with this
- # file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
--MOZ_APP_DISPLAYNAME=Instantbird
-+MOZ_APP_DISPLAYNAME="Tor Messenger"
diff --git a/projects/instantbird/browserMountPoints.inc b/projects/instantbird/browserMountPoints.inc
deleted file mode 100644
index e4315b0..0000000
--- a/projects/instantbird/browserMountPoints.inc
+++ /dev/null
@@ -1,12 +0,0 @@
-<stringbundleset id="stringbundleset"/>
-
-<commandset id="mainCommandSet"/>
-<commandset id="baseMenuCommandSet"/>
-<commandset id="placesCommands"/>
-
-<broadcasterset id="mainBroadcasterSet"/>
-
-<keyset id="mainKeyset"/>
-<keyset id="baseMenuKeyset"/>
-
-<menubar id="main-menubar"/>
\ No newline at end of file
diff --git a/projects/instantbird/bug-1218193.patch b/projects/instantbird/bug-1218193.patch
deleted file mode 100644
index c540301..0000000
--- a/projects/instantbird/bug-1218193.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-
-# HG changeset patch
-# User Nihanth Subramanya <nhnt11(a)gmail.com>
-# Date 1456270075 28800
-# Node ID 07b10276713c5f9cd891ea6e5b944d985c3f2fc2
-# Parent 599fd18da6c144abcc9b7feec4ee30b92e9d7bfc
-Bug 1218193 - Fix tab strip background colour on OS X. r=aleth
-
-diff --git a/im/themes/tabbrowser-pinstripe/tabbrowser.css b/im/themes/tabbrowser-pinstripe/tabbrowser.css
---- a/im/themes/tabbrowser-pinstripe/tabbrowser.css
-+++ b/im/themes/tabbrowser-pinstripe/tabbrowser.css
-@@ -203,17 +203,17 @@ statusbarpanel#statusbar-display {
- }
-
- .tabbrowser-tab:-moz-lwtheme {
- color: inherit;
- text-shadow: inherit;
- }
-
- .tabbrowser-strip {
-- -moz-appearance: -moz-mac-unified-toolbar;
-+ -moz-appearance: toolbar;
- height: 26px;
- background-repeat: repeat-x;
- }
-
- .tabbrowser-strip:not(:-moz-lwtheme) {
- background-color: -moz-mac-chrome-active;
- }
-
-
diff --git a/projects/instantbird/bug-1246431.patch b/projects/instantbird/bug-1246431.patch
deleted file mode 100644
index 649e5c2..0000000
--- a/projects/instantbird/bug-1246431.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-
-# HG changeset patch
-# User Arlo Breault <arlolra(a)gmail.com>
-# Date 1454792228 28800
-# Node ID 1759abefc9195a9110c89822fcaf051cd05b0132
-# Parent 27b50a06b9b2b977b31f0777ae8f3ea355cc1130
-Bug 1246431 - XMPP createConversation should handle incoming messages from the server properly. r=aleth
-
-diff --git a/chat/protocols/xmpp/xmpp.jsm b/chat/protocols/xmpp/xmpp.jsm
---- a/chat/protocols/xmpp/xmpp.jsm
-+++ b/chat/protocols/xmpp/xmpp.jsm
-@@ -2096,17 +2096,17 @@ var XMPPAccountPrototype = {
- // Checks if conversation is with a participant of a MUC we are in. We do
- // not want to strip the resource as it is of the form room@domain/nick.
- let isMucParticipant = this._mucs.has(convName);
- if (isMucParticipant)
- convName = this.normalizeFullJid(aName);
-
- // Checking that the aName can be parsed and is not broken.
- let jid = this._parseJID(convName);
-- if (!jid || !jid.node || (isMucParticipant && !jid.resource)) {
-+ if (!jid || !jid.domain || (isMucParticipant && (!jid.node || !jid.resource))) {
- this.ERROR("Could not create conversation as jid is broken: " + convName);
- throw "Invalid JID";
- }
-
- if (!this._conv.has(convName)) {
- this._conv.set(convName,
- new this._conversationConstructor(this, convName,
- isMucParticipant));
-
diff --git a/projects/instantbird/bug-1298574.patch b/projects/instantbird/bug-1298574.patch
deleted file mode 100644
index b0a4ae2..0000000
--- a/projects/instantbird/bug-1298574.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-# HG changeset patch
-# User Arlo Breault <arlolra(a)gmail.com>
-# Date 1472399861 25200
-# Sun Aug 28 08:57:41 2016 -0700
-# Branch THUNDERBIRD4530_2016082513_RELBRANCH
-# Node ID 69baf6e1ea1e4c8f4ddf719bff6b542869a99a23
-# Parent f4a50139b69d93674a2fa55b51ab843a66d3fae2
-Bug 1298574 - Set _userVCard own property when downloading vCard fails. r=aleth
- * This prevents an infinite req / res cycle.
-
---HG--
-extra : amend_source : fb94df25b6157ec06dcf8f57b66a484aee243a28
-
-diff --git a/chat/protocols/xmpp/xmpp.jsm b/chat/protocols/xmpp/xmpp.jsm
---- a/chat/protocols/xmpp/xmpp.jsm
-+++ b/chat/protocols/xmpp/xmpp.jsm
-@@ -2231,16 +2231,30 @@ var XMPPAccountPrototype = {
- if (this._userVCard) {
- let binval = this._userVCard.getElement(["PHOTO", "BINVAL"]);
- if (binval && binval.children.length) {
- binval = binval.children[0];
- binval.text = binval.text.replace(/[^A-Za-z0-9\+\/\=]/g, "")
- .replace(/.{74}/g, "$&\n");
- }
- }
-+ else {
-+ // Downloading the vCard failed.
-+ if (this.handleErrors({
-+ itemNotFound: () => false, // OK, no vCard exists yet.
-+ default: () => true
-+ })(aStanza)) {
-+ this.WARN("Unexpected error retrieving the user's vcard, " +
-+ "so we won't attempt to set it either.");
-+ return;
-+ }
-+ // Set this so that we don't get into an infinite loop trying to download
-+ // the vcard again. The check in sendVCard is for hasOwnProperty.
-+ this._userVCard = null;
-+ }
- this._sendVCard();
- },
-
- _cachingUserIcon: false,
- _cacheUserIcon: function() {
- if (this._cachingUserIcon)
- return;
-
diff --git a/projects/instantbird/build b/projects/instantbird/build
index c67ddc5..9b808bc 100644
--- a/projects/instantbird/build
+++ b/projects/instantbird/build
@@ -1,90 +1,67 @@
#!/bin/sh
set -e
rootdir=$(pwd)
+
export SHELL=/bin/sh
export HOME=$rootdir
export MOZ_BUILD_DATE=$(date -d @[% c('timestamp') %] +%Y%m%d%H%M%S)
export SOURCE_DATE_EPOCH=[% c('timestamp') %]
+
[% IF c('var/osx') -%]
[% pc('gcc', 'var/setup', { compiler_tarfile => c('input_files_by_name/gcchost') }) %]
ln -s /var/tmp/dist/gcc/bin/gcc /var/tmp/dist/gcc/bin/cc
[% END -%]
+
[% pc(c('var/compiler'), 'var/setup', { compiler_tarfile => c('input_files_by_name/' _ c('var/compiler')) }) %]
+
mkdir -p /var/tmp/dist
cd /var/tmp/dist
+
[% IF c("var/linux") -%]
tar xf $rootdir/[% c('input_files_by_name/python') %]
export PATH="/var/tmp/dist/python/bin:$PATH"
tar xf $rootdir/[% c('input_files_by_name/binutils') %]
export PATH="/var/tmp/dist/binutils/bin:$PATH"
[% END -%]
+
# LD_BIND_NOW needed to avoid this error:
# undefined symbol: _ZNSt14error_categoryD2Ev
export LD_BIND_NOW=1
+
[% IF c("var/osname") == "linux-i686" -%]
export LDFLAGS=-m32
export CFLAGS=-m32
export CC='gcc -m32'
[% END -%]
+
[% IF c("var/linux") -%]
mkdir -p /var/tmp/dist/yasm/bin
ln -s /usr/bin/yasm-1 /var/tmp/dist/yasm/bin/yasm
export PATH="/var/tmp/dist/yasm/bin:$PATH"
[% END -%]
+
cd $rootdir
mkdir /var/tmp/build
tar -C /var/tmp/build -xf [% project %]-[% c('version') %].tar.[% c('compress_tar') %]
+
mkdir moz
cd moz
tar xf $rootdir/[% c('input_files_by_name/mozilla') %]
mv mozilla-* /var/tmp/build/[% project %]-[% c('version') %]/mozilla
-cd /var/tmp/build/[% project %]-[% c('version') %]
-mkdir im/branding/messenger
-cp -R im/branding/nightly/* im/branding/messenger/
+cd /var/tmp/build/[% project %]-[% c('version') %]
for patch in $(ls -1 $rootdir/*.patch | sort)
do
- patch -p1 < $patch
-done
-for patch in $(ls -1 $rootdir/branding/*.patch | sort)
-do
- patch -p1 < $patch
+ git apply -p1 < $patch
done
-[% IF c("var/osx") -%]
-cp $rootdir/cert_override.txt im/app/profile
-cp $rootdir/browserMountPoints.inc im/content/
-[% END -%]
-
-cp $rootdir/xmppRegister* im/content/
-
-cp $rootdir/branding/default*.png im/branding/messenger/gtk/
-cp $rootdir/branding/convWindow*.png im/branding/messenger/gtk/
-cp $rootdir/branding/blistWindow*.png im/branding/messenger/gtk/
-
-cp $rootdir/branding/blistWindow.ico im/branding/messenger/windows/
-cp $rootdir/branding/convWindow.ico im/branding/messenger/windows/
-cp $rootdir/branding/default.ico im/branding/messenger/windows/
-
-cp $rootdir/branding/instantbird.ico im/branding/messenger/
-cp $rootdir/branding/instantbird.icns im/branding/messenger/
-
-cp $rootdir/about-logo.png im/branding/messenger/content/
-cp $rootdir/about-logo(a)2x.png im/branding/messenger/content/
-cp $rootdir/about-wordmark.png im/branding/messenger/content/
-
-cp $rootdir/branding-aboutDialog.css im/branding/messenger/content/aboutDialog.css
-
-rm im/content/aboutDialog*
-
-cp $rootdir/aboutDialog* im/content/
-cp $rootdir/aboutDialog.dtd im/locales/en-US/chrome/instantbird/aboutDialog.dtd
-
echo '[% c("var/tormessenger_version") %]' > im/config/version.txt
cp $rootdir/[% c('input_files_by_name/mozconfig') %] .mozconfig
echo ac_add_options --with-tor-browser-version='[% c("var/tormessenger_version") %]' >> .mozconfig
-./mozilla/mach build || ./mozilla/mach build
+
+./mozilla/mach build
./mozilla/mach package
+
mv obj-*/dist/instantbird-*.[% c('var/archive_suffix') %] [% dest_dir _ '/' _ c('filename') %]
diff --git a/projects/instantbird/cert-installer.patch b/projects/instantbird/cert-installer.patch
deleted file mode 100644
index b514b9f..0000000
--- a/projects/instantbird/cert-installer.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-diff --git a/im/app/profile/moz.build b/im/app/profile/moz.build
---- a/im/app/profile/moz.build
-+++ b/im/app/profile/moz.build
-@@ -9,6 +9,7 @@
- DEFINES['HAVE_SHELL_SERVICE'] = 1
-
- FINAL_TARGET_FILES.defaults.profile += [
-+ 'cert_override.txt',
- 'localstore.rdf',
- 'mimeTypes.rdf',
- ]
-diff --git a/im/installer/package-manifest.in b/im/installer/package-manifest.in
---- a/im/installer/package-manifest.in
-+++ b/im/installer/package-manifest.in
-@@ -160,6 +160,7 @@
- @RESPATH@/defaults/profile/localstore.rdf
- @RESPATH@/defaults/profile/prefs.js
- @RESPATH@/defaults/profile/mimeTypes.rdf
-+@RESPATH@/defaults/profile/cert_override.txt
-
- #ifdef XP_MACOSX
- @RESPATH@/components/ibDockBadge.js
-diff --git a/im/installer/Makefile.in b/im/installer/Makefile.in
---- a/im/installer/Makefile.in
-+++ b/im/installer/Makefile.in
-@@ -109,7 +109,9 @@
- MOZ_PKG_MAC_EXTRA=--symlink "/Applications:/ "
- endif
-
--NON_OMNIJAR_FILES =
-+NON_OMNIJAR_FILES = \
-+ defaults/profile/cert_override.txt \
-+ $(NULL)
-
- INSTALL_SDK = 1
-
diff --git a/projects/instantbird/cert_override.txt b/projects/instantbird/cert_override.txt
deleted file mode 100644
index 4e616f6..0000000
--- a/projects/instantbird/cert_override.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-# PSM Certificate Override Settings file
-# This is a generated file! Do not edit.
-jabber.ccc.de:5222 OID.2.16.840.1.101.3.4.2.1 59:2F:46:18:35:27:AB:40:83:88:82:AB:4C:B4:AE:F4:E2:CF:91:60:74:AB:01:F9:BC:24:39:31:CA:5C:4E:D1 U AAAAAAAAAAAAAAADAAAAexFL3TB5MRAwDgYDVQQKEwdSb290IENBMR4wHAYDVQQL ExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNBIENlcnQgU2lnbmlu ZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRAY2FjZXJ0Lm9yZw==
diff --git a/projects/instantbird/config b/projects/instantbird/config
index 58c1f85..03b89ae 100644
--- a/projects/instantbird/config
+++ b/projects/instantbird/config
@@ -17,6 +17,7 @@ var:
- imagemagick
- ccache
- yasm
+ - git-core
targets:
windows-i686:
var:
@@ -57,71 +58,26 @@ targets:
- rsync
- sqlite3
input_files:
- - filename: preferences.patch
- - filename: irc-default-server.patch
- - filename: top-protocols.patch
- - filename: disable-links.patch
- - filename: account-picture.patch
- - filename: show-traffic-tor.patch
- - filename: hide-get-protocols.patch
- - filename: ctcp-time.patch
- - filename: ctcp-ping.patch
- - filename: xmpp-inband-registration.patch
- - filename: xmpp-default-domain.patch
- - filename: xmppRegister.js
- - filename: xmppRegister.xul
- - filename: xmpp-gtalk-resource.patch
- - filename: bug-1298574.patch
- - filename: bug-1246431.patch
- - filename: trac-16489.patch
- - filename: trac-17896.patch
- - filename: trac-17494.patch
- - filename: trac-13312.patch
- - filename: search-context-menu.patch
- - filename: search-preferences-xul.patch
- - filename: log-preferences-xul.patch
- - filename: themes-remove-links.patch
- - filename: theme-extension-update.patch
- - filename: branding/blistWindow.png
- - filename: branding/blistWindow16.png
- - filename: branding/blistWindow48.png
- - filename: branding/convWindow.png
- - filename: branding/convWindow16.png
- - filename: branding/convWindow48.png
- - filename: branding/default.png
- - filename: branding/default16.png
- - filename: branding/default48.png
- - filename: branding/blistWindow.ico
- - filename: branding/convWindow.ico
- - filename: branding/default.ico
- - filename: branding/instantbird.ico
- - filename: branding/name.patch
- - filename: branding/instantbird.icns
- - filename: branding/jar.patch
- - filename: branding/about.png
- - filename: aboutDialog.xul
- - filename: aboutDialog.js
- - filename: aboutDialog-appUpdater.js
- - filename: aboutDialog-jar.patch
- - filename: aboutDialog.css
- - filename: aboutDialog.dtd
- - filename: about-logo.png
- - filename: about-logo(a)2x.png
- - filename: about-wordmark.png
- - filename: branding-aboutDialog.css
- - filename: updater-text.patch
- - filename: trac-20207.patch
- enable: '[% c("var/osx") %]'
- - filename: branding/osx.patch
- enable: '[% c("var/osx") %]'
- - filename: bug-1218193.patch
- enable: '[% c("var/osx") %]'
- - filename: cert-installer.patch
- enable: '[% c("var/osx") %]'
- - filename: cert_override.txt
- enable: '[% c("var/osx") %]'
- - filename: browserMountPoints.inc
- enable: '[% c("var/osx") %]'
+ - filename: 0001-Set-Tor-Messenger-preferences.patch
+ - filename: 0002-Trac-16489-Prevent-account-autologin.patch
+ - filename: 0003-Trac-17896-Support-Special-Characters-input-prompt-o.patch
+ - filename: 0004-Trac-17494-Better-error-reporting-for-failed-outgoin.patch
+ - filename: 0005-Trac-13312-OTR-over-Twitter-DMs.patch
+ - filename: 0006-Bug-1218193-Fix-tab-strip-background-colour-on-OS-X..patch
+ - filename: 0007-Bug-1246431-XMPP-createConversation-should-handle-in.patch
+ - filename: 0008-Bug-1298574-Set-_userVCard-own-property-when-downloa.patch
+ - filename: 0009-XMPP-in-band-registration.patch
+ - filename: 0010-Remove-search-from-UI.patch
+ - filename: 0011-Add-Tor-Messenger-branding.patch
+ - filename: 0012-Account-picture.patch
+ - filename: 0013-Modify-protocol-defaults.patch
+ - filename: 0014-Modify-IRC-defaults.patch
+ - filename: 0015-Modify-themes.patch
+ - filename: 0016-Modify-XMPP-defaults.patch
+ - filename: 0017-Remove-logging-UI.patch
+ - filename: 0018-Cert-override.patch
+ - filename: 0019-Display-all-traffic-over-Tor.patch
+ - filename: 0020-Trac-17480-Content-sink.patch
- filename: 'mozconfig-[% c("var/osname") %]'
name: mozconfig
- name: mozilla
diff --git a/projects/instantbird/ctcp-ping.patch b/projects/instantbird/ctcp-ping.patch
deleted file mode 100644
index 9bc452f..0000000
--- a/projects/instantbird/ctcp-ping.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-diff --git a/chat/protocols/irc/ircCTCP.jsm b/chat/protocols/irc/ircCTCP.jsm
---- a/chat/protocols/irc/ircCTCP.jsm
-+++ b/chat/protocols/irc/ircCTCP.jsm
-@@ -167,19 +167,7 @@
- },
-
- // Used to measure the delay of the IRC network between clients.
-- "PING": function(aMessage) {
-- // PING timestamp
-- if (aMessage.command == "PRIVMSG") {
-- // Received PING request, send PING response.
-- this.LOG("Received PING request from " + aMessage.origin +
-- ". Sending PING response: \"" + aMessage.ctcp.param + "\".");
-- this.sendCTCPMessage(aMessage.origin, true, "PING",
-- aMessage.ctcp.param);
-- return true;
-- }
-- else
-- return this.handlePingReply(aMessage.origin, aMessage.ctcp.param);
-- },
-+ // "PING": function(aMessage) {
-
- // These are commented out since CLIENTINFO automatically returns the
- // supported CTCP parameters and this is not supported.
diff --git a/projects/instantbird/ctcp-time.patch b/projects/instantbird/ctcp-time.patch
deleted file mode 100644
index 4336592..0000000
--- a/projects/instantbird/ctcp-time.patch
+++ /dev/null
@@ -1,12 +0,0 @@
-diff --git a/chat/protocols/irc/ircCTCP.jsm b/chat/protocols/irc/ircCTCP.jsm
---- a/chat/protocols/irc/ircCTCP.jsm
-+++ b/chat/protocols/irc/ircCTCP.jsm
-@@ -195,7 +195,7 @@
- if (aMessage.command == "PRIVMSG") {
- // TIME
- // Received a TIME request, send a human readable response.
-- let now = (new Date()).toString();
-+ let now = (new Date()).toUTCString();
- this.LOG("Received TIME request from " + aMessage.origin +
- ". Sending TIME response: \"" + now + "\".");
- this.sendCTCPMessage(aMessage.origin, true, "TIME", ":" + now);
diff --git a/projects/instantbird/disable-links.patch b/projects/instantbird/disable-links.patch
deleted file mode 100644
index 1b559e6..0000000
--- a/projects/instantbird/disable-links.patch
+++ /dev/null
@@ -1,102 +0,0 @@
-From f4b2401ec1f431ea9b90ac0c86106714a94cc3bc Mon Sep 17 00:00:00 2001
-From: Arlo Breault <arlolra(a)gmail.com>
-Date: Wed, 5 Oct 2016 11:09:25 -0700
-Subject: [PATCH] A patch for trac 17480
-
- * url linkification
----
- chat/modules/imContentSink.jsm | 30 +++++-------------------------
- im/content/preferences/content.xul | 2 +-
- 2 files changed, 6 insertions(+), 26 deletions(-)
-
-diff --git a/chat/modules/imContentSink.jsm b/chat/modules/imContentSink.jsm
-index e03c5bb..895ab88 100644
---- a/chat/modules/imContentSink.jsm
-+++ b/chat/modules/imContentSink.jsm
-@@ -59,10 +59,6 @@ var kStrictMode = {
- attrs: { },
-
- tags: {
-- 'a': {
-- 'title': true,
-- 'href': kAllowedURLs
-- },
- 'br': true,
- 'p': true
- },
-@@ -72,12 +68,9 @@ var kStrictMode = {
-
- // standard mode allows basic formattings (bold, italic, underlined)
- var kStandardMode = {
-- attrs: {
-- 'style': true
-- },
-+ attrs: { },
-
- tags: {
-- 'div': true,
- 'a': {
- 'title': true,
- 'href': kAllowedURLs
-@@ -87,24 +80,11 @@ var kStandardMode = {
- 'b': true,
- 'i': true,
- 'u': true,
-- 'span': {
-- 'class': kAllowedMozClasses
-- },
- 'br': true,
-- 'code': true,
-- 'ul': true,
-- 'li': true,
-- 'ol': true,
-- 'cite': true,
-- 'blockquote': true,
- 'p': true
- },
-
-- styles: {
-- 'font-style': true,
-- 'font-weight': true,
-- 'text-decoration-line': true
-- }
-+ styles: { }
- };
-
- // permissive mode allows about anything that isn't going to mess up the chat window
-@@ -158,7 +138,7 @@ var kPermissiveMode = {
- };
-
- var kModePref = "messenger.options.filterMode";
--var kModes = [kStrictMode, kStandardMode, kPermissiveMode];
-+var kModes = [kStrictMode, kStandardMode];
-
- var gGlobalRuleset = null;
-
-@@ -184,8 +164,8 @@ var styleObserver = {
- function getModePref()
- {
- let baseNum = Services.prefs.getIntPref(kModePref);
-- if (baseNum < 0 || baseNum > 2)
-- baseNum = 1;
-+ if (baseNum < 0 || baseNum > 1)
-+ baseNum = 0;
-
- return kModes[baseNum];
- }
-diff --git a/im/content/preferences/content.xul b/im/content/preferences/content.xul
-index 3b8ccfa..ba41da7 100644
---- a/im/content/preferences/content.xul
-+++ b/im/content/preferences/content.xul
-@@ -35,7 +35,7 @@
- <label control="filterLevel" accesskey="&filterLevel.accesskey;">&filterLevel.label;</label>
- <menulist id="filterLevel" preference="messenger.options.filterMode">
- <menupopup>
-- <menuitem value="2" label="&filterLevelAll;"/>
-+ <!-- <menuitem value="2" label="&filterLevelAll;"/> -->
- <menuitem value="1" label="&filterLevelBasic;"/>
- <menuitem value="0" label="&filterLevelNone;"/>
- </menupopup>
---
-2.10.1
-
diff --git a/projects/instantbird/hide-get-protocols.patch b/projects/instantbird/hide-get-protocols.patch
deleted file mode 100644
index 0a06be1..0000000
--- a/projects/instantbird/hide-get-protocols.patch
+++ /dev/null
@@ -1,12 +0,0 @@
-diff --git a/im/content/accountWizard.xul b/im/content/accountWizard.xul
---- a/im/content/accountWizard.xul
-+++ b/im/content/accountWizard.xul
-@@ -50,7 +50,7 @@
- <listbox flex="1" id="protolist"
- ondblclick="document.getElementById('accountWizard').advance();"/>
- <hbox pack="end">
-- <label id="getMoreProtocols" class="text-link" value="&accountProtocolGetMore.label;"
-+ <label id="getMoreProtocols" class="text-link" value=""
- onclick="if (event.button == 0) { accountWizard.openURL(this.getAttribute('getMoreURL')); }"/>
- </hbox>
- </wizardpage>
diff --git a/projects/instantbird/irc-default-server.patch b/projects/instantbird/irc-default-server.patch
deleted file mode 100644
index f05a3ff..0000000
--- a/projects/instantbird/irc-default-server.patch
+++ /dev/null
@@ -1,12 +0,0 @@
-diff --git a/chat/protocols/irc/irc.js b/chat/protocols/irc/irc.js
---- a/chat/protocols/irc/irc.js
-+++ b/chat/protocols/irc/irc.js
-@@ -1931,7 +1931,7 @@
-
- usernameSplits: [
- {get label() { return _("options.server"); }, separator: "@",
-- defaultValue: "chat.freenode.net", reverse: true}
-+ defaultValue: "", reverse: true}
- ],
-
- options: {
diff --git a/projects/instantbird/log-preferences-xul.patch b/projects/instantbird/log-preferences-xul.patch
deleted file mode 100644
index 2c8f6a2..0000000
--- a/projects/instantbird/log-preferences-xul.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-diff --git a/im/content/preferences/privacy.xul b/im/content/preferences/privacy.xul
---- a/im/content/preferences/privacy.xul
-+++ b/im/content/preferences/privacy.xul
-@@ -66,26 +66,6 @@
- preference="purple.conversations.im.send_typing"/>
- </groupbox>
-
-- <!-- Logs -->
-- <groupbox id="logsGroup">
-- <caption label="&logsGroup.label;"/>
-- <checkbox id="logConversations" label="&logConversations.label;"
-- accesskey="&logConversations.accesskey;"
-- preference="purple.logging.log_ims"
-- onsynctopreference="document.getElementById('purple.logging.log_chats').value = this.checked;"/>
-- <checkbox id="logSystem" label="&logSystem.label;"
-- accesskey="&logSystem.accesskey;"
-- preference="purple.logging.log_system"/>
-- <separator class="thin"/>
-- <hbox align="center">
-- <description control="openLogFolder"
-- flex="1">&logShowFolder.description;</description>
-- <button id="openLogFolder" label="&logShowFolderButton.label;"
-- accesskey="&logShowFolderButton.accesskey;"
-- oncommand="gPrivacyPane.openLogFolder();"/>
-- </hbox>
-- </groupbox>
--
- <!-- Passwords -->
- <groupbox id="passwordsGroup" orient="vertical">
- <caption label="&passwords.label;"/>
diff --git a/projects/instantbird/preferences.patch b/projects/instantbird/preferences.patch
deleted file mode 100644
index 2815c79..0000000
--- a/projects/instantbird/preferences.patch
+++ /dev/null
@@ -1,196 +0,0 @@
-diff --git a/im/app/profile/all-instantbird.js b/im/app/profile/all-instantbird.js
---- a/im/app/profile/all-instantbird.js
-+++ b/im/app/profile/all-instantbird.js
-@@ -28,7 +28,7 @@
- // 0 = spellcheck nothing
- // 1 = check multi-line controls [default]
- // 2 = check multi/single line controls
--pref("layout.spellcheckDefault", 1);
-+pref("layout.spellcheckDefault", 0);
-
- pref("messenger.accounts.convertOldPasswords", true);
- pref("messenger.accounts.promptOnDelete", true);
-@@ -66,18 +66,18 @@
-
- // Whether message related sounds should be played at all. If this is enabled
- // then the more specific prefs are checked as well.
--pref("messenger.options.playSounds.message", true);
-+pref("messenger.options.playSounds.message", false);
- // Specifies whether each message event should trigger a sound for incoming
- // and outgoing messages, or when your nickname is mentioned in a chat.
- pref("messenger.options.playSounds.outgoing", true);
- pref("messenger.options.playSounds.incoming", true);
- pref("messenger.options.playSounds.alert", true);
- // Whether contact list related sounds should be played at all. If this is
- // enabled then the more specific prefs are checked as well.
- pref("messenger.options.playSounds.blist", false);
- // Specifies whether sounds should be played on login/logout events.
- pref("messenger.options.playSounds.login", true);
- pref("messenger.options.playSounds.logout", true);
-
- pref("font.default.x-western", "sans-serif");
- pref("font.default.x-unicode", "sans-serif");
-@@ -142,26 +142,28 @@
-
- // Update service URL:
- // You do not need to use all the %VAR% parameters. Use what you need, %PRODUCT%,%VERSION%,%BUILD_ID%,%CHANNEL% for example
--pref("app.update.url", "https://update.instantbird.org/1/%PRODUCT%/%VERSION%/%BUILD_ID%/%BUILD_TARG…");
-+pref("app.update.url", "https://aus2.torproject.org/tormessenger/update_2/%CHANNEL%/%BUILD_TARGET%/…");
-+
-+#ifdef XP_WIN
-+// For now, disable staged updates on Windows (see #18292).
-+pref("app.update.staging.enabled", false);
-+#endif
-
- // URL user can browse to manually if for some reason all update installation
- // attempts fail.
--pref("app.update.url.manual", "http://www.instantbird.com/download.html");
-+pref("app.update.url.manual", "https://www.torproject.org");
-
- // A default value for the "More information about this update" link
- // supplied in the "An update is available" page of the update wizard.
--pref("app.update.url.details", "http://www.instantbird.com/");
--
--// User-settable override to app.update.url for testing purposes.
--//pref("app.update.url.override", "");
-+pref("app.update.url.details", "https://trac.torproject.org/projects/tor/wiki/doc/TorMessenger");
-
- // Interval: Time between checks for a new version (in seconds)
- // default=1 day
--pref("app.update.interval", 86400);
-+pref("app.update.interval", 43200);
-
- // Interval: Time before prompting the user to download a new version that
- // is available (in seconds) default=1 day
--pref("app.update.nagTimer.download", 86400);
-+pref("app.update.nagTimer.download", 3600);
-
- // Interval: Time before prompting the user to restart to install the latest
- // download (in seconds) default=30 minutes
-@@ -202,7 +204,7 @@
- pref("browser.search.order.2", "chrome://instantbird/locale/region.properties");
-
- // send ping to the server to update
--pref("browser.search.update", true);
-+pref("browser.search.update", false);
-
- // disable logging for the search service update system by default
- pref("browser.search.update.log", false);
-@@ -222,7 +224,7 @@
- pref("extensions.logging.enabled", false);
- pref("general.skins.selectedSkin", "classic/1.0");
-
--pref("extensions.update.enabled", true);
-+pref("extensions.update.enabled", false);
- pref("extensions.update.interval", 86400);
- pref("extensions.update.url", "https://addons.instantbird.org/services/update.php?reqVersion=%REQ_VERSION%…");
- pref("extensions.update.autoUpdateDefault", true);
-@@ -245,9 +247,9 @@
- pref("extensions.getMoreProtocolsURL", "https://add-ons.instantbird.org/%LOCALE%/%APP%/%VERSION%/protocols/");
-
- // suppress external-load warning for standard browser schemes
--pref("network.protocol-handler.warn-external.http", false);
--pref("network.protocol-handler.warn-external.https", false);
--pref("network.protocol-handler.warn-external.ftp", false);
-+pref("network.protocol-handler.warn-external.http", true);
-+pref("network.protocol-handler.warn-external.https", true);
-+pref("network.protocol-handler.warn-external.ftp", true);
-
- // don't load links inside Instantbird
- pref("network.protocol-handler.expose-all", false);
-@@ -262,10 +264,10 @@
- pref("network.protocol-handler.expose.javascript", true);
-
- // 0-Accept, 1-dontAcceptForeign, 2-dontUse
--pref("network.cookie.cookieBehavior", 0);
-+pref("network.cookie.cookieBehavior", 1);
-
- // The breakpad report server to link to in about:crashes
--pref("breakpad.reportURL", "http://crash-stats.instantbird.com/report/index/");
-+pref("breakpad.reportURL", "https://crash-stats.instantbird.com/report/index/");
-
- // We have an Error Console menu item by default so let's display chrome errors
- pref("javascript.options.showInConsole", true);
-@@ -300,14 +302,76 @@
- // 3 at the end of the tabstrip
- pref("browser.tabs.closeButtons", 1);
-
--#expand pref("chat.irc.defaultQuitMessage", "Instantbird __APP_VERSION__ -- http://www.instantbird.com");
-+#expand pref("chat.irc.defaultQuitMessage", "");
-
- pref("chat.twitter.consumerKey", "TSuyS1ieRAkB3qWv8yyEw");
- pref("chat.twitter.consumerSecret", "DKtKaSf5a7pBNhdBsSZHTnI5Y03hRlPFYWmb4xXBlkU");
-
- // Comma separated list of prpl ids that should use libpurple even if there is
- // a JS implementation. This is used to land JS-prpls pref'ed off in nightlies.
--pref("chat.prpls.forcePurple", "prpl-jabber");
-+pref("chat.prpls.forcePurple", "");
-
- // Whether to parse log files for conversation statistics.
--pref("statsService.parseLogsForStats", true);
-+pref("statsService.parseLogsForStats", false);
-+
-+/* Tor Messenger */
-+// Logging
-+// Disable all logging
-+pref("purple.logging.log_chats", false);
-+pref("purple.logging.log_ims", false);
-+pref("purple.logging.log_system", false);
-+
-+// Network
-+// Use a manual proxy configuration
-+pref("network.proxy.type", 1);
-+// Empty the "no proxy" setting
-+pref("network.proxy.no_proxies_on", "");
-+// Configure Instantbird to use the SOCKS5 proxy
-+pref("network.proxy.socks", "127.0.0.1");
-+pref("network.proxy.socks_port", 9152);
-+pref("network.proxy.socks_version", 5);
-+// Set DNS proxying through SOCKS5
-+pref("network.proxy.socks_remote_dns", true);
-+// Disable DNS prefetching
-+pref("network.dns.disablePrefetch", true);
-+// Disable SPDY
-+pref("network.http.spdy.enabled", false);
-+// Set the user-agent to Instantbird stable
-+pref("general.useragent.override", "Mozilla/5.0 (Windows NT 6.1; rv:25.0) Gecko/20100101 Instantbird/1.5");
-+
-+// Security
-+// Disable SSLv3 by setting the minimum supported protocol to TLS 1.0.
-+pref("security.tls.version.min", 1);
-+// We use the certdb. Necessary for the TB patch,
-+// "Bug 14716: HTTP Basic Authentication prompt only displayed once"
-+pref("security.nocertdb", false);
-+// Disable geolocation
-+pref("geo.enabled", false);
-+
-+// Do not report idle status or the away message
-+pref("messenger.status.awayWhenIdle", false);
-+pref("messenger.status.defaultIdleAwayMessage", "");
-+pref("messenger.status.reportIdle", false);
-+// Do not send the message format (fonts, colors)
-+pref("messenger.conversations.sendFormat", false);
-+// Disable text formatting (remove the tags)
-+pref("messenger.options.filterMode", 0);
-+// Disable typing notifications
-+pref("purple.conversations.im.send_typing", false);
-+
-+// Browser
-+// Disable caching
-+pref("browser.cache.disk.enable", false);
-+pref("browser.cache.offline.enable", false);
-+
-+// Media
-+// Disable WebRTC
-+pref("media.peerconnection.enabled", false);
-+// Disable "Take Picture" functionality that accesses the webcam
-+pref("media.navigator.video.enabled", false);
-+// Disable hardware acceleration
-+pref("gfx.direct2d.disabled", true);
-+pref("layers.acceleration.disabled", true);
-+
-+// Other Updates
-+pref("app.update.promptWaitTime", 3600);
-+
-+// Put conversations on hold so that OTR disconnect is not sent. See #20208.
-+pref("messenger.conversations.holdByDefault", true);
diff --git a/projects/instantbird/search-context-menu.patch b/projects/instantbird/search-context-menu.patch
deleted file mode 100644
index a27d323..0000000
--- a/projects/instantbird/search-context-menu.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-diff --git a/im/content/nsContextMenu.js b/im/content/nsContextMenu.js
---- a/im/content/nsContextMenu.js
-+++ b/im/content/nsContextMenu.js
-@@ -468,23 +468,7 @@
- if (selectedText.length > 15)
- selectedText = selectedText.substr(0,15) + this.ellipsis;
-
-- var engine = Services.search.defaultEngine;
-- if (!engine)
-- return false;
--
-- // format "Search <engine> for <selection>" string to show in menu
-- var bundle = document.getElementById("bundle_instantbird");
-- var menuLabel = bundle.getFormattedString("contextMenuSearchText",
-- [engine.name,
-- selectedText]);
-- document.getElementById("context-searchselect").label = menuLabel;
-- document.getElementById("context-searchselect").accessKey =
-- bundle.getString("contextMenuSearchText.accesskey");
-- menuLabel = bundle.getFormattedString("contextMenuSearchWith",
-- [selectedText]);
-- document.getElementById("context-searchselect-with").label = menuLabel;
--
-- return true;
-+ return false;
- },
-
- // Returns true if anything is selected.
diff --git a/projects/instantbird/search-preferences-xul.patch b/projects/instantbird/search-preferences-xul.patch
deleted file mode 100644
index a6b2a31..0000000
--- a/projects/instantbird/search-preferences-xul.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-diff --git a/im/content/preferences/advanced.xul b/im/content/preferences/advanced.xul
---- a/im/content/preferences/advanced.xul
-+++ b/im/content/preferences/advanced.xul
-@@ -143,17 +143,6 @@
- preference="layout.spellcheckDefault"/>
- </groupbox>
-
-- <!-- Search engines -->
-- <groupbox id="searchEnginesGroup" orient="horizontal" align="center">
-- <caption label="&searchEnginesGroup.label;"/>
--
-- <description control="manageSearchEnginesButton"
-- flex="1">&searchEnginesDesc.label;</description>
-- <button id="manageSearchEnginesButton" label="&searchEngines.label;"
-- accesskey="&searchEngines.accesskey;"
-- oncommand="gAdvancedPane.showSearchEngineManager();"/>
-- </groupbox>
--
- <!-- Advanced Configuration -->
- <groupbox>
- <caption label="&configEditDesc.label;"/>
diff --git a/projects/instantbird/show-traffic-tor.patch b/projects/instantbird/show-traffic-tor.patch
deleted file mode 100644
index ae55305..0000000
--- a/projects/instantbird/show-traffic-tor.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-diff --git a/im/content/accountWizard.xul b/im/content/accountWizard.xul
---- a/im/content/accountWizard.xul
-+++ b/im/content/accountWizard.xul
-@@ -39,6 +39,8 @@
- <description class="top-proto-description" value="&accountProtocolShowMore.description;"/>
- </richlistitem>
- </richlistbox>
-+ <separator class="thin"/>
-+ <description>&accountProtocolInfo.label3;</description>
- </wizardpage>
-
- <wizardpage id="accountprotocol" pageid="accountprotocol" next="accountusername"
-diff --git a/im/locales/en-US/chrome/instantbird/accountWizard.dtd b/im/locales/en-US/chrome/instantbird/accountWizard.dtd
---- a/im/locales/en-US/chrome/instantbird/accountWizard.dtd
-+++ b/im/locales/en-US/chrome/instantbird/accountWizard.dtd
-@@ -6,6 +6,7 @@
-
- <!ENTITY accountProtocolTitle.label "Protocol">
- <!ENTITY accountProtocolInfo.label2 "Please choose the protocol of your IM account.">
-+<!ENTITY accountProtocolInfo.label3 "All traffic will be routed over the Tor network.">
- <!ENTITY accountProtocolGetMore.label "Get more…">
- <!ENTITY accountProtocolShowMore.label "Show all protocols">
- <!ENTITY accountProtocolShowMore.description "Choose from the full list of protocols">
diff --git a/projects/instantbird/theme-extension-update.patch b/projects/instantbird/theme-extension-update.patch
deleted file mode 100644
index a1585a8..0000000
--- a/projects/instantbird/theme-extension-update.patch
+++ /dev/null
@@ -1,12 +0,0 @@
-diff --git a/im/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf b/im/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf
---- a/im/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf
-+++ b/im/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf
-@@ -26,6 +26,8 @@
- <!-- Front End MetaData -->
- <em:name>Instantbird (default)</em:name>
- <em:description>The default theme.</em:description>
-+ <em:updateURL>data:text/plain,</em:updateURL>
-+ <em:updateKey>-</em:updateKey>
-
- <!-- EXTENSION AUTHORS!
- DO NOT COPY THIS PROPERTY INTO YOUR INSTALL RDF FILES
diff --git a/projects/instantbird/themes-remove-links.patch b/projects/instantbird/themes-remove-links.patch
deleted file mode 100644
index 8ef25d7..0000000
--- a/projects/instantbird/themes-remove-links.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-diff --git a/im/content/preferences/themes.js b/im/content/preferences/themes.js
---- a/im/content/preferences/themes.js
-+++ b/im/content/preferences/themes.js
-@@ -31,21 +31,6 @@
- default:
- return;
- }
--
-- var getMore = document.getElementById("getMore" + aType);
-- var showGetMore = false;
-- const nsIPrefBranch2 = Components.interfaces.nsIPrefBranch2;
-- if (Services.prefs.getPrefType(prefURL) != nsIPrefBranch2.PREF_INVALID) {
-- try {
-- var getMoreURL = Components.classes["@mozilla.org/toolkit/URLFormatterService;1"]
-- .getService(Components.interfaces.nsIURLFormatter)
-- .formatURLPref(prefURL);
-- getMore.setAttribute("getMoreURL", getMoreURL);
-- showGetMore = getMoreURL != "about:blank";
-- }
-- catch (e) { }
-- }
-- getMore.hidden = !showGetMore;
- },
-
- /* Create the drop down list for emoticons and messagestyles;
-diff --git a/im/content/preferences/themes.xul b/im/content/preferences/themes.xul
---- a/im/content/preferences/themes.xul
-+++ b/im/content/preferences/themes.xul
-@@ -65,8 +65,6 @@
- </menupopup>
- </menulist>
- <separator orient="vertical" class="thin"/>
-- <label id="getMoreMessageStyles" class="text-link" value="&messageStyleGetMore.label;"
-- onclick="if (event.button == 0) { gThemePane.openURL(this.getAttribute('getMoreURL')); }"/>
- </hbox>
- <separator class="thin"/>
- <label value="&messageStylePreview.label;"/>
-@@ -115,8 +113,6 @@
- </menupopup>
- </menulist>
- <separator orient="vertical" class="thin"/>
-- <label id="getMoreEmoticons" class="text-link" value="&emoticonsGetMore.label;"
-- onclick="if (event.button == 0) { gThemePane.openURL(this.getAttribute('getMoreURL')); }"/>
- </hbox>
- <separator class="thin"/>
- <description>&emoticonsPreview.description;</description>
diff --git a/projects/instantbird/top-protocols.patch b/projects/instantbird/top-protocols.patch
deleted file mode 100644
index eb7c8f3..0000000
--- a/projects/instantbird/top-protocols.patch
+++ /dev/null
@@ -1,18 +0,0 @@
-diff --git a/im/locales/en-US/chrome/instantbird/accountWizard.properties b/im/locales/en-US/chrome/instantbird/accountWizard.properties
---- a/im/locales/en-US/chrome/instantbird/accountWizard.properties
-+++ b/im/locales/en-US/chrome/instantbird/accountWizard.properties
-@@ -8,11 +8,13 @@
- # Exceeding 4 protocols may cause scrolling. A list of the
- # available protocols can be found at
- # https://wiki.instantbird.org/Protocol_Identifiers
--topProtocol.list=prpl-gtalk,prpl-twitter,prpl-aim,prpl-yahoo,prpl-irc
-+topProtocol.list=prpl-irc,prpl-jabber,prpl-twitter,prpl-gtalk
-
- # LOCALIZATION NOTE
- # These are the descriptions of the top protocols specified above.
- # A description should be provided for each protocol ID listed above.
-+topProtocol.prpl-irc.description=Connect to your favourite IRC network
-+topProtocol.prpl-jabber.description=Chat with friends using XMPP
- topProtocol.prpl-gtalk.description=Talk to your Gmail contacts
- topProtocol.prpl-twitter.description=Stay up to date with your Twitter timeline
- topProtocol.prpl-aim.description=Chat with your buddies on AOL Instant Messenger
diff --git a/projects/instantbird/trac-13312.patch b/projects/instantbird/trac-13312.patch
deleted file mode 100644
index c3ea75f..0000000
--- a/projects/instantbird/trac-13312.patch
+++ /dev/null
@@ -1,1414 +0,0 @@
-# HG changeset patch
-# User Arlo Breault <arlolra(a)gmail.com>
-# Date 1458088842 25200
-# Tue Mar 15 17:40:42 2016 -0700
-# Branch THUNDERBIRD4530_2016082513_RELBRANCH
-# Node ID 64dd542b1c7d0e62b43dc0d5a57a3ff034b514da
-# Parent 69baf6e1ea1e4c8f4ddf719bff6b542869a99a23
-Changes to twitter.js upstream
-
-diff --git a/chat/protocols/twitter/twitter.js b/chat/protocols/twitter/twitter.js
---- a/chat/protocols/twitter/twitter.js
-+++ b/chat/protocols/twitter/twitter.js
-@@ -124,17 +124,21 @@ Action.prototype = {
- };
-
- function Conversation(aAccount)
- {
- this._init(aAccount);
- this._ensureParticipantExists(aAccount.name);
- // We need the screen names for the IDs in _friends, but _userInfo is
- // indexed by name, so we build an ID -> name map.
-- let names = new Map([userInfo.id_str, name] for ([name, userInfo] of aAccount._userInfo));
-+ let entries = [];
-+ for (let [name, userInfo] of aAccount._userInfo) {
-+ entries.push([userInfo.id_str, name]);
-+ }
-+ let names = new Map(entries);
- for (let id_str of aAccount._friends)
- this._ensureParticipantExists(names.get(id_str));
-
- // If the user's info has already been received, update the timeline topic.
- if (aAccount._userInfo.has(aAccount.name)) {
- let userInfo = aAccount._userInfo.get(aAccount.name);
- if ("description" in userInfo)
- this.setTopic(userInfo.description, aAccount.name, true);
-@@ -314,17 +318,17 @@ Conversation.prototype = {
- end: um.indices[1],
- str: "@" + um.screen_name,
- text: '@<span class="ib-person">' + um.screen_name + "</span>",
- title: um.name,
- href: "https://twitter.com/" + um.screen_name})));
- }
- entArray.sort((a, b) => a.start - b.start);
- let offset = 0;
-- for each (let entity in entArray) {
-+ for (let entity of entArray) {
- let str = text.substring(offset + entity.start, offset + entity.end);
- if (str[0] == "\uFF20") // @ - unicode character similar to @
- str = "@" + str.substring(1);
- if (str[0] == "\uFF03") // # - unicode character similar to #
- str = "#" + str.substring(1);
- if (str.toLowerCase() != entity.str.toLowerCase())
- continue;
-
-@@ -507,17 +511,17 @@ Account.prototype = {
-
- let keyFactory = Cc["@mozilla.org/security/keyobjectfactory;1"]
- .getService(Ci.nsIKeyObjectFactory);
- let hmac =
- Cc["@mozilla.org/security/hmac;1"].createInstance(Ci.nsICryptoHMAC);
- hmac.init(hmac.SHA1,
- keyFactory.keyFromString(Ci.nsIKeyObject.HMAC, signatureKey));
- // No UTF-8 encoding, special chars are already escaped.
-- let bytes = [b.charCodeAt() for each (b in signatureBase)];
-+ let bytes = [...signatureBase].map(b => b.charCodeAt());
- hmac.update(bytes, bytes.length);
- let signature = hmac.finish(true);
-
- params.push(["oauth_signature", encodeURIComponent(signature)]);
-
- let authorization =
- "OAuth " + params.map(p => p[0] + "=\"" + p[1] + "\"").join(", ");
-
-@@ -615,17 +619,17 @@ Account.prototype = {
- this.signAndSend(url, null, null, this.onTimelineReceived,
- this.onTimelineError, this, null));
- }
- },
-
- get timeline() { return this._timeline || (this._timeline = new Conversation(this)); },
- displayMessages: function(aMessages) {
- let lastMsgId = this._lastMsgId;
-- for each (let tweet in aMessages) {
-+ for (let tweet of aMessages) {
- if (!("user" in tweet) || !("text" in tweet) || !("id_str" in tweet) ||
- this._knownMessageIds.has(tweet.id_str))
- continue;
- let id = tweet.id_str;
- // Update the last known message.
- // Compare the length of the ids first, and then the text.
- // This avoids converting tweet ids into rounded numbers.
- if (id.length > lastMsgId.length ||
-@@ -734,33 +738,33 @@ Account.prototype = {
- this.gotDisconnected(Ci.prplIAccount.ERROR_NETWORK_ERROR, "timeout");
- },
- onDataAvailable: function(aRequest) {
- this.resetStreamTimeout();
- let newText = this._pendingData + aRequest.target.response;
- this.DEBUG("Received data: " + newText);
- let messages = newText.split(/\r\n?/);
- this._pendingData = messages.pop();
-- for each (let message in messages) {
-+ for (let message of messages) {
- if (!message.trim())
- continue;
- let msg;
- try {
- msg = JSON.parse(message);
- } catch (e) {
- this.ERROR(e + " while parsing " + message);
- continue;
- }
- if ("text" in msg)
- this.displayMessages([msg]);
- else if ("friends" in msg) {
- // Filter out the IDs that info has already been received from (e.g. a
- // tweet has been received as part of the timeline request).
- let userInfoIds = new Set();
-- for each (let userInfo in this._userInfo)
-+ for (let userInfo of this._userInfo.values())
- userInfoIds.add(userInfo.id_str);
- let ids = msg.friends.filter(
- aId => !userInfoIds.has(aId.toString()));
-
- while (ids.length) {
- // Take the first 100 elements, turn them into a comma separated list.
- this.signAndSend("1.1/users/lookup.json", null,
- [["user_id", ids.slice(0, 99).join(",")]],
-@@ -946,17 +950,17 @@ Account.prototype = {
- this.name + " -> " + aAuthResult.screen_name);
- this.__defineGetter__("name", () => aAuthResult.screen_name);
- return true;
- },
-
- cleanUp: function() {
- this.finishAuthorizationRequest();
- if (this._pendingRequests.length != 0) {
-- for each (let request in this._pendingRequests)
-+ for (let request of this._pendingRequests)
- request.abort();
- delete this._pendingRequests;
- }
- if (this._streamTimeout) {
- clearTimeout(this._streamTimeout);
- delete this._streamTimeout;
- // Remove the preference observer that is added when the user stream is
- // opened. (This needs to be removed even if an error occurs, in which
-@@ -1083,17 +1087,17 @@ Account.prototype = {
- Services.obs.notifyObservers(new nsSimpleEnumerator(tooltipInfo),
- "user-info-received", aBuddyName);
- },
-
- // Handle the full user info for each received friend. Set the user info and
- // create the participant.
- onLookupReceived: function(aData) {
- let users = JSON.parse(aData);
-- for each (let user in users) {
-+ for (let user of users) {
- this.setUserInfo(user);
- this.timeline._ensureParticipantExists(user.screen_name);
- }
- },
-
- onConfigReceived: function(aData) {
- this.config = JSON.parse(aData);
- },
-# HG changeset patch
-# User Arlo Breault <arlolra(a)gmail.com>
-# Date 1458087696 25200
-# Tue Mar 15 17:21:36 2016 -0700
-# Branch THUNDERBIRD4530_2016082513_RELBRANCH
-# Node ID 9f2addccb7a8d4875746abd96f6beba38ef0f398
-# Parent 64dd542b1c7d0e62b43dc0d5a57a3ff034b514da
-Update twitter-text.jsm
-
-diff --git a/chat/protocols/twitter/twitter-text.jsm b/chat/protocols/twitter/twitter-text.jsm
---- a/chat/protocols/twitter/twitter-text.jsm
-+++ b/chat/protocols/twitter/twitter-text.jsm
-@@ -14,17 +14,17 @@
- */
-
- this.EXPORTED_SYMBOLS = ["twttr"];
-
- var window = {};
-
- // The code below is imported from Twitter's JavaScript utility for parsing
- // tweets. The original version of this file can be found at
--// https://github.com/twitter/twitter-text-js/blob/master/twitter-text.js
-+// https://github.com/twitter/twitter-text/blob/master/js/twitter-text.js
-
- (function() {
- if (typeof twttr === "undefined" || twttr === null) {
- var twttr = {};
- }
-
- twttr.txt = {};
- twttr.txt.regexen = {};
-@@ -120,90 +120,16 @@ var window = {};
-
- twttr.txt.regexen.spaces_group = regexSupplant(UNICODE_SPACES.join(""));
- twttr.txt.regexen.spaces = regexSupplant("[" + UNICODE_SPACES.join("") + "]");
- twttr.txt.regexen.invalid_chars_group = regexSupplant(INVALID_CHARS.join(""));
- twttr.txt.regexen.punct = /\!'#%&'\(\)*\+,\\\-\.\/:;<=>\?@\[\]\^_{|}~\$/;
- twttr.txt.regexen.rtl_chars = /[\u0600-\u06FF]|[\u0750-\u077F]|[\u0590-\u05FF]|[\uFE70-\uFEFF]/mg;
- twttr.txt.regexen.non_bmp_code_pairs = /[\uD800-\uDBFF][\uDC00-\uDFFF]/mg;
-
-- var nonLatinHashtagChars = [];
-- // Cyrillic
-- addCharsToCharClass(nonLatinHashtagChars, 0x0400, 0x04ff); // Cyrillic
-- addCharsToCharClass(nonLatinHashtagChars, 0x0500, 0x0527); // Cyrillic Supplement
-- addCharsToCharClass(nonLatinHashtagChars, 0x2de0, 0x2dff); // Cyrillic Extended A
-- addCharsToCharClass(nonLatinHashtagChars, 0xa640, 0xa69f); // Cyrillic Extended B
-- // Hebrew
-- addCharsToCharClass(nonLatinHashtagChars, 0x0591, 0x05bf); // Hebrew
-- addCharsToCharClass(nonLatinHashtagChars, 0x05c1, 0x05c2);
-- addCharsToCharClass(nonLatinHashtagChars, 0x05c4, 0x05c5);
-- addCharsToCharClass(nonLatinHashtagChars, 0x05c7, 0x05c7);
-- addCharsToCharClass(nonLatinHashtagChars, 0x05d0, 0x05ea);
-- addCharsToCharClass(nonLatinHashtagChars, 0x05f0, 0x05f4);
-- addCharsToCharClass(nonLatinHashtagChars, 0xfb12, 0xfb28); // Hebrew Presentation Forms
-- addCharsToCharClass(nonLatinHashtagChars, 0xfb2a, 0xfb36);
-- addCharsToCharClass(nonLatinHashtagChars, 0xfb38, 0xfb3c);
-- addCharsToCharClass(nonLatinHashtagChars, 0xfb3e, 0xfb3e);
-- addCharsToCharClass(nonLatinHashtagChars, 0xfb40, 0xfb41);
-- addCharsToCharClass(nonLatinHashtagChars, 0xfb43, 0xfb44);
-- addCharsToCharClass(nonLatinHashtagChars, 0xfb46, 0xfb4f);
-- // Arabic
-- addCharsToCharClass(nonLatinHashtagChars, 0x0610, 0x061a); // Arabic
-- addCharsToCharClass(nonLatinHashtagChars, 0x0620, 0x065f);
-- addCharsToCharClass(nonLatinHashtagChars, 0x066e, 0x06d3);
-- addCharsToCharClass(nonLatinHashtagChars, 0x06d5, 0x06dc);
-- addCharsToCharClass(nonLatinHashtagChars, 0x06de, 0x06e8);
-- addCharsToCharClass(nonLatinHashtagChars, 0x06ea, 0x06ef);
-- addCharsToCharClass(nonLatinHashtagChars, 0x06fa, 0x06fc);
-- addCharsToCharClass(nonLatinHashtagChars, 0x06ff, 0x06ff);
-- addCharsToCharClass(nonLatinHashtagChars, 0x0750, 0x077f); // Arabic Supplement
-- addCharsToCharClass(nonLatinHashtagChars, 0x08a0, 0x08a0); // Arabic Extended A
-- addCharsToCharClass(nonLatinHashtagChars, 0x08a2, 0x08ac);
-- addCharsToCharClass(nonLatinHashtagChars, 0x08e4, 0x08fe);
-- addCharsToCharClass(nonLatinHashtagChars, 0xfb50, 0xfbb1); // Arabic Pres. Forms A
-- addCharsToCharClass(nonLatinHashtagChars, 0xfbd3, 0xfd3d);
-- addCharsToCharClass(nonLatinHashtagChars, 0xfd50, 0xfd8f);
-- addCharsToCharClass(nonLatinHashtagChars, 0xfd92, 0xfdc7);
-- addCharsToCharClass(nonLatinHashtagChars, 0xfdf0, 0xfdfb);
-- addCharsToCharClass(nonLatinHashtagChars, 0xfe70, 0xfe74); // Arabic Pres. Forms B
-- addCharsToCharClass(nonLatinHashtagChars, 0xfe76, 0xfefc);
-- addCharsToCharClass(nonLatinHashtagChars, 0x200c, 0x200c); // Zero-Width Non-Joiner
-- // Thai
-- addCharsToCharClass(nonLatinHashtagChars, 0x0e01, 0x0e3a);
-- addCharsToCharClass(nonLatinHashtagChars, 0x0e40, 0x0e4e);
-- // Hangul (Korean)
-- addCharsToCharClass(nonLatinHashtagChars, 0x1100, 0x11ff); // Hangul Jamo
-- addCharsToCharClass(nonLatinHashtagChars, 0x3130, 0x3185); // Hangul Compatibility Jamo
-- addCharsToCharClass(nonLatinHashtagChars, 0xA960, 0xA97F); // Hangul Jamo Extended-A
-- addCharsToCharClass(nonLatinHashtagChars, 0xAC00, 0xD7AF); // Hangul Syllables
-- addCharsToCharClass(nonLatinHashtagChars, 0xD7B0, 0xD7FF); // Hangul Jamo Extended-B
-- addCharsToCharClass(nonLatinHashtagChars, 0xFFA1, 0xFFDC); // half-width Hangul
-- // Japanese and Chinese
-- addCharsToCharClass(nonLatinHashtagChars, 0x30A1, 0x30FA); // Katakana (full-width)
-- addCharsToCharClass(nonLatinHashtagChars, 0x30FC, 0x30FE); // Katakana Chouon and iteration marks (full-width)
-- addCharsToCharClass(nonLatinHashtagChars, 0xFF66, 0xFF9F); // Katakana (half-width)
-- addCharsToCharClass(nonLatinHashtagChars, 0xFF70, 0xFF70); // Katakana Chouon (half-width)
-- addCharsToCharClass(nonLatinHashtagChars, 0xFF10, 0xFF19); // \
-- addCharsToCharClass(nonLatinHashtagChars, 0xFF21, 0xFF3A); // - Latin (full-width)
-- addCharsToCharClass(nonLatinHashtagChars, 0xFF41, 0xFF5A); // /
-- addCharsToCharClass(nonLatinHashtagChars, 0x3041, 0x3096); // Hiragana
-- addCharsToCharClass(nonLatinHashtagChars, 0x3099, 0x309E); // Hiragana voicing and iteration mark
-- addCharsToCharClass(nonLatinHashtagChars, 0x3400, 0x4DBF); // Kanji (CJK Extension A)
-- addCharsToCharClass(nonLatinHashtagChars, 0x4E00, 0x9FFF); // Kanji (Unified)
-- // -- Disabled as it breaks the Regex.
-- //addCharsToCharClass(nonLatinHashtagChars, 0x20000, 0x2A6DF); // Kanji (CJK Extension B)
-- addCharsToCharClass(nonLatinHashtagChars, 0x2A700, 0x2B73F); // Kanji (CJK Extension C)
-- addCharsToCharClass(nonLatinHashtagChars, 0x2B740, 0x2B81F); // Kanji (CJK Extension D)
-- addCharsToCharClass(nonLatinHashtagChars, 0x2F800, 0x2FA1F); // Kanji (CJK supplement)
-- addCharsToCharClass(nonLatinHashtagChars, 0x3003, 0x3003); // Kanji iteration mark
-- addCharsToCharClass(nonLatinHashtagChars, 0x3005, 0x3005); // Kanji iteration mark
-- addCharsToCharClass(nonLatinHashtagChars, 0x303B, 0x303B); // Han iteration mark
--
-- twttr.txt.regexen.nonLatinHashtagChars = regexSupplant(nonLatinHashtagChars.join(""));
--
- var latinAccentChars = [];
- // Latin accented characters (subtracted 0xD7 from the range, it's a confusable multiplication sign. Looks like "x")
- addCharsToCharClass(latinAccentChars, 0x00c0, 0x00d6);
- addCharsToCharClass(latinAccentChars, 0x00d8, 0x00f6);
- addCharsToCharClass(latinAccentChars, 0x00f8, 0x00ff);
- // Latin Extended A and B
- addCharsToCharClass(latinAccentChars, 0x0100, 0x024f);
- // assorted IPA Extensions
-@@ -220,26 +146,30 @@ var window = {};
- // Okina for Hawaiian (it *is* a letter character)
- addCharsToCharClass(latinAccentChars, 0x02bb, 0x02bb);
- // Combining diacritics
- addCharsToCharClass(latinAccentChars, 0x0300, 0x036f);
- // Latin Extended Additional
- addCharsToCharClass(latinAccentChars, 0x1e00, 0x1eff);
- twttr.txt.regexen.latinAccentChars = regexSupplant(latinAccentChars.join(""));
-
-- // A hashtag must contain characters, numbers and underscores, but not all numbers.
-+ var unicodeLettersAndMarks = "A-Za-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B2\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0
B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8
-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u
2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\u
FB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC\u0300-\u036F\u0483-\u0489\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08E4-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B62\u0B63\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0C00-\u0C03\u0C3E-\u0C44
\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0D01-\u0D03\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D82\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F\u109A-\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u180B-\u180D\u18A9\u1920-\u192B\u1930-\u193B\u19B0-\u19C0\u19C8\u19C9\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F\u1AB0-\u1ABE\u1B00-\u1B04\u1B34-\u1B44\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BE6-\u1BF3\u1C24-\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF2-\u1CF4\u1CF8\u1CF9\u1DC0-\u1DF5\u1DFC-\u1DFF\u20D0-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099
\u309A\uA66F-\uA672\uA674-\uA67D\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA880\uA881\uA8B4-\uA8C4\uA8E0-\uA8F1\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9E5\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2D";
-+ var unicodeNumbers = "0-9\u0660-\u0669\u06F0-\u06F9\u07C0-\u07C9\u0966-\u096F\u09E6-\u09EF\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0BE6-\u0BEF\u0C66-\u0C6F\u0CE6-\u0CEF\u0D66-\u0D6F\u0DE6-\u0DEF\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F29\u1040-\u1049\u1090-\u1099\u17E0-\u17E9\u1810-\u1819\u1946-\u194F\u19D0-\u19D9\u1A80-\u1A89\u1A90-\u1A99\u1B50-\u1B59\u1BB0-\u1BB9\u1C40-\u1C49\u1C50-\u1C59\uA620-\uA629\uA8D0-\uA8D9\uA900-\uA909\uA9D0-\uA9D9\uA9F0-\uA9F9\uAA50-\uAA59\uABF0-\uABF9\uFF10-\uFF19";
-+ var hashtagSpecialChars = "_\u200c\u200d\ua67e\u05be\u05f3\u05f4\uff5e\u301c\u309b\u309c\u30a0\u30fb\u3003\u0f0b\u0f0c\u00b7";
-+
-+ // A hashtag must contain at least one unicode letter or mark, as well as numbers, underscores, and select special characters.
- twttr.txt.regexen.hashSigns = /[##]/;
-- twttr.txt.regexen.hashtagAlpha = regexSupplant(/[a-z_#{latinAccentChars}#{nonLatinHashtagChars}]/i);
-- twttr.txt.regexen.hashtagAlphaNumeric = regexSupplant(/[a-z0-9_#{latinAccentChars}#{nonLatinHashtagChars}]/i);
-+ twttr.txt.regexen.hashtagAlpha = new RegExp("[" + unicodeLettersAndMarks + "]");
-+ twttr.txt.regexen.hashtagAlphaNumeric = new RegExp("[" + unicodeLettersAndMarks + unicodeNumbers + hashtagSpecialChars + "]");
- twttr.txt.regexen.endHashtagMatch = regexSupplant(/^(?:#{hashSigns}|:\/\/)/);
-- twttr.txt.regexen.hashtagBoundary = regexSupplant(/(?:^|$|[^&a-z0-9_#{latinAccentChars}#{nonLatinHashtagChars}])/);
-- twttr.txt.regexen.validHashtag = regexSupplant(/(#{hashtagBoundary})(#{hashSigns})(#{hashtagAlphaNumeric}*#{hashtagAlpha}#{hashtagAlphaNumeric}*)/gi);
-+ twttr.txt.regexen.hashtagBoundary = new RegExp("(?:^|$|[^&" + unicodeLettersAndMarks + unicodeNumbers + hashtagSpecialChars + "])");
-+ twttr.txt.regexen.validHashtag = regexSupplant(/(#{hashtagBoundary})(#{hashSigns})(?!\ufe0f|\u20e3)(#{hashtagAlphaNumeric}*#{hashtagAlpha}#{hashtagAlphaNumeric}*)/gi);
-
- // Mention related regex collection
-- twttr.txt.regexen.validMentionPrecedingChars = /(?:^|[^a-zA-Z0-9_!#$%&*@@]|RT:?)/;
-+ twttr.txt.regexen.validMentionPrecedingChars = /(?:^|[^a-zA-Z0-9_!#$%&*@@]|(?:^|[^a-zA-Z0-9_+~.-])(?:rt|RT|rT|Rt):?)/;
- twttr.txt.regexen.atSigns = /[@@]/;
- twttr.txt.regexen.validMentionOrList = regexSupplant(
- '(#{validMentionPrecedingChars})' + // $1: Preceding character
- '(#{atSigns})' + // $2: At mark
- '([a-zA-Z0-9_]{1,20})' + // $3: Screen name
- '(\/[a-zA-Z][a-zA-Z0-9_\-]{0,24})?' // $4: List (optional)
- , 'g');
- twttr.txt.regexen.validReply = regexSupplant(/^(?:#{spaces})*#{atSigns}([a-zA-Z0-9_]{1,20})/);
-@@ -247,40 +177,120 @@ var window = {};
-
- // URL related regex collection
- twttr.txt.regexen.validUrlPrecedingChars = regexSupplant(/(?:[^A-Za-z0-9@@$###{invalid_chars_group}]|^)/);
- twttr.txt.regexen.invalidUrlWithoutProtocolPrecedingChars = /[-_.\/]$/;
- twttr.txt.regexen.invalidDomainChars = stringSupplant("#{punct}#{spaces_group}#{invalid_chars_group}", twttr.txt.regexen);
- twttr.txt.regexen.validDomainChars = regexSupplant(/[^#{invalidDomainChars}]/);
- twttr.txt.regexen.validSubdomain = regexSupplant(/(?:(?:#{validDomainChars}(?:[_-]|#{validDomainChars})*)?#{validDomainChars}\.)/);
- twttr.txt.regexen.validDomainName = regexSupplant(/(?:(?:#{validDomainChars}(?:-|#{validDomainChars})*)?#{validDomainChars}\.)/);
-- twttr.txt.regexen.validGTLD = regexSupplant(/(?:(?:aero|asia|biz|cat|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|net|org|pro|tel|travel|xxx)(?=[^0-9a-zA-Z]|$))/);
-+ twttr.txt.regexen.validGTLD = regexSupplant(RegExp(
-+ '(?:(?:' +
-+ 'abb|abbott|abogado|academy|accenture|accountant|accountants|aco|active|actor|ads|adult|aeg|aero|' +
-+ 'afl|agency|aig|airforce|airtel|allfinanz|alsace|amsterdam|android|apartments|app|aquarelle|' +
-+ 'archi|army|arpa|asia|associates|attorney|auction|audio|auto|autos|axa|azure|band|bank|bar|' +
-+ 'barcelona|barclaycard|barclays|bargains|bauhaus|bayern|bbc|bbva|bcn|beer|bentley|berlin|best|' +
-+ 'bet|bharti|bible|bid|bike|bing|bingo|bio|biz|black|blackfriday|bloomberg|blue|bmw|bnl|' +
-+ 'bnpparibas|boats|bond|boo|boots|boutique|bradesco|bridgestone|broker|brother|brussels|budapest|' +
-+ 'build|builders|business|buzz|bzh|cab|cafe|cal|camera|camp|cancerresearch|canon|capetown|capital|' +
-+ 'caravan|cards|care|career|careers|cars|cartier|casa|cash|casino|cat|catering|cba|cbn|ceb|center|' +
-+ 'ceo|cern|cfa|cfd|chanel|channel|chat|cheap|chloe|christmas|chrome|church|cisco|citic|city|' +
-+ 'claims|cleaning|click|clinic|clothing|cloud|club|coach|codes|coffee|college|cologne|com|' +
-+ 'commbank|community|company|computer|condos|construction|consulting|contractors|cooking|cool|' +
-+ 'coop|corsica|country|coupons|courses|credit|creditcard|cricket|crown|crs|cruises|cuisinella|' +
-+ 'cymru|cyou|dabur|dad|dance|date|dating|datsun|day|dclk|deals|degree|delivery|delta|democrat|' +
-+ 'dental|dentist|desi|design|dev|diamonds|diet|digital|direct|directory|discount|dnp|docs|dog|' +
-+ 'doha|domains|doosan|download|drive|durban|dvag|earth|eat|edu|education|email|emerck|energy|' +
-+ 'engineer|engineering|enterprises|epson|equipment|erni|esq|estate|eurovision|eus|events|everbank|' +
-+ 'exchange|expert|exposed|express|fage|fail|faith|family|fan|fans|farm|fashion|feedback|film|' +
-+ 'finance|financial|firmdale|fish|fishing|fit|fitness|flights|florist|flowers|flsmidth|fly|foo|' +
-+ 'football|forex|forsale|forum|foundation|frl|frogans|fund|furniture|futbol|fyi|gal|gallery|game|' +
-+ 'garden|gbiz|gdn|gent|genting|ggee|gift|gifts|gives|giving|glass|gle|global|globo|gmail|gmo|gmx|' +
-+ 'gold|goldpoint|golf|goo|goog|google|gop|gov|graphics|gratis|green|gripe|group|guge|guide|' +
-+ 'guitars|guru|hamburg|hangout|haus|healthcare|help|here|hermes|hiphop|hitachi|hiv|hockey|' +
-+ 'holdings|holiday|homedepot|homes|honda|horse|host|hosting|hoteles|hotmail|house|how|hsbc|ibm|' +
-+ 'icbc|ice|icu|ifm|iinet|immo|immobilien|industries|infiniti|info|ing|ink|institute|insure|int|' +
-+ 'international|investments|ipiranga|irish|ist|istanbul|itau|iwc|java|jcb|jetzt|jewelry|jlc|jll|' +
-+ 'jobs|joburg|jprs|juegos|kaufen|kddi|kim|kitchen|kiwi|koeln|komatsu|krd|kred|kyoto|lacaixa|' +
-+ 'lancaster|land|lasalle|lat|latrobe|law|lawyer|lds|lease|leclerc|legal|lexus|lgbt|liaison|lidl|' +
-+ 'life|lighting|limited|limo|link|live|lixil|loan|loans|lol|london|lotte|lotto|love|ltda|lupin|' +
-+ 'luxe|luxury|madrid|maif|maison|man|management|mango|market|marketing|markets|marriott|mba|media|' +
-+ 'meet|melbourne|meme|memorial|men|menu|miami|microsoft|mil|mini|mma|mobi|moda|moe|mom|monash|' +
-+ 'money|montblanc|mormon|mortgage|moscow|motorcycles|mov|movie|movistar|mtn|mtpc|museum|nadex|' +
-+ 'nagoya|name|navy|nec|net|netbank|network|neustar|new|news|nexus|ngo|nhk|nico|ninja|nissan|nokia|' +
-+ 'nra|nrw|ntt|nyc|office|okinawa|omega|one|ong|onl|online|ooo|oracle|orange|org|organic|osaka|' +
-+ 'otsuka|ovh|page|panerai|paris|partners|parts|party|pet|pharmacy|philips|photo|photography|' +
-+ 'photos|physio|piaget|pics|pictet|pictures|pink|pizza|place|play|plumbing|plus|pohl|poker|porn|' +
-+ 'post|praxi|press|pro|prod|productions|prof|properties|property|pub|qpon|quebec|racing|realtor|' +
-+ 'realty|recipes|red|redstone|rehab|reise|reisen|reit|ren|rent|rentals|repair|report|republican|' +
-+ 'rest|restaurant|review|reviews|rich|ricoh|rio|rip|rocks|rodeo|rsvp|ruhr|run|ryukyu|saarland|' +
-+ 'sakura|sale|samsung|sandvik|sandvikcoromant|sanofi|sap|sarl|saxo|sca|scb|schmidt|scholarships|' +
-+ 'school|schule|schwarz|science|scor|scot|seat|seek|sener|services|sew|sex|sexy|shiksha|shoes|' +
-+ 'show|shriram|singles|site|ski|sky|skype|sncf|soccer|social|software|sohu|solar|solutions|sony|' +
-+ 'soy|space|spiegel|spreadbetting|srl|starhub|statoil|studio|study|style|sucks|supplies|supply|' +
-+ 'support|surf|surgery|suzuki|swatch|swiss|sydney|systems|taipei|tatamotors|tatar|tattoo|tax|taxi|' +
-+ 'team|tech|technology|tel|telefonica|temasek|tennis|thd|theater|tickets|tienda|tips|tires|tirol|' +
-+ 'today|tokyo|tools|top|toray|toshiba|tours|town|toyota|toys|trade|trading|training|travel|trust|' +
-+ 'tui|ubs|university|uno|uol|vacations|vegas|ventures|vermögensberater|vermögensberatung|' +
-+ 'versicherung|vet|viajes|video|villas|vin|vision|vista|vistaprint|vlaanderen|vodka|vote|voting|' +
-+ 'voto|voyage|wales|walter|wang|watch|webcam|website|wed|wedding|weir|whoswho|wien|wiki|' +
-+ 'williamhill|win|windows|wine|wme|work|works|world|wtc|wtf|xbox|xerox|xin|xperia|xxx|xyz|yachts|' +
-+ 'yandex|yodobashi|yoga|yokohama|youtube|zip|zone|zuerich|дети|ком|москва|онлайн|орг|рус|сайт|קום|' +
-+ 'بازار|شبكة|كوم|موقع|कॉम|नेट|संगठन|คอม|みんな|グーグル|コム|世界|中信|中文网|企业|佛山|信息|健康|八卦|公司|公益|商城|商店|商标|在线|大拿|' +
-+ '娱乐|工行|广东|慈善|我爱你|手机|政务|政府|新闻|时尚|机构|淡马锡|游戏|点看|移动|组织机构|网址|网店|网络|谷歌|集团|飞利浦|餐厅|닷넷|닷컴|삼성|onion' +
-+ ')(?=[^0-9a-zA-Z@]|$))'));
- twttr.txt.regexen.validCCTLD = regexSupplant(RegExp(
-- "(?:(?:ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|" +
-- "ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|" +
-- "ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|" +
-- "ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|" +
-- "na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|" +
-- "sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|" +
-- "ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|za|zm|zw)(?=[^0-9a-zA-Z]|$))"));
-+ '(?:(?:' +
-+ 'ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bl|bm|bn|bo|bq|' +
-+ 'br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cw|cx|cy|cz|de|dj|dk|dm|do|dz|' +
-+ 'ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|' +
-+ 'gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|' +
-+ 'la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mf|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|' +
-+ 'my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|' +
-+ 'rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|' +
-+ 'tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|um|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|za|zm|zw|ελ|' +
-+ 'бел|мкд|мон|рф|срб|укр|қаз|հայ|الاردن|الجزائر|السعودية|المغرب|امارات|ایران|بھارت|تونس|سودان|' +
-+ 'سورية|عراق|عمان|فلسطين|قطر|مصر|مليسيا|پاکستان|भारत|বাংলা|ভারত|ਭਾਰਤ|ભારત|இந்தியா|இலங்கை|' +
-+ 'சிங்கப்பூர்|భారత్|ලංකා|ไทย|გე|中国|中國|台湾|台灣|新加坡|澳門|香港|한국' +
-+ ')(?=[^0-9a-zA-Z@]|$))'));
- twttr.txt.regexen.validPunycode = regexSupplant(/(?:xn--[0-9a-z]+)/);
-+ twttr.txt.regexen.validSpecialCCTLD = regexSupplant(RegExp(
-+ '(?:(?:co|tv)(?=[^0-9a-zA-Z@]|$))'));
- twttr.txt.regexen.validDomain = regexSupplant(/(?:#{validSubdomain}*#{validDomainName}(?:#{validGTLD}|#{validCCTLD}|#{validPunycode}))/);
- twttr.txt.regexen.validAsciiDomain = regexSupplant(/(?:(?:[\-a-z0-9#{latinAccentChars}]+)\.)+(?:#{validGTLD}|#{validCCTLD}|#{validPunycode})/gi);
-- twttr.txt.regexen.invalidShortDomain = regexSupplant(/^#{validDomainName}#{validCCTLD}$/);
-+ twttr.txt.regexen.invalidShortDomain = regexSupplant(/^#{validDomainName}#{validCCTLD}$/i);
-+ twttr.txt.regexen.validSpecialShortDomain = regexSupplant(/^#{validDomainName}#{validSpecialCCTLD}$/i);
-
- twttr.txt.regexen.validPortNumber = regexSupplant(/[0-9]+/);
-
-- twttr.txt.regexen.validGeneralUrlPathChars = regexSupplant(/[a-z0-9!\*';:=\+,\.\$\/%#\[\]\-_~@|&#{latinAccentChars}]/i);
-- // Allow URL paths to contain balanced parens
-+ twttr.txt.regexen.cyrillicLettersAndMarks = regexSupplant("\u0400-\u04FF");
-+ twttr.txt.regexen.validGeneralUrlPathChars = regexSupplant(/[a-z#{cyrillicLettersAndMarks}0-9!\*';:=\+,\.\$\/%#\[\]\-_~@\|&#{latinAccentChars}]/i);
-+ // Allow URL paths to contain up to two nested levels of balanced parens
- // 1. Used in Wikipedia URLs like /Primer_(film)
- // 2. Used in IIS sessions like /S(dfd346)/
-- twttr.txt.regexen.validUrlBalancedParens = regexSupplant(/\(#{validGeneralUrlPathChars}+\)/i);
-+ // 3. Used in Rdio URLs like /track/We_Up_(Album_Version_(Edited))/
-+ twttr.txt.regexen.validUrlBalancedParens = regexSupplant(
-+ '\\(' +
-+ '(?:' +
-+ '#{validGeneralUrlPathChars}+' +
-+ '|' +
-+ // allow one nested level of balanced parentheses
-+ '(?:' +
-+ '#{validGeneralUrlPathChars}*' +
-+ '\\(' +
-+ '#{validGeneralUrlPathChars}+' +
-+ '\\)' +
-+ '#{validGeneralUrlPathChars}*' +
-+ ')' +
-+ ')' +
-+ '\\)'
-+ , 'i');
- // Valid end-of-path chracters (so /foo. does not gobble the period).
- // 1. Allow =&# for empty URL parameters and other URL-join artifacts
-- twttr.txt.regexen.validUrlPathEndingChars = regexSupplant(/[\+\-a-z0-9=_#\/#{latinAccentChars}]|(?:#{validUrlBalancedParens})/i);
-+ twttr.txt.regexen.validUrlPathEndingChars = regexSupplant(/[\+\-a-z#{cyrillicLettersAndMarks}0-9=_#\/#{latinAccentChars}]|(?:#{validUrlBalancedParens})/i);
- // Allow @ in a url, but only in the middle. Catch things like http://example.com/@user/
- twttr.txt.regexen.validUrlPath = regexSupplant('(?:' +
- '(?:' +
- '#{validGeneralUrlPathChars}*' +
- '(?:#{validUrlBalancedParens}#{validGeneralUrlPathChars}*)*' +
- '#{validUrlPathEndingChars}'+
- ')|(?:@#{validGeneralUrlPathChars}+\/)'+
- ')', 'i');
-@@ -304,17 +314,17 @@ var window = {};
- twttr.txt.regexen.urlHasProtocol = /^https?:\/\//i;
- twttr.txt.regexen.urlHasHttps = /^https:\/\//i;
-
- // cashtag related regex
- twttr.txt.regexen.cashtag = /[a-z]{1,6}(?:[._][a-z]{1,2})?/i;
- twttr.txt.regexen.validCashtag = regexSupplant('(^|#{spaces})(\\$)(#{cashtag})(?=$|\\s|[#{punct}])', 'gi');
-
- // These URL validation pattern strings are based on the ABNF from RFC 3986
-- twttr.txt.regexen.validateUrlUnreserved = /[a-z0-9\-._~]/i;
-+ twttr.txt.regexen.validateUrlUnreserved = /[a-z\u0400-\u04FF0-9\-._~]/i;
- twttr.txt.regexen.validateUrlPctEncoded = /(?:%[0-9a-f]{2})/i;
- twttr.txt.regexen.validateUrlSubDelims = /[!$&'()*+,;=]/i;
- twttr.txt.regexen.validateUrlPchar = regexSupplant('(?:' +
- '#{validateUrlUnreserved}|' +
- '#{validateUrlPctEncoded}|' +
- '#{validateUrlSubDelims}|' +
- '[:|@]' +
- ')', 'i');
-@@ -473,17 +483,17 @@ var window = {};
-
- twttr.txt.linkToHashtag = function(entity, text, options) {
- var hash = text.substring(entity.indices[0], entity.indices[0] + 1);
- var hashtag = twttr.txt.htmlEscape(entity.hashtag);
- var attrs = clone(options.htmlAttrs || {});
- attrs.href = options.hashtagUrlBase + hashtag;
- attrs.title = "#" + hashtag;
- attrs["class"] = options.hashtagClass;
-- if (hashtag[0].match(twttr.txt.regexen.rtl_chars)){
-+ if (hashtag.charAt(0).match(twttr.txt.regexen.rtl_chars)){
- attrs["class"] += " rtl";
- }
- if (options.targetBlank) {
- attrs.target = '_blank';
- }
-
- return twttr.txt.linkToTextWithSymbol(entity, hash, hashtag, attrs, options);
- };
-@@ -678,32 +688,44 @@ var window = {};
- }
- beginIndex = entity.indices[1];
- }
- result += nonEntity(text.substring(beginIndex, text.length));
- return result;
- };
-
- twttr.txt.autoLinkWithJSON = function(text, json, options) {
-+ // map JSON entity to twitter-text entity
-+ if (json.user_mentions) {
-+ for (var i = 0; i < json.user_mentions.length; i++) {
-+ // this is a @mention
-+ json.user_mentions[i].screenName = json.user_mentions[i].screen_name;
-+ }
-+ }
-+
-+ if (json.hashtags) {
-+ for (var i = 0; i < json.hashtags.length; i++) {
-+ // this is a #hashtag
-+ json.hashtags[i].hashtag = json.hashtags[i].text;
-+ }
-+ }
-+
-+ if (json.symbols) {
-+ for (var i = 0; i < json.symbols.length; i++) {
-+ // this is a $CASH tag
-+ json.symbols[i].cashtag = json.symbols[i].text;
-+ }
-+ }
-+
- // concatenate all entities
- var entities = [];
- for (var key in json) {
- entities = entities.concat(json[key]);
- }
-- // map JSON entity to twitter-text entity
-- for (var i = 0; i < entities.length; i++) {
-- entity = entities[i];
-- if (entity.screen_name) {
-- // this is @mention
-- entity.screenName = entity.screen_name;
-- } else if (entity.text) {
-- // this is #hashtag
-- entity.hashtag = entity.text;
-- }
-- }
-+
- // modify indices to UTF-16
- twttr.txt.modifyIndicesFromUnicodeToUTF16(text, entities);
-
- return twttr.txt.autoLinkEntities(text, entities, options);
- };
-
- twttr.txt.extractHtmlAttrsFromOptions = function(options) {
- var htmlAttrs = {};
-@@ -856,17 +878,16 @@ var window = {};
-
- return urlsOnly;
- };
-
- twttr.txt.extractUrlsWithIndices = function(text, options) {
- if (!options) {
- options = {extractUrlsWithoutProtocol: true};
- }
--
- if (!text || (options.extractUrlsWithoutProtocol ? !text.match(/\./) : !text.match(/:/))) {
- return [];
- }
-
- var urls = [];
-
- while (twttr.txt.regexen.extractUrl.exec(text)) {
- var before = RegExp.$2, url = RegExp.$3, protocol = RegExp.$4, domain = RegExp.$5, path = RegExp.$7;
-@@ -876,41 +897,38 @@ var window = {};
- // if protocol is missing and domain contains non-ASCII characters,
- // extract ASCII-only domains.
- if (!protocol) {
- if (!options.extractUrlsWithoutProtocol
- || before.match(twttr.txt.regexen.invalidUrlWithoutProtocolPrecedingChars)) {
- continue;
- }
- var lastUrl = null,
-- lastUrlInvalidMatch = false,
- asciiEndPosition = 0;
- domain.replace(twttr.txt.regexen.validAsciiDomain, function(asciiDomain) {
- var asciiStartPosition = domain.indexOf(asciiDomain, asciiEndPosition);
- asciiEndPosition = asciiStartPosition + asciiDomain.length;
- lastUrl = {
- url: asciiDomain,
- indices: [startPosition + asciiStartPosition, startPosition + asciiEndPosition]
- };
-- lastUrlInvalidMatch = asciiDomain.match(twttr.txt.regexen.invalidShortDomain);
-- if (!lastUrlInvalidMatch) {
-+ if (path
-+ || asciiDomain.match(twttr.txt.regexen.validSpecialShortDomain)
-+ || !asciiDomain.match(twttr.txt.regexen.invalidShortDomain)) {
- urls.push(lastUrl);
- }
- });
-
- // no ASCII-only domain found. Skip the entire URL.
- if (lastUrl == null) {
- continue;
- }
-
- // lastUrl only contains domain. Need to add path and query if they exist.
- if (path) {
-- if (lastUrlInvalidMatch) {
-- urls.push(lastUrl);
-- }
- lastUrl.url = url.replace(domain, lastUrl.url);
- lastUrl.indices[1] = endPosition;
- }
- } else {
- // In the case of t.co URLs, don't allow additional path characters.
- if (url.match(twttr.txt.regexen.validTcoUrl)) {
- url = RegExp.lastMatch;
- endPosition = startPosition + url.length;
-@@ -1194,30 +1212,30 @@ var window = {};
-
- // Returns the length of Tweet text with consideration to t.co URL replacement
- // and chars outside the basic multilingual plane that use 2 UTF16 code points
- twttr.txt.getTweetLength = function(text, options) {
- if (!options) {
- options = {
- // These come from https://api.twitter.com/1/help/configuration.json
- // described by https://dev.twitter.com/docs/api/1/get/help/configuration
-- short_url_length: 22,
-+ short_url_length: 23,
- short_url_length_https: 23
- };
- }
- var textLength = twttr.txt.getUnicodeTextLength(text),
- urlsWithIndices = twttr.txt.extractUrlsWithIndices(text);
- twttr.txt.modifyIndicesFromUTF16ToUnicode(text, urlsWithIndices);
-
- for (var i = 0; i < urlsWithIndices.length; i++) {
-- // Subtract the length of the original URL
-+ // Subtract the length of the original URL
- textLength += urlsWithIndices[i].indices[0] - urlsWithIndices[i].indices[1];
-
- // Add 23 characters for URL starting with https://
-- // Otherwise add 22 characters
-+ // http:// URLs still use https://t.co so they are 23 characters as well
- if (urlsWithIndices[i].url.toLowerCase().match(twttr.txt.regexen.urlHasHttps)) {
- textLength += options.short_url_length_https;
- } else {
- textLength += options.short_url_length;
- }
- }
-
- return textLength;
-@@ -1237,22 +1255,29 @@ var window = {};
- return "empty";
- }
-
- // Determine max length independent of URL length
- if (twttr.txt.getTweetLength(text) > MAX_LENGTH) {
- return "too_long";
- }
-
-+ if (twttr.txt.hasInvalidCharacters(text)) {
-+ return "invalid_characters";
-+ }
-+
-+ return false;
-+ };
-+
-+ twttr.txt.hasInvalidCharacters = function(text) {
- for (var i = 0; i < INVALID_CHARACTERS.length; i++) {
- if (text.indexOf(INVALID_CHARACTERS[i]) >= 0) {
-- return "invalid_characters";
-+ return true;
- }
- }
--
- return false;
- };
-
- twttr.txt.isValidTweetText = function(text) {
- return !twttr.txt.isInvalidTweet(text);
- };
-
- twttr.txt.isValidUsername = function(username) {
-@@ -1334,16 +1359,20 @@ var window = {};
- // RegExp["$&"] is the text of the last match
- return (!string || (string.match(regex) && RegExp["$&"] === string));
- }
-
- if (typeof module != 'undefined' && module.exports) {
- module.exports = twttr.txt;
- }
-
-+ if (typeof define == 'function' && define.amd) {
-+ define([], twttr.txt);
-+ }
-+
- if (typeof window != 'undefined') {
- if (window.twttr) {
- for (var prop in twttr) {
- window.twttr[prop] = twttr[prop];
- }
- } else {
- window.twttr = twttr;
- }
-# HG changeset patch
-# User Arlo Breault <arlolra(a)gmail.com>
-# Date 1458087794 25200
-# Tue Mar 15 17:23:14 2016 -0700
-# Branch THUNDERBIRD4530_2016082513_RELBRANCH
-# Node ID f1a6121c96fc353621c823b5d2757805fb65b721
-# Parent 9f2addccb7a8d4875746abd96f6beba38ef0f398
-Bug 955642 - Handle Twitter direct messages (DMs)
-
-diff --git a/chat/components/src/imConversations.js b/chat/components/src/imConversations.js
---- a/chat/components/src/imConversations.js
-+++ b/chat/components/src/imConversations.js
-@@ -25,16 +25,17 @@ OutgoingMessage.prototype = {
- action: false
- };
-
- function imMessage(aPrplMessage) {
- this.prplMessage = aPrplMessage;
- }
- imMessage.prototype = {
- __proto__: ClassInfo(["imIMessage", "prplIMessage"], "IM Message"),
-+ get wrappedJSObject() { return this; },
- cancelled: false,
- color: "",
- _displayMessage: null,
-
- get displayMessage() {
- // Explicitly test for null so that blank messages don't fall back to
- // the original. Especially problematic in encryption extensions like OTR.
- return this._displayMessage !== null ?
-@@ -409,17 +410,18 @@ UIConversation.prototype = {
- this._observers = this._observers.filter(o => o !== aObserver);
- },
- notifyObservers: function(aSubject, aTopic, aData) {
- if (aTopic == "new-text") {
- aSubject = new imMessage(aSubject);
- this.notifyObservers(aSubject, "received-message");
- if (aSubject.cancelled)
- return;
-- aSubject.conversation.prepareForDisplaying(aSubject);
-+ if (!aSubject.system)
-+ aSubject.conversation.prepareForDisplaying(aSubject);
-
- this._messages.push(aSubject);
- ++this._unreadMessageCount;
- if (aSubject.incoming && !aSubject.system) {
- ++this._unreadIncomingMessageCount;
- if (!this.isChat || aSubject.containsNick)
- ++this._unreadTargetedMessageCount;
- }
-diff --git a/chat/modules/jsProtoHelper.jsm b/chat/modules/jsProtoHelper.jsm
---- a/chat/modules/jsProtoHelper.jsm
-+++ b/chat/modules/jsProtoHelper.jsm
-@@ -376,16 +376,17 @@ var GenericAccountBuddyPrototype = {
- // aUserName is required only if aBuddy is null, i.e., we are adding a buddy.
- function AccountBuddy(aAccount, aBuddy, aTag, aUserName) {
- this._init(aAccount, aBuddy, aTag, aUserName);
- }
- AccountBuddy.prototype = GenericAccountBuddyPrototype;
-
- var GenericMessagePrototype = {
- __proto__: ClassInfo("prplIMessage", "generic message object"),
-+ get wrappedJSObject() { return this; },
-
- _lastId: 0,
- _init: function (aWho, aMessage, aObject) {
- this.id = ++GenericMessagePrototype._lastId;
- this.time = Math.round(new Date() / 1000);
- this.who = aWho;
- this.message = aMessage;
- this.originalMessage = aMessage;
-diff --git a/chat/protocols/twitter/twitter.js b/chat/protocols/twitter/twitter.js
---- a/chat/protocols/twitter/twitter.js
-+++ b/chat/protocols/twitter/twitter.js
-@@ -31,32 +31,40 @@ ChatBuddy.prototype = {
- let userInfo = this._account._userInfo.get(this.name);
- if (userInfo)
- return userInfo.profile_image_url;
- return undefined;
- },
- set buddyIconFilename(aName) {
- // Prevent accidental removal of the getter.
- throw("Don't set chatBuddy.buddyIconFilename directly for Twitter.");
-+ },
-+ createConversation: function() {
-+ return this._account.createConversation(this._name);
- }
--}
-+};
-
- function Tweet(aTweet, aWho, aMessage, aObject)
- {
- this._tweet = aTweet;
- this._init(aWho, aMessage, aObject);
- }
- Tweet.prototype = {
- __proto__: GenericMessagePrototype,
- _deleted: false,
- getActions: function(aCount) {
- let account = this.conversation._account;
- let actions = [];
-
-- if (account.connected) {
-+ if (!this.conversation.isChat) {
-+ if (aCount)
-+ aCount.value = actions.length;
-+ return actions;
-+ }
-+ else if (account.connected) {
- actions.push(
- new Action(_("action.reply"), function() {
- this.conversation.startReply(this._tweet);
- }, this)
- );
- if (this.incoming) {
- actions.push(
- new Action(_("action.retweet"), function() {
-@@ -118,17 +126,109 @@ function Action(aLabel, aAction, aTweet)
- this._action = aAction;
- this._tweet = aTweet;
- }
- Action.prototype = {
- __proto__: ClassInfo("prplIMessageAction", "generic message action object"),
- get run() { return this._action.bind(this._tweet); }
- };
-
--function Conversation(aAccount)
-+// Properties / methods shared by both DirectMessageConversation and
-+// TimelineConversation.
-+var GenericTwitterConversation = {
-+ getTweetLength: function (aString) {
-+ // Use the Twitter library to calculate the length.
-+ return twttr.txt.getTweetLength(aString, this._account.config);
-+ },
-+ systemMessage: function(aMessage, aIsError, aDate) {
-+ let flags = {system: true};
-+ if (aIsError)
-+ flags.error = true;
-+ if (aDate)
-+ flags.time = aDate;
-+ this.writeMessage("twitter.com", aMessage, flags);
-+ },
-+ onSentCallback: function(aMsg, aData) {
-+ // The conversation may have been unitialized in the time it takes for
-+ // the async callback to fire. Use `_observers` as a proxy for uninit'd.
-+ if (!Array.isArray(this._observers))
-+ return;
-+
-+ let tweet = JSON.parse(aData);
-+ // The OTR extension requires that the protocol not modify the message
-+ // (see the notes at `imIOutgoingMessage`). That's the contract we made.
-+ // Unfortunately, Twitter trims tweets and substitutes links.
-+ tweet.text = aMsg;
-+ this.displayMessages([tweet]);
-+ },
-+ prepareForDisplaying: function(aMsg) {
-+ let text = aMsg.displayMessage;
-+ let tweet = aMsg.wrappedJSObject.prplMessage.wrappedJSObject._tweet;
-+
-+ // Handle retweets: retweeted_status contains the object for the original
-+ // tweet that is being retweeted.
-+ // If the retweet prefix ("RT @<username>: ") causes the tweet to be over
-+ // 140 characters, ellipses will be added. In this case, we want to get
-+ // the FULL text from the original tweet and update the entities to match.
-+ // Note: the truncated flag is not always set correctly by twitter, so we
-+ // always make use of the original tweet.
-+ if ("retweeted_status" in tweet) {
-+ let retweet = tweet["retweeted_status"];
-+ // We're going to take portions of the retweeted status and replace parts
-+ // of the original tweet, the retweeted status prepends the original
-+ // status with "RT @<username>: ", we need to keep the prefix.
-+ // Note: this doesn't play nice with extensions that may have altered
-+ // `text` to this point, but at least OTR doesn't act on `isChat`.
-+ let offset = text.indexOf(": ") + 2;
-+ text = text.slice(0, offset) + retweet.text;
-+ }
-+
-+ // Pass in the url entities so the t.co links are replaced.
-+ aMsg.displayMessage = twttr.txt.autoLink(text, {
-+ urlEntities: tweet.entities.urls.map(function(u) {
-+ var o = Object.assign(u);
-+ // But remove the indices so they apply in the face of modifications.
-+ delete o.indices;
-+ return o;
-+ })
-+ });
-+
-+ GenericConversationPrototype.prepareForDisplaying.apply(this, arguments);
-+ },
-+ displayTweet: function(aTweet, aUser) {
-+ let name = aUser.screen_name;
-+
-+ let flags = name == this.nick ? {outgoing: true} : {incoming: true};
-+ flags.time = Math.round(new Date(aTweet.created_at) / 1000);
-+ flags._iconURL = aUser.profile_image_url;
-+ if (aTweet.delayed)
-+ flags.delayed = true;
-+ if (aTweet.entities && aTweet.entities.user_mentions &&
-+ Array.isArray(aTweet.entities.user_mentions) &&
-+ aTweet.entities.user_mentions.some(mention => mention.screen_name == this.nick))
-+ flags.containsNick = true;
-+
-+ (new Tweet(aTweet, name, aTweet.text, flags)).conversation = this;
-+ },
-+ _parseError: function(aData) {
-+ let error = "";
-+ try {
-+ let data = JSON.parse(aData);
-+ if ("error" in data)
-+ error = data.error;
-+ else if ("errors" in data)
-+ error = data.errors[0].message;
-+ if (error)
-+ error = "(" + error + ")";
-+ } catch(e) {}
-+ return error;
-+ }
-+};
-+
-+function TimelineConversation(aAccount)
- {
- this._init(aAccount);
- this._ensureParticipantExists(aAccount.name);
- // We need the screen names for the IDs in _friends, but _userInfo is
- // indexed by name, so we build an ID -> name map.
- let entries = [];
- for (let [name, userInfo] of aAccount._userInfo) {
- entries.push([userInfo.id_str, name]);
-@@ -139,17 +239,17 @@ function Conversation(aAccount)
-
- // If the user's info has already been received, update the timeline topic.
- if (aAccount._userInfo.has(aAccount.name)) {
- let userInfo = aAccount._userInfo.get(aAccount.name);
- if ("description" in userInfo)
- this.setTopic(userInfo.description, aAccount.name, true);
- }
- }
--Conversation.prototype = {
-+TimelineConversation.prototype = {
- __proto__: GenericConvChatPrototype,
- unInit: function() {
- delete this._account._timeline;
- GenericConvChatPrototype.unInit.call(this);
- },
- inReplyToStatusId: null,
- startReply: function(aTweet) {
- this.inReplyToStatusId = aTweet.id_str;
-@@ -169,203 +269,66 @@ Conversation.prototype = {
- .map(aNick => "@" + aNick)
- .join(" ") + " ";
-
- this.notifyObservers(null, "replying-to-prompt", prompt);
- this.notifyObservers(null, "status-text-changed",
- _("replyingToStatusText", aTweet.text));
- },
- reTweet: function(aTweet) {
-- this._account.reTweet(aTweet, this.onSentCallback,
-- function(aException, aData) {
-+ this._account.reTweet(aTweet, null, function(aException, aData) {
- this.systemMessage(_("error.retweet", this._parseError(aData),
- aTweet.text), true);
- }, this);
- },
-- getTweetLength: function (aString) {
-- // Use the Twitter library to calculate the length.
-- return twttr.txt.getTweetLength(aString, this._account.config);
-- },
-- sendMsg: function (aMsg) {
-+ sendMsg: function(aMsg) {
- if (this.getTweetLength(aMsg) > kMaxMessageLength) {
- this.systemMessage(_("error.tooLong"), true);
- throw Cr.NS_ERROR_INVALID_ARG;
- }
-- this._account.tweet(aMsg, this.inReplyToStatusId, this.onSentCallback,
-+ this._account.tweet(aMsg, this.inReplyToStatusId,
-+ this.onSentCallback.bind(this, aMsg),
- function(aException, aData) {
- let error = this._parseError(aData);
- this.systemMessage(_("error.general", error, aMsg), true);
- }, this);
- this.sendTyping("");
- },
- sendTyping: function(aString) {
- if (aString.length == 0 && this.inReplyToStatusId) {
- delete this.inReplyToStatusId;
- this.notifyObservers(null, "status-text-changed", "");
- return kMaxMessageLength;
- }
- return kMaxMessageLength - this.getTweetLength(aString);
- },
-- systemMessage: function(aMessage, aIsError, aDate) {
-- let flags = {system: true};
-- if (aIsError)
-- flags.error = true;
-- if (aDate)
-- flags.time = aDate;
-- this.writeMessage("twitter.com", aMessage, flags);
-- },
-- onSentCallback: function(aData) {
-- let tweet = JSON.parse(aData);
-- if (tweet.user.screen_name != this._account.name)
-- throw "Wrong screen_name... Uh?";
-- this._account.displayMessages([tweet]);
-- },
-- _parseError: function(aData) {
-- let error = "";
-- try {
-- let data = JSON.parse(aData);
-- if ("error" in data)
-- error = data.error;
-- else if ("errors" in data)
-- error = data.errors[0].message;
-- if (error)
-- error = "(" + error + ")";
-- } catch(e) {}
-- return error;
-- },
-- parseTweet: function(aTweet) {
-- let text = aTweet.text;
-- let entities = {};
-- // Handle retweets: retweeted_status contains the object for the original
-- // tweet that is being retweeted.
-- // If the retweet prefix ("RT @<username>: ") causes the tweet to be over
-- // 140 characters, ellipses will be added. In this case, we want to get
-- // the FULL text from the original tweet and update the entities to match.
-- // Note: the truncated flag is not always set correctly by twitter, so we
-- // always make use of the original tweet.
-- if ("retweeted_status" in aTweet) {
-- let retweet = aTweet["retweeted_status"];
-- // We're going to take portions of the retweeted status and replace parts
-- // of the original tweet, the retweeted status prepends the original
-- // status with "RT @<username>: ", we need to keep the prefix.
-- let offset = text.indexOf(": ") + 2;
-- text = text.slice(0, offset) + retweet.text;
--
-- // Keep any entities that refer to the prefix (we can refer directly to
-- // aTweet for these since they are not edited).
-- if ("entities" in aTweet) {
-- for (let type in aTweet.entities) {
-- let filteredEntities =
-- aTweet.entities[type].filter(e => e.indices[0] < offset);
-- if (filteredEntities.length)
-- entities[type] = filteredEntities;
-- }
-- }
--
-- // Add the entities from the retweet (a copy of these must be made since
-- // they will be edited and we do not wish to change aTweet).
-- if ("entities" in retweet) {
-- for (let type in retweet.entities) {
-- if (!(type in entities))
-- entities[type] = [];
-+ displayMessages: function(aMessages) {
-+ let account = this._account;
-+ let lastMsgId = account._lastMsgId;
-+ for (let tweet of aMessages) {
-+ if (!("user" in tweet) || !("text" in tweet) || !("id_str" in tweet) ||
-+ account._knownMessageIds.has(tweet.id_str))
-+ continue;
-+ let id = tweet.id_str;
-+ // Update the last known message.
-+ // Compare the length of the ids first, and then the text.
-+ // This avoids converting tweet ids into rounded numbers.
-+ if (id.length > lastMsgId.length ||
-+ (id.length == lastMsgId.length && id > lastMsgId))
-+ lastMsgId = id;
-+ account._knownMessageIds.add(id);
-+ account.setUserInfo(tweet.user);
-
-- // Append the entities from the original status.
-- entities[type] = entities[type].concat(
-- retweet.entities[type].map(function(aEntity) {
-- let entity = Object.create(aEntity);
-- // Add the offset to the indices to account for the prefix.
-- entity.indices = entity.indices.map(i => i + offset);
-- return entity;
-- })
-- );
-- }
-- }
-- } else {
-- // For non-retweets, we just want to use the entities that are given.
-- if ("entities" in aTweet)
-- entities = aTweet.entities;
-+ this._ensureParticipantExists(tweet.user.screen_name);
-+ this.displayTweet(tweet, tweet.user);
- }
--
-- if (Object.keys(entities).length) {
-- /* entArray is an array of entities ready to be replaced in the tweet,
-- * each entity contains:
-- * - start: the start index of the entity inside the tweet,
-- * - end: the end index of the entity inside the tweet,
-- * - str: the string that should be replaced inside the tweet,
-- * - href: the url (href attribute) of the created link tag,
-- * - [optional] text: the text to display for the link,
-- * The original string (str) will be used if this is not set.
-- * - [optional] title: the title attribute for the link.
-- */
-- let entArray = [];
-- if ("hashtags" in entities && Array.isArray(entities.hashtags)) {
-- entArray = entArray.concat(entities.hashtags.map(h => ({
-- start: h.indices[0],
-- end: h.indices[1],
-- str: "#" + h.text,
-- href: "https://twitter.com/#!/search?q=%23" + h.text})));
-- }
-- if ("urls" in entities && Array.isArray(entities.urls)) {
-- entArray = entArray.concat(entities.urls.map(u => ({
-- start: u.indices[0],
-- end: u.indices[1],
-- str: u.url,
-- text: u.display_url || u.url,
-- href: u.expanded_url || u.url})));
-- }
-- if ("user_mentions" in entities &&
-- Array.isArray(entities.user_mentions)) {
-- entArray = entArray.concat(entities.user_mentions.map(um => ({
-- start: um.indices[0],
-- end: um.indices[1],
-- str: "@" + um.screen_name,
-- text: '@<span class="ib-person">' + um.screen_name + "</span>",
-- title: um.name,
-- href: "https://twitter.com/" + um.screen_name})));
-- }
-- entArray.sort((a, b) => a.start - b.start);
-- let offset = 0;
-- for (let entity of entArray) {
-- let str = text.substring(offset + entity.start, offset + entity.end);
-- if (str[0] == "\uFF20") // @ - unicode character similar to @
-- str = "@" + str.substring(1);
-- if (str[0] == "\uFF03") // # - unicode character similar to #
-- str = "#" + str.substring(1);
-- if (str.toLowerCase() != entity.str.toLowerCase())
-- continue;
--
-- let html = "<a href=\"" + entity.href + "\"";
-- if ("title" in entity)
-- html += " title=\"" + entity.title + "\"";
-- html += ">" + ("text" in entity ? entity.text : entity.str) + "</a>";
-- text = text.slice(0, offset + entity.start) + html +
-- text.slice(offset + entity.end);
-- offset += html.length - (entity.end - entity.start);
-- }
-+ if (lastMsgId != account._lastMsgId) {
-+ account._lastMsgId = lastMsgId;
-+ account.prefs.setCharPref("lastMessageId", account._lastMsgId);
- }
--
-- return text;
-- },
-- displayTweet: function(aTweet) {
-- let name = aTweet.user.screen_name;
-- this._ensureParticipantExists(name);
-- let text = this.parseTweet(aTweet);
--
-- let flags =
-- name == this._account.name ? {outgoing: true} : {incoming: true};
-- flags.time = Math.round(new Date(aTweet.created_at) / 1000);
-- flags._iconURL = aTweet.user.profile_image_url;
-- if (aTweet.delayed)
-- flags.delayed = true;
-- if (aTweet.entities && aTweet.entities.user_mentions &&
-- Array.isArray(aTweet.entities.user_mentions) &&
-- aTweet.entities.user_mentions.some(mention => mention.screen_name == this.nick))
-- flags.containsNick = true;
--
-- (new Tweet(aTweet, name, text, flags)).conversation = this;
- },
- _ensureParticipantExists: function(aNick) {
- if (this._participants.has(aNick))
- return;
-
- let chatBuddy = new ChatBuddy(aNick, this._account);
- this._participants.set(aNick, chatBuddy);
- this.notifyObservers(new nsSimpleEnumerator([chatBuddy]),
-@@ -377,23 +340,60 @@ Conversation.prototype = {
- set nick(aNick) {},
- get topicSettable() { return this.nick == this._account.name; },
- get topic() { return this._topic; }, // can't add a setter without redefining the getter
- set topic(aTopic) {
- if (this.topicSettable)
- this._account.setUserDescription(aTopic);
- }
- };
-+Object.assign(TimelineConversation.prototype, GenericTwitterConversation);
-+
-+function DirectMessageConversation(aAccount, aName)
-+{
-+ this._init(aAccount, aName);
-+}
-+DirectMessageConversation.prototype = {
-+ __proto__: GenericConvIMPrototype,
-+ sendMsg: function(aMsg) {
-+ this._account.directMessage(aMsg, this.name,
-+ this.onSentCallback.bind(this, aMsg),
-+ function(aException, aData) {
-+ let error = this._parseError(aData);
-+ this.systemMessage(_("error.general", error, aMsg), true);
-+ }, this);
-+ },
-+ displayMessages: function(aMessages) {
-+ let account = this._account;
-+ for (let tweet of aMessages) {
-+ if (!("sender" in tweet) || !("recipient" in tweet) ||
-+ !("text" in tweet) || !("id_str" in tweet))
-+ continue;
-+ account.setUserInfo(tweet.sender);
-+ account.setUserInfo(tweet.recipient);
-+ this.displayTweet(tweet, tweet.sender);
-+ }
-+ },
-+ unInit: function() {
-+ this._account.removeConversation(this.name);
-+ GenericConvIMPrototype.unInit.call(this);
-+ },
-+ get nick() { return this._account.name; },
-+ set nick(aNick) {}
-+}
-+Object.assign(DirectMessageConversation.prototype, GenericTwitterConversation);
-
- function Account(aProtocol, aImAccount)
- {
- this._init(aProtocol, aImAccount);
- this._knownMessageIds = new Set();
- this._userInfo = new Map();
- this._friends = new Set();
-+ // Contains just `DirectMessageConversation`s
-+ this._conversations = new Map();
- }
- Account.prototype = {
- __proto__: GenericAccountPrototype,
-
- // The correct normalization for twitter would be just toLowerCase().
- // Unfortunately, for backwards compatibility we retain this normalization,
- // which can cause edge cases for usernames with underscores.
- normalize: aString => aString.replace(/[^a-z0-9]/gi, "").toLowerCase(),
-@@ -554,16 +554,21 @@ Account.prototype = {
- reTweet: function(aTweet, aOnSent, aOnError, aThis) {
- let url = "1.1/statuses/retweet/" + aTweet.id_str + ".json";
- this.signAndSend(url, null, [], aOnSent, aOnError, aThis);
- },
- destroy: function(aTweet, aOnSent, aOnError, aThis) {
- let url = "1.1/statuses/destroy/" + aTweet.id_str + ".json";
- this.signAndSend(url, null, [], aOnSent, aOnError, aThis);
- },
-+ directMessage: function(aMsg, aName, aOnSent, aOnError, aThis) {
-+ let POSTData = [["text", aMsg], ["screen_name", aName]];
-+ this.signAndSend("1.1/direct_messages/new.json", null, POSTData, aOnSent,
-+ aOnError, aThis);
-+ },
-
- _friends: null,
- follow: function(aUserName) {
- this.signAndSend("1.1/friendships/create.json", null,
- [["screen_name", aUserName]]);
- },
- stopFollowing: function(aUserName) {
- // friendships/destroy will return the user in case of success.
-@@ -616,39 +621,17 @@ Account.prototype = {
- getParams = "?q=" + trackQuery + lastMsgParam + "&count=100";
- let url = "1.1/search/tweets.json" + getParams;
- this._pendingRequests.push(
- this.signAndSend(url, null, null, this.onTimelineReceived,
- this.onTimelineError, this, null));
- }
- },
-
-- get timeline() { return this._timeline || (this._timeline = new Conversation(this)); },
-- displayMessages: function(aMessages) {
-- let lastMsgId = this._lastMsgId;
-- for (let tweet of aMessages) {
-- if (!("user" in tweet) || !("text" in tweet) || !("id_str" in tweet) ||
-- this._knownMessageIds.has(tweet.id_str))
-- continue;
-- let id = tweet.id_str;
-- // Update the last known message.
-- // Compare the length of the ids first, and then the text.
-- // This avoids converting tweet ids into rounded numbers.
-- if (id.length > lastMsgId.length ||
-- (id.length == lastMsgId.length && id > lastMsgId))
-- lastMsgId = id;
-- this._knownMessageIds.add(id);
-- this.setUserInfo(tweet.user);
-- this.timeline.displayTweet(tweet);
-- }
-- if (lastMsgId != this._lastMsgId) {
-- this._lastMsgId = lastMsgId;
-- this.prefs.setCharPref("lastMessageId", this._lastMsgId);
-- }
-- },
-+ get timeline() { return this._timeline || (this._timeline = new TimelineConversation(this)); },
-
- onTimelineError: function(aError, aResponseText, aRequest) {
- this.ERROR(aError);
- if (aRequest.status == 401)
- ++this._timelineAuthError;
- this._doneWithTimelineRequest(aRequest);
- },
-
-@@ -686,17 +669,17 @@ Account.prototype = {
- this.reportConnected();
-
- // If the conversation already exists, notify it we are back online.
- if (this._timeline)
- this._timeline.notifyObservers(this._timeline, "update-buddy-status");
-
- this._timelineBuffer.sort(this.sortByDate);
- this._timelineBuffer.forEach(aTweet => aTweet.delayed = true);
-- this.displayMessages(this._timelineBuffer);
-+ this.timeline.displayMessages(this._timelineBuffer);
-
- // Fetch userInfo for the user if we don't already have it.
- this.requestBuddyInfo(this.name);
-
- // Reset in case we get disconnected
- delete this._timelineBuffer;
- delete this._pendingRequests;
-
-@@ -748,18 +731,23 @@ Account.prototype = {
- continue;
- let msg;
- try {
- msg = JSON.parse(message);
- } catch (e) {
- this.ERROR(e + " while parsing " + message);
- continue;
- }
-- if ("text" in msg)
-- this.displayMessages([msg]);
-+ if ("direct_message" in msg) {
-+ let dm = msg["direct_message"];
-+ if (dm.sender_screen_name !== this.name) // These are displayed on send.
-+ this.getConversation(dm.sender_screen_name).displayMessages([dm]);
-+ }
-+ else if ("text" in msg)
-+ this.timeline.displayMessages([msg]);
- else if ("friends" in msg) {
- // Filter out the IDs that info has already been received from (e.g. a
- // tweet has been received as part of the timeline request).
- let userInfoIds = new Set();
- for (let userInfo of this._userInfo.values())
- userInfoIds.add(userInfo.id_str);
- let ids = msg.friends.filter(
- aId => !userInfoIds.has(aId.toString()));
-@@ -1102,16 +1090,29 @@ Account.prototype = {
- this.config = JSON.parse(aData);
- },
-
- // Allow us to reopen the timeline via the join chat menu.
- get canJoinChat() { return true; },
- joinChat: function(aComponents) {
- // The 'timeline' getter opens a timeline conversation if none exists.
- this.timeline;
-+ },
-+
-+ getConversation: function(aName) {
-+ if (!this._conversations.has(aName))
-+ this._conversations.set(aName, new DirectMessageConversation(this, aName));
-+ return this._conversations.get(aName);
-+ },
-+ removeConversation: function(aName) {
-+ if (this._conversations.has(aName))
-+ this._conversations.delete(aName);
-+ },
-+ createConversation: function(aName) {
-+ return this.getConversation(aName);
- }
- };
-
- // Shortcut to get the JavaScript account object.
- function getAccount(aConv) { return aConv.wrappedJSObject._account; }
-
- function TwitterProtocol() {
- this.registerCommands();
-# HG changeset patch
-# User Arlo Breault <arlolra(a)gmail.com>
-# Date 1472492642 25200
-# Mon Aug 29 10:44:02 2016 -0700
-# Branch THUNDERBIRD4530_2016082513_RELBRANCH
-# Node ID 600363f6a85a72e0ef6ccf104b6bc5c8b4f9a0c0
-# Parent f1a6121c96fc353621c823b5d2757805fb65b721
-Remove backwards compat. normalize in twitter prpl
-
- * Just use .toLowerCase()
-
-diff --git a/chat/protocols/twitter/twitter.js b/chat/protocols/twitter/twitter.js
---- a/chat/protocols/twitter/twitter.js
-+++ b/chat/protocols/twitter/twitter.js
-@@ -388,21 +388,16 @@ function Account(aProtocol, aImAccount)
- this._userInfo = new Map();
- this._friends = new Set();
- // Contains just `DirectMessageConversation`s
- this._conversations = new Map();
- }
- Account.prototype = {
- __proto__: GenericAccountPrototype,
-
-- // The correct normalization for twitter would be just toLowerCase().
-- // Unfortunately, for backwards compatibility we retain this normalization,
-- // which can cause edge cases for usernames with underscores.
-- normalize: aString => aString.replace(/[^a-z0-9]/gi, "").toLowerCase(),
--
- consumerKey: Services.prefs.getCharPref("chat.twitter.consumerKey"),
- consumerSecret: Services.prefs.getCharPref("chat.twitter.consumerSecret"),
- completionURI: "http://oauthcallback.local/",
- baseURI: "https://api.twitter.com/",
- _lastMsgId: "",
-
- // Use this to keep track of the pending timeline requests. We attempt to fetch
- // home_timeline, @ mentions and tracked keywords (i.e. 3 timelines)
diff --git a/projects/instantbird/trac-16489.patch b/projects/instantbird/trac-16489.patch
deleted file mode 100644
index 4d58846..0000000
--- a/projects/instantbird/trac-16489.patch
+++ /dev/null
@@ -1,108 +0,0 @@
-# HG changeset patch
-# User Arlo Breault <arlolra(a)gmail.com>
-# Date 1447735073 28800
-# Mon Nov 16 20:37:53 2015 -0800
-# Node ID dd2cd9b18e3a356e227d02beec052f8591509cec
-# Parent 073468887b0faecb810a6e4463a2806924fead81
-trac 16489 - autologin
-
-diff --git a/chat/components/src/imAccounts.js b/chat/components/src/imAccounts.js
---- a/chat/components/src/imAccounts.js
-+++ b/chat/components/src/imAccounts.js
-@@ -588,7 +588,7 @@
- },
-
- get autoLogin() {
-- let autoLogin = true;
-+ let autoLogin = false;
- try {
- autoLogin = this.prefBranch.getBoolPref(kPrefAccountAutoLogin);
- } catch (e) { }
-diff --git a/im/content/account.xml b/im/content/account.xml
---- a/im/content/account.xml
-+++ b/im/content/account.xml
-@@ -41,10 +41,6 @@
- accesskey="&certmgr.addException.accesskey;"/>
- <xul:spacer flex="1"/>
- </xul:vbox>
-- <xul:checkbox label="&account.autoSignOn.label;" dir="reverse"
-- xbl:inherits="checked=autologin" class="autoSignOn"
-- accesskey="&account.autoSignOn.accesskey;"
-- oncommand="gAccountManager.autologin()"/>
- </xul:hbox>
- <xul:hbox flex="1" class="account-buttons" anonid="buttons"
- xbl:inherits="autologin"/>
-diff --git a/im/content/accountWizard.js b/im/content/accountWizard.js
---- a/im/content/accountWizard.js
-+++ b/im/content/accountWizard.js
-@@ -442,22 +442,13 @@
- throw "unknown type";
- }
- }
-- let autologin = this.getValue("connectAutomatically");
-- acc.autoLogin = autologin;
-+ acc.autoLogin = false;
-
- if (this.proto.usePurpleProxy)
- acc.proxyInfo = this.proxy;
-
- acc.save();
-
-- try {
-- if (autologin)
-- acc.connect();
-- } catch (e) {
-- // If the connection fails (for example if we are currently in
-- // offline mode), we still want to close the account wizard
-- }
--
- if (window.opener) {
- let am = window.opener.gAccountManager;
- if (am)
-diff --git a/im/content/accountWizard.xul b/im/content/accountWizard.xul
---- a/im/content/accountWizard.xul
-+++ b/im/content/accountWizard.xul
-@@ -137,8 +137,6 @@
- </columns>
- <rows id="summaryRows"/>
- </grid>
-- <separator/>
-- <checkbox id="connectAutomatically" label= "&accountSummary.connectAutomatically.label;" checked="true"/>
- </wizardpage>
-
- </wizard>
-diff --git a/im/content/preferences/main.xul b/im/content/preferences/main.xul
---- a/im/content/preferences/main.xul
-+++ b/im/content/preferences/main.xul
-@@ -20,7 +20,6 @@
- <script type="application/javascript" src="chrome://instantbird/content/preferences/main.js"/>
-
- <preferences id="mainPreferences">
-- <preference id="messenger.startup.action" name="messenger.startup.action" type="int"/>
- <preference id="messenger.options.playSounds.blist" name="messenger.options.playSounds.blist" type="bool"/>
- <preference id="messenger.options.playSounds.message" name="messenger.options.playSounds.message" type="bool"/>
- <preference id="messenger.options.getAttentionOnNewMessages" name="messenger.options.getAttentionOnNewMessages" type="bool"/>
-@@ -33,23 +32,6 @@
- <preference id="messenger.options.notifyOfNewMessages" name="messenger.options.notifyOfNewMessages" type="bool"/>
- </preferences>
-
-- <!-- Startup -->
-- <groupbox id="startupGroup">
-- <caption label="&startup.label;"/>
--
-- <hbox align="center">
-- <label value="&startupAction.label;" accesskey="&startupAction.accesskey;"
-- control="messengerStartupAction"/>
-- <menulist id="messengerStartupAction" preference="messenger.startup.action">
-- <menupopup>
-- <menuitem label="&startupOffline.label;" value="0"/>
-- <menuitem label="&startupConnectAuto.label;" value="1"/>
-- </menupopup>
-- </menulist>
-- </hbox>
-- </groupbox>
--
--
- <groupbox id="accountsMgrGroup" orient="horizontal" align="center">
- <caption label="&accountsMgr.label;"/>
-
diff --git a/projects/instantbird/trac-17494.patch b/projects/instantbird/trac-17494.patch
deleted file mode 100644
index fcd7703..0000000
--- a/projects/instantbird/trac-17494.patch
+++ /dev/null
@@ -1,83 +0,0 @@
-# HG changeset patch
-# User Arlo Breault <arlolra(a)gmail.com>
-# Date 1454457891 28800
-# Node ID 4cfc2a04ebe02f53d789c7c27f8c3cd2a40b6483
-# Parent 19694424a48639d4f9ca458e3e891292e0c2ae1e
-Bug 1245325 - Better error reporting for failed outgoing messages. r=clokep
-
-diff --git a/chat/locales/en-US/xmpp.properties b/chat/locales/en-US/xmpp.properties
---- a/chat/locales/en-US/xmpp.properties
-+++ b/chat/locales/en-US/xmpp.properties
-@@ -61,31 +61,33 @@ conversation.error.changeTopicFailedNotA
- # %2$S is the text of the message that wasn't delivered.
- conversation.error.sendFailedAsNotInRoom=Message could not be sent to %1$S as you are no longer in the room: %2$S
- # This is displayed in a conversation as an error message when the user sends
- # a message to a room that the recipient is not in.
- # %1$S is the jid of the recipient.
- # %2$S is the text of the message that wasn't delivered.
- conversation.error.sendFailedAsRecipientNotInRoom=Message could not be sent to %1$S as the recipient is no longer in the room: %2$S
- # These are displayed in a conversation as a system error message.
--conversation.error.remoteServerNotFound=Could not reach the recipient's server
-+conversation.error.remoteServerNotFound=Could not reach the recipient's server.
-+conversation.error.unknownSendError=An unknown error occurred on sending this message.
-+# %S is the name of the message recipient.
-+conversation.error.sendServiceUnavailable=It is not possible to send messages to %S at this time.
- # %S is the nick of participant that is not in room.
- conversation.error.nickNotInRoom=%S is not in the room.
- conversation.error.banCommandAnonymousRoom=You can't ban participants from anonymous rooms. Try /kick instead.
- conversation.error.banKickCommandNotAllowed=You don't have the required privileges to remove this participant from the room.
- conversation.error.banKickCommandConflict=Sorry, you can't remove yourself from the room.
- conversation.error.changeNickFailedConflict=Could not change your nick to %S as this nick is already in use.
- conversation.error.changeNickFailedNotAcceptable=Could not change your nick to %S as nicks are locked down in this room.
- conversation.error.inviteFailedForbidden=You don't have the required privileges to invite users to this room.
- # %S is the jid of user that is invited.
- conversation.error.failedJIDNotFound=Could not reach %S.
- # %S is the jid that is invalid.
- conversation.error.invalidJID=%S is an invalid jid (Jabber identifiers must be of the form user@domain).
- conversation.error.commandFailedNotInRoom=You have to rejoin the room to be able to use this command.
--conversation.error.unknownError=Unknown error
-
- # LOCALIZATION NOTE (tooltip.*):
- # These are the titles of lines of information that will appear in
- # the tooltip showing details about a contact or conversation.
- # LOCALIZATION NOTE (tooltip.status):
- # %S will be replaced by the XMPP resource identifier
- tooltip.status=Status (%S)
- tooltip.statusNoResource=Status
-diff --git a/chat/protocols/xmpp/xmpp.jsm b/chat/protocols/xmpp/xmpp.jsm
---- a/chat/protocols/xmpp/xmpp.jsm
-+++ b/chat/protocols/xmpp/xmpp.jsm
-@@ -674,21 +674,28 @@ var XMPPConversationPrototype = {
- this._targetResource = this._account._parseJID(from).resource;
- let flags = {};
- let error = this._account.parseError(aStanza);
- if (error) {
- let norm = this._account.normalize(from);
- let muc = this._account._mucs.get(norm);
-
- if (!aMsg) {
-- // Failed outgoing message unknown.
-- if (error.condition == "remote-server-not-found")
-- aMsg = _("conversation.error.remoteServerNotFound");
-- else
-- aMsg = _("conversation.error.unknownError");
-+ // Failed outgoing message.
-+ switch (error.condition) {
-+ case "remote-server-not-found":
-+ aMsg = _("conversation.error.remoteServerNotFound");
-+ break;
-+ case "service-unavailable":
-+ aMsg = _("conversation.error.sendServiceUnavailable", this.shortName);
-+ break;
-+ default:
-+ aMsg = _("conversation.error.unknownSendError");
-+ break;
-+ }
- }
- else if (this._isMucParticipant && muc && !muc.left &&
- error.condition == "item-not-found") {
- // XEP-0045 (7.5): MUC private messages.
- // If we try to send to participant not in a room we are in.
- aMsg = _("conversation.error.sendFailedAsRecipientNotInRoom",
- this._targetResource, aMsg);
- }
diff --git a/projects/instantbird/trac-17896.patch b/projects/instantbird/trac-17896.patch
deleted file mode 100644
index ebef6e4..0000000
--- a/projects/instantbird/trac-17896.patch
+++ /dev/null
@@ -1,67 +0,0 @@
-# HG changeset patch
-# User aleth <aleth(a)instantbird.org>
-# Date 1454183798 -3600
-# Sat Jan 30 20:56:38 2016 +0100
-# Node ID 6eac77f5536560efd9028d80faa8df716d20907a
-# Parent bd360247708a91a220b79303b4c0f59be61520f9
-Bug 1151784 - Add Edit menu to the conversation window on OS X. r=nhnt11,florian
-
-Adding an edit menu also enables the emoji panel and dictation.
-
-diff --git a/im/content/instantbird.xul b/im/content/instantbird.xul
---- a/im/content/instantbird.xul
-+++ b/im/content/instantbird.xul
-@@ -48,7 +48,28 @@
- <script type="application/javascript" src="chrome://instantbird/content/nsContextMenu.js"/>
-
- #ifdef XP_MACOSX
--#include menus.xul.inc
-+# As menus.xul.inc, but with an Edit menu.
-+ <commandset id="maincommandset"/>
-+ <keyset id="mainkeyset"/>
-+ <menubar id="blistMenubar">
-+ <menu id="menu_edit">
-+ <menupopup id="menu_editpopup">
-+ <menuitem id="menu_undo"/>
-+ <menuitem id="menu_redo"/>
-+ <menuseparator/>
-+ <menuitem id="menu_cut"/>
-+ <menuitem id="menu_copy"/>
-+ <menuitem id="menu_paste"/>
-+ <menuitem id="menu_delete"/>
-+ <menuseparator/>
-+ <menuitem id="menu_selectAll"/>
-+ <menuseparator/>
-+ <menuitem id="menu_find"/>
-+ <menuitem id="menu_findAgain"/>
-+ </menupopup>
-+ </menu>
-+ </menubar>
-+ <popupset id="mainPopupSet"/>
- #endif
-
- <commandset id="conversationsCommands">
-diff --git a/im/content/menus.xul b/im/content/menus.xul
---- a/im/content/menus.xul
-+++ b/im/content/menus.xul
-@@ -43,7 +43,7 @@
- </keyset>
-
- <menubar id="blistMenubar">
-- <menu label="&file.menu;" id="fileMenu" accesskey="&file.accesskey;">
-+ <menu label="&file.menu;" id="fileMenu" accesskey="&file.accesskey;" insertbefore="menu_edit">
- <menupopup id="fileMenuPopup" onpopupshowing="menus.updateFileMenuitems();">
- <menuitem id="addBuddyMenuItem" label="&addContact;" command="cmd_addbuddy" key="addBuddykey" accesskey="&addContact.accesskey;"/>
- <menuitem id="newTabMenuItem" label="&newtab;" command="cmd_newtab" key="newtabkey" accesskey="&newtab.accesskey;"/>
-diff --git a/im/content/menus.xul.inc b/im/content/menus.xul.inc
---- a/im/content/menus.xul.inc
-+++ b/im/content/menus.xul.inc
-@@ -2,6 +2,8 @@
- # License, v. 2.0. If a copy of the MPL was not distributed with this
- # file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-+# Note instantbird.xul contains a modified copy of this file that
-+# should be kept in sync.
- <commandset id="maincommandset"/>
- <keyset id="mainkeyset"/>
- <menubar id="blistMenubar"/>
diff --git a/projects/instantbird/trac-20207.patch b/projects/instantbird/trac-20207.patch
deleted file mode 100644
index b7720b9..0000000
--- a/projects/instantbird/trac-20207.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From c57457ede9853527f529fd4dd1337ede51f4f312 Mon Sep 17 00:00:00 2001
-From: Vu Quoc Huy <huyvq.c633(a)gmail.com>
-Date: Tue, 11 Oct 2016 10:30:40 +0700
-Subject: [PATCH] Change CFBundleIdentifier to prevent notification sharing on
- macOS
-
-* Resolve ticket #20207
----
- im/app/macbuild/Contents/Info.plist.in | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/im/app/macbuild/Contents/Info.plist.in b/im/app/macbuild/Contents/Info.plist.in
-index dc048c0..78a5305 100644
---- a/im/app/macbuild/Contents/Info.plist.in
-+++ b/im/app/macbuild/Contents/Info.plist.in
-@@ -11,7 +11,7 @@
- <key>CFBundleIconFile</key>
- <string>instantbird.icns</string>
- <key>CFBundleIdentifier</key>
-- <string>org.instantbird</string>
-+ <string>org.mozilla.tor messenger</string>
- <key>CFBundleInfoDictionaryVersion</key>
- <string>6.0</string>
- <key>CFBundleName</key>
---
-2.7.4
-
diff --git a/projects/instantbird/updater-text.patch b/projects/instantbird/updater-text.patch
deleted file mode 100644
index d571511..0000000
--- a/projects/instantbird/updater-text.patch
+++ /dev/null
@@ -1,9 +0,0 @@
-diff --git a/im/locales/en-US/updater/updater.ini b/im/locales/en-US/updater/updater.ini
---- a/im/locales/en-US/updater/updater.ini
-+++ b/im/locales/en-US/updater/updater.ini
-@@ -5,4 +5,4 @@
- ; This file is in the UTF-8 encoding
- [Strings]
- Title=Software Update
--Info=Instantbird is installing your updates and will start in a few moments…
-+Info=Tor Messenger is installing your updates and will start in a few moments…
diff --git a/projects/instantbird/xmpp-default-domain.patch b/projects/instantbird/xmpp-default-domain.patch
deleted file mode 100644
index 38bf703..0000000
--- a/projects/instantbird/xmpp-default-domain.patch
+++ /dev/null
@@ -1,12 +0,0 @@
-diff --git a/chat/protocols/xmpp/xmpp.js b/chat/protocols/xmpp/xmpp.js
---- a/chat/protocols/xmpp/xmpp.js
-+++ b/chat/protocols/xmpp/xmpp.js
-@@ -31,7 +31,7 @@
-
- usernameSplits: [
- {get label() { return _("options.domain"); }, separator: "@",
-- defaultValue: "jabber.org", reverse: true}
-+ defaultValue: "", reverse: true}
- ],
-
- options: {
diff --git a/projects/instantbird/xmpp-gtalk-resource.patch b/projects/instantbird/xmpp-gtalk-resource.patch
deleted file mode 100644
index a09d538..0000000
--- a/projects/instantbird/xmpp-gtalk-resource.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-diff --git a/chat/protocols/gtalk/gtalk.js b/chat/protocols/gtalk/gtalk.js
---- a/chat/protocols/gtalk/gtalk.js
-+++ b/chat/protocols/gtalk/gtalk.js
-@@ -96,7 +96,7 @@
- getAccount: function(aImAccount) { return new GTalkAccount(this, aImAccount); },
- options: {
- resource: {get label() { return _("options.resource"); },
-- get default() { return XMPPDefaultResource; }}
-+ default: "Instantbird"},
- },
- get chatHasTopic() { return true; },
- classID: Components.ID("{38a224c1-6748-49a9-8ab2-efc362b1000d}")
-diff --git a/chat/protocols/xmpp/xmpp.js b/chat/protocols/xmpp/xmpp.js
---- a/chat/protocols/xmpp/xmpp.js
-+++ b/chat/protocols/xmpp/xmpp.js
-@@ -36,7 +36,7 @@
-
- options: {
- resource: {get label() { return _("options.resource"); },
-- get default() { return XMPPDefaultResource; }},
-+ default: "Instantbird"},
- priority: {get label() { return _("options.priority"); }, default: 0},
- connection_security: {
- get label() { return _("options.connectionSecurity"); },
diff --git a/projects/instantbird/xmpp-inband-registration.patch b/projects/instantbird/xmpp-inband-registration.patch
deleted file mode 100644
index c471346..0000000
--- a/projects/instantbird/xmpp-inband-registration.patch
+++ /dev/null
@@ -1,188 +0,0 @@
-diff --git a/chat/locales/en-US/xmpp.properties b/chat/locales/en-US/xmpp.properties
---- a/chat/locales/en-US/xmpp.properties
-+++ b/chat/locales/en-US/xmpp.properties
-@@ -13,6 +13,9 @@
- connection.authenticating=Authenticating
- connection.gettingResource=Getting resource
- connection.downloadingRoster=Downloading contact list
-+connection.registering=Registering new account
-+connection.gettingRegistration=Getting registration form
-+connection.onRegistrationSuccess=Account registered
-
- # LOCALIZATION NOTE (connection.error.*)
- # These will show in the account manager if an error occurs during the
-@@ -33,6 +36,8 @@
- connection.error.authenticationFailure=Authentication failure
- connection.error.notAuthorized=Not authorized (Did you enter the wrong password?)
- connection.error.failedToGetAResource=Failed to get a resource
-+connection.error.noRegistrationSupport=The server does not support in-band registration
-+connection.error.registrationCancel=Registration canceled
-
-
- # LOCALIZATION NOTE (conversation.error.notDelivered):
-diff --git a/chat/protocols/xmpp/xmpp-session.jsm b/chat/protocols/xmpp/xmpp-session.jsm
---- a/chat/protocols/xmpp/xmpp-session.jsm
-+++ b/chat/protocols/xmpp/xmpp-session.jsm
-@@ -11,6 +11,8 @@
- Cu.import("resource:///modules/xmpp-xml.jsm");
- Cu.import("resource:///modules/xmpp-authmechs.jsm");
-
-+const registerWindow = "chrome://instantbird/content/xmppRegister.xul";
-+
- XPCOMUtils.defineLazyGetter(this, "_", () =>
- l10nHelper("chrome://chat/locale/xmpp.properties")
- );
-@@ -68,6 +70,7 @@
- Stanza.node("ping", Stanza.NS.ping)),
- this.cancelDisconnectTimer, this);
- },
-+ nodes: {},
- _lastReceiveTime: 0,
- _lastSendTime: 0,
- checkPingTimer(aJustSentSomething = false) {
-@@ -271,6 +274,69 @@
- this.onXmppStanza = this.stanzaListeners.startAuth;
- this.onXmppStanza(aStanza);
- },
-+ onRegisterResponse: function(aStanza) {
-+ let error = this._account.parseError(aStanza);
-+ if (error) {
-+ this.onError(null, aStanza.getElement(["error"]).innerText);
-+ return;
-+ }
-+ if (aStanza.attributes["type"] == "result") {
-+ this._account.reportConnecting(_("connection.onRegistrationSuccess"));
-+ this._account.prefs.setBoolPref("register", false);
-+ this._account.connect();
-+ }
-+ return;
-+ },
-+ startRegister: function(aStanza) {
-+ // Some servers do not support in-band registration. In that case,
-+ // complain and quit the registration process.
-+ let error = this._account.parseError(aStanza);
-+ if (error) {
-+ this.onError(null, _("connection.error.noRegistrationSupport"));
-+ return;
-+ }
-+
-+ // Clear the existing elements from previous registrations.
-+ for (let elem in this.nodes)
-+ delete this.nodes[elem];
-+
-+ this._account.reportConnecting(_("connection.gettingRegistration"));
-+ let registerStanza = aStanza.getChildrenByNS(Stanza.NS.register)[0];
-+ // If we get registration data, show the form, else quit.
-+ if (registerStanza.getElement(["x"])) {
-+ this.nodes["username"] = this._jid.node;
-+ registerStanza.wrappedJSObject = registerStanza;
-+ let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"]
-+ .getService(Ci.nsIWindowWatcher);
-+ let win = ww.openWindow(null, registerWindow, "",
-+ "centerscreen,chrome,modal,minimizable=no", registerStanza);
-+ } else {
-+ this.onError(null, _("connection.error.noRegistrationSupport"));
-+ return;
-+ }
-+
-+ // If the user cancelled the form, we should stop the registration.
-+ if (this.nodes["cancel"]) {
-+ this.onError(null, _("connection.error.registrationCancel"));
-+ return;
-+ }
-+
-+ let xml = '<?xml version="1.0"?>';
-+ let fieldNodes = [];
-+ for (let key in this.nodes) {
-+ let node = Stanza.node("field", null, {"var": key});
-+ let childNode = Stanza.node("value");
-+ childNode.addText(this.nodes[key]);
-+ node.addChild(childNode);
-+ fieldNodes.push(node);
-+ }
-+ let registerResponse = Stanza.iq("set", null, this._domain,
-+ Stanza.node("query", Stanza.NS.register, null,
-+ Stanza.node("x", Stanza.NS.xdata,
-+ {"type": "submit"}, fieldNodes)));
-+ this.sendStanza(registerResponse);
-+ this.onXmppStanza = this.stanzaListeners.onRegisterResponse;
-+ },
- startTLS: function(aStanza) {
- if (aStanza.localName != "proceed") {
- this._networkError(_("connection.error.failedToStartTLS"));
-@@ -283,6 +349,18 @@
- this.onXmppStanza = this.stanzaListeners.startAuth;
- },
- startAuth: function(aStanza) {
-+ // If the user has requested for a new account, we try to perform
-+ // in-band registration first (if the server supports it) and then
-+ // we authenticate.
-+ if (this._account.getBool("register")) {
-+ this._account.reportConnecting(_("connection.registering"));
-+ let register = Stanza.iq("get", null, null,
-+ Stanza.node("query", Stanza.NS.register));
-+ this.sendStanza(register);
-+ this.onXmppStanza = this.stanzaListeners.startRegister;
-+ return;
-+ }
-+
- if (aStanza.localName != "features") {
- this.ERROR("Unexpected stanza " + aStanza.localName + ", expected 'features'");
- this._networkError(_("connection.error.incorrectResponse"));
-diff --git a/im/content/accountWizard.js b/im/content/accountWizard.js
---- a/im/content/accountWizard.js
-+++ b/im/content/accountWizard.js
-@@ -119,6 +119,12 @@
- return;
- }
-
-+ if (this.proto.id == "prpl-jabber") {
-+ document.getElementById("registerXMPP").hidden = false;
-+ } else {
-+ document.getElementById("registerXMPP").hidden = true;
-+ }
-+
- let bundle = document.getElementById("accountsBundle");
- let usernameInfo;
- let emptyText = this.proto.usernameEmptyText;
-@@ -424,6 +430,8 @@
- acc.alias = this.alias;
- //FIXME: newMailNotification
-
-+ acc.setBool("register", document.getElementById("registerXMPP").checked);
-+
- for (let i = 0; i < this.prefs.length; ++i) {
- let option = this.prefs[i];
- let opt = option.opt;
-diff --git a/im/content/accountWizard.xul b/im/content/accountWizard.xul
---- a/im/content/accountWizard.xul
-+++ b/im/content/accountWizard.xul
-@@ -65,6 +65,7 @@
- <vbox id="userNameBox"/>
- <separator/>
- <description id="duplicateAccount" hidden="true">&accountUsernameDuplicate.label;</description>
-+ <checkbox id="registerXMPP" label="®isterXMPP.label;" hidden="true" />
- </wizardpage>
-
- <wizardpage id="accountpassword" pageid="accountpassword" next="accountadvanced"
-diff --git a/im/content/jar.mn b/im/content/jar.mn
---- a/im/content/jar.mn
-+++ b/im/content/jar.mn
-@@ -61,6 +61,8 @@
- * content/instantbird/viewlog.xul
- content/instantbird/viewlog.js
- content/instantbird/viewlog.css
-+ content/instantbird/xmppRegister.xul
-+ content/instantbird/xmppRegister.js
- #ifdef XP_MACOSX
- * content/instantbird/hiddenWindow.xul
- content/instantbird/menus-mac.xul
-diff --git a/im/locales/en-US/chrome/instantbird/accountWizard.dtd b/im/locales/en-US/chrome/instantbird/accountWizard.dtd
---- a/im/locales/en-US/chrome/instantbird/accountWizard.dtd
-+++ b/im/locales/en-US/chrome/instantbird/accountWizard.dtd
-@@ -31,3 +31,5 @@
- <!ENTITY accountSummaryTitle.label "Summary">
- <!ENTITY accountSummaryInfo.label "A summary of the information you entered is displayed below. Please check it before the account is created.">
- <!ENTITY accountSummary.connectAutomatically.label "Connect this account automatically.">
-+
-+<!ENTITY registerXMPP.label "Create this new account on the server">
diff --git a/projects/instantbird/xmpp-onion-js.patch b/projects/instantbird/xmpp-onion-js.patch
deleted file mode 100644
index 03652ee..0000000
--- a/projects/instantbird/xmpp-onion-js.patch
+++ /dev/null
@@ -1,89 +0,0 @@
-diff --git a/im/content/accountWizard.js b/im/content/accountWizard.js
---- a/im/content/accountWizard.js
-+++ b/im/content/accountWizard.js
-@@ -7,6 +7,14 @@
-
- const PREF_EXTENSIONS_GETMOREPROTOCOLSURL = "extensions.getMoreProtocolsURL";
-
-+// Borrowed and inspired by xmpp-client.
-+const kServerOnions = {
-+ "riseup.net": "4cjw6cwpeaeppfqz.onion",
-+ "jabber.ccc.de": "okj7xc6j2szr2y75.onion",
-+ "jabber.otr.im": "5rgdtlawqkcplz75.onion",
-+ "jabber.calyxinstitute.org": "ijeeynrc6x2uy5ob.onion",
-+}
-+
- var accountWizard = {
- onload: function aw_onload() {
- let topProtoList = document.getElementById("topprotolist");
-@@ -105,6 +113,21 @@
- return textbox;
- },
-
-+ insertOnionAddress: function aw_insertOnionAddress() {
-+ // Currently, we only use onion addresses for XMPP.
-+ if (this.proto.id == "prpl-jabber") {
-+ // If the value of the domain is one for which there exists a
-+ // hidden service, replace the address with the onion address.
-+ this.jabberDomain = document.getElementById("username-split-0");
-+ if (this.jabberDomain.value in kServerOnions) {
-+ this.onionAddress = kServerOnions[this.jabberDomain.value];
-+ }
-+ else {
-+ this.onionAddress = "";
-+ }
-+ }
-+ },
-+
- showUsernamePage: function aw_showUsernamePage() {
- let proto = this.proto.id;
- if ("userNameBoxes" in this && this.userNameProto == proto) {
-@@ -160,11 +183,20 @@
- document.getElementById("accountusername").next = next;
- },
-
-+ setOnionAddress: function aw_setOnionAddress() {
-+ if (this.proto.id == "prpl-jabber") {
-+ document.getElementById("prpl-jabber-server").value = this.onionAddress;
-+ }
-+ },
-+
- showAdvanced: function aw_showAdvanced() {
- // ensure we don't destroy user data if it's not necessary
- let id = this.proto.id;
-- if ("protoSpecOptId" in this && this.protoSpecOptId == id)
-+ if ("protoSpecOptId" in this && this.protoSpecOptId == id) {
-+ // But we should still set the onion address, if it exists.
-+ this.setOnionAddress();
- return;
-+ }
- this.protoSpecOptId = id;
-
- /* FIXME
-@@ -172,6 +204,7 @@
- !this.proto.newMailNotification;
- */
- this.populateProtoSpecificBox();
-+ this.setOnionAddress();
-
- let proxyVisible = this.proto.usePurpleProxy;
- if (proxyVisible) {
-@@ -405,7 +438,17 @@
- for (let i = 0; i < this.prefs.length; ++i) {
- let opt = this.prefs[i];
- let label = bundle.getFormattedString("accountColon", [opt.opt.label]);
-- rows.appendChild(this.createSummaryRow(label, opt.value));
-+ // Only append the label for the "Server" field.
-+ if (this.onionAddress == opt.value) {
-+ let wizardBundle = document.getElementById("topProtocolsBundle");
-+ let onionLabel = wizardBundle.getFormattedString("onionAddress.label",
-+ [this.jabberDomain.value]);
-+ rows.appendChild(this.createSummaryRow(label, opt.value));
-+ rows.appendChild(this.createSummaryRow("", onionLabel));
-+ }
-+ else {
-+ rows.appendChild(this.createSummaryRow(label, opt.value));
-+ }
- }
- },
-
diff --git a/projects/instantbird/xmpp-onion-locale.patch b/projects/instantbird/xmpp-onion-locale.patch
deleted file mode 100644
index 3744907..0000000
--- a/projects/instantbird/xmpp-onion-locale.patch
+++ /dev/null
@@ -1,10 +0,0 @@
-diff --git a/im/locales/en-US/chrome/instantbird/accountWizard.properties b/im/locales/en-US/chrome/instantbird/accountWizard.properties
-index 77dd6dd..8fa4c4f 100644
---- a/im/locales/en-US/chrome/instantbird/accountWizard.properties
-+++ b/im/locales/en-US/chrome/instantbird/accountWizard.properties
-@@ -19,3 +19,5 @@ topProtocol.prpl-twitter.description=Stay up to date with your Twitter timeline
- topProtocol.prpl-aim.description=Chat with your buddies on AOL Instant Messenger
- topProtocol.prpl-msn.description=Microsoft Windows Live Messenger (formerly MSN)
- topProtocol.prpl-yahoo.description=Chat with friends using Yahoo! Messenger
-+
-+onionAddress.label=(Secure connection to %S)
diff --git a/projects/instantbird/xmpp-onion-xul.patch b/projects/instantbird/xmpp-onion-xul.patch
deleted file mode 100644
index 5707435..0000000
--- a/projects/instantbird/xmpp-onion-xul.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-diff --git a/im/content/accountWizard.xul b/im/content/accountWizard.xul
-index 5fa5b82..89f88fe 100644
---- a/im/content/accountWizard.xul
-+++ b/im/content/accountWizard.xul
-@@ -59,7 +59,8 @@
- label="&accountUsernameTitle.label;"
- onpageshow="accountWizard.showUsernamePage();"
- onpagehide="accountWizard.hideUsernamePage();"
-- onpagerewound="return accountWizard.rewindFromUsernamePage();">
-+ onpagerewound="return accountWizard.rewindFromUsernamePage();"
-+ onpageadvanced="return accountWizard.insertOnionAddress();">
- <description id="usernameInfo"/>
- <separator/>
- <vbox id="userNameBox"/>
-@@ -98,7 +99,7 @@
- <checkbox id="newMailNotification"
- label="&accountAdvanced.newMailNotification.label;" hidden="true"/>
-
-- <groupbox id="protoSpecificGroupbox" class="collapsable" closed="true"
-+ <groupbox id="protoSpecificGroupbox" class="collapsable" closed="false"
- onkeypress="accountWizard.onGroupboxKeypress(event)">
- <caption id="protoSpecificCaption"
- onclick="accountWizard.toggleGroupbox('protoSpecificGroupbox')"/>
diff --git a/projects/instantbird/xmppRegister.js b/projects/instantbird/xmppRegister.js
deleted file mode 100644
index 3b43ffb..0000000
--- a/projects/instantbird/xmppRegister.js
+++ /dev/null
@@ -1,142 +0,0 @@
-const { interfaces: Ci, utils: Cu, classes: Cc } = Components;
-
-Cu.import("resource:///modules/imXPCOMUtils.jsm");
-Cu.import("resource:///modules/xmpp-session.jsm");
-
-XPCOMUtils.defineLazyGetter(this, "_", function()
- l10nHelper("chrome://branding/locale/brand.properties")
-);
-
-let registerAccount = {
- createElement: function(aType, aID, aValue) {
- let element = document.createElement(aType);
- if (aID)
- element.setAttribute("id", aID);
- if (aValue)
- element.setAttribute("value", aValue);
- return element;
- },
-
- createRow: function() {
- let row = document.createElement("row");
- row.setAttribute("align", "baseline");
- return row;
- },
-
- onLoad: function() {
- document.documentElement.getButton("accept").disabled = true;
-
- this.rows = document.getElementById("register-rows");
- this.groupbox = document.getElementById("register-groupbox");
-
- this.nodes = XMPPSession.prototype.nodes;
- this.registerStanza = window.arguments[0].wrappedJSObject;
- this.dataStanza = this.registerStanza.getElement(["x"]);
-
- let instructions = this.dataStanza.getElement(["instructions"]);
- if (instructions) {
- let instructionLabel = this.createElement("caption");
- instructionLabel.setAttribute("label", instructions.innerText);
- this.groupbox.appendChild(instructionLabel);
- }
-
- let title = this.dataStanza.getElement(["title"]);
- if (title)
- document.title = title.innerText;
- else
- document.title = _("brandShortName");
-
- for each (let ele in this.dataStanza.getElements(["field"])) {
- let attrib = ele.attributes;
- let fieldType = attrib["type"];
- switch (fieldType) {
-
- case "text-single":
- case "text-private":
- let textRow = this.createRow();
- let textLabel = this.createElement("label", null,
- ele.getElement(["required"]) ?
- attrib["label"] + " *" : attrib["label"]);
-
- let textBox = this.createElement("textbox", attrib["var"],
- ele.getElement(["value"]) ?
- ele.getElement(["value"]).innerText : "");
-
- if (attrib["var"] == "username")
- textBox.setAttribute("value", this.nodes["username"]);
- if (attrib["var"] == "url")
- textBox.setAttribute("readonly", "true");
-
- if (fieldType == "text-private") {
- textBox.setAttribute("type", "password");
- textBox.setAttribute("oninput", "onInput(this);");
- }
-
- textRow.appendChild(textLabel);
- textRow.appendChild(textBox);
- this.rows.appendChild(textRow);
- break;
-
- case "fixed":
- let fixedRow = this.createRow();
- let fixedLabel = this.createElement("label", null, ele.getElement(["value"]).innerText);
- fixedRow.appendChild(fixedLabel);
- this.rows.appendChild(fixedRow);
- break;
- }
- }
-
- // Some forms have an OCR field. In that case, show the OCR image
- // and provide input for the same.
- let ocr = this.dataStanza.getElements(["field"]).find(e => e.attributes["var"] == "ocr");
- if (ocr) {
- let ocrRow = this.createRow();
-
- let ocrImage = this.createElement("image");
- ocrImage.setAttribute("src", "data:image/png;base64," + this.registerStanza.getElement(["data"]).innerText);
-
- // OCR will always be a required entry.
- let ocrLabel = this.createElement("label", null, ocr.attributes["label"] + " *");
- let ocrInput = this.createElement("textbox", ocr.attributes["var"], null);
-
- ocrRow.appendChild(ocrLabel);
- this.rows.appendChild(ocrRow);
-
- let ocrBox = document.createElement("hbox");
- ocrBox.setAttribute("flex", "1");
- let spacer = document.createElement("spacer");
- spacer.setAttribute("flex", "1");
-
- ocrBox.appendChild(ocrImage);
- ocrBox.appendChild(spacer);
- ocrBox.appendChild(ocrInput);
- this.groupbox.appendChild(ocrBox);
- }
- // Set focus on the password field.
- if (document.getElementById("password")) {
- document.getElementById("password").focus();
- }
- },
-
- onSave: function() {
- for each (let elements in this.dataStanza.getElements(["field"])) {
- if (elements.attributes["var"] != undefined) {
- let variable = elements.attributes["var"];
- if (document.getElementById(variable))
- this.nodes[variable] = document.getElementById(variable).value;
- else
- this.nodes[variable] = elements.getElement(["value"]).innerText;
- }
- }
- delete this.nodes["cancel"];
- },
-
- onCancel: function() {
- // The form was cancelled so we quit the registration.
- this.nodes["cancel"] = true;
- },
-};
-
-function onInput(e) {
- document.documentElement.getButton("accept").disabled = !e.value;
-}
diff --git a/projects/instantbird/xmppRegister.xul b/projects/instantbird/xmppRegister.xul
deleted file mode 100644
index e2bd367..0000000
--- a/projects/instantbird/xmppRegister.xul
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" ?>
-<?xml-stylesheet href="chrome://global/skin/" type="text/css" ?>
-
-<dialog
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- id="registerDialog"
- onload="registerAccount.onLoad()"
- buttons="accept,cancel"
- ondialogaccept="return registerAccount.onSave()"
- ondialogcancel="registerAccount.onCancel()">
-
- <script type="application/javascript" src="chrome://instantbird/content/xmppRegister.js" />
-
- <groupbox id="register-groupbox" flex="1">
-
- <grid flex="1">
- <columns>
- <column flex="1" />
- </columns>
-
- <rows id="register-rows" />
-
- </grid>
-
- </groupbox>
-
-</dialog>
1
0

[translation/tor-messenger-ircproperties] Update translations for tor-messenger-ircproperties
by translation@torproject.org 11 Oct '16
by translation@torproject.org 11 Oct '16
11 Oct '16
commit ad4edc4a9aeb86d9f3e96546991afd73652a6d93
Author: Translation commit bot <translation(a)torproject.org>
Date: Tue Oct 11 06:17:51 2016 +0000
Update translations for tor-messenger-ircproperties
---
el/irc.properties | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/el/irc.properties b/el/irc.properties
index a856f24..847dcb6 100644
--- a/el/irc.properties
+++ b/el/irc.properties
@@ -113,7 +113,7 @@ message.quit2=: %S
message.inviteReceived=%1$S σας προσκάλεσε στο %2$S.
# %1$S is the nickname of the invited user, %2$S is the conversation name
# they were invited to.
-message.invited=%1$S was successfully invited to %2$S.
+message.invited=%1$S προσκαλέστηκε με επιτυχία στο %2$S.
# %1$S is the nickname of the invited user, %2$S is the conversation name
# they were invited to but are already in
message.alreadyInChannel=%1$S είναι ήδη στο %2$S.
1
0