commit 1eb04e3a93a72627cea0d3ffdcd1ad3fcd13fdd7 Author: Arlo Breault arlolra@gmail.com Date: Tue Jan 24 14:45:25 2017 -0800
Switch to Tor Browser 6.5
* Use the tor-browser-45.7.0esr-6.5-1-build1 tag on tor-browser
* Use the THUNDERBIRD_45_7_0_RELEASE tag on comm-esr45
* Update tor-browser to 6.5
* Update tor-launcher to 0.2.10.3 --- ChangeLog | 6 +- .../0001-Set-Tor-Messenger-preferences.patch | 20 +- ...0002-Trac-16489-Prevent-account-autologin.patch | 4 +- ...Support-Special-Characters-input-prompt-o.patch | 4 +- ...Better-error-reporting-for-failed-outgoin.patch | 6 +- .../0005-Trac-13312-OTR-over-Twitter-DMs.patch | 4 +- ...-Fix-tab-strip-background-colour-on-OS-X..patch | 4 +- ...-XMPP-createConversation-should-handle-in.patch | 6 +- ...-Set-_userVCard-own-property-when-downloa.patch | 39 - .../0008-XMPP-in-band-registration.patch | 396 + .../instantbird/0009-Remove-search-from-UI.patch | 64 + .../0009-XMPP-in-band-registration.patch | 396 - .../0010-Add-Tor-Messenger-branding.patch | 5134 +++++++++++ .../instantbird/0010-Remove-search-from-UI.patch | 64 - projects/instantbird/0011-Account-picture.patch | 26 + .../0011-Add-Tor-Messenger-branding.patch | 5134 ----------- projects/instantbird/0012-Account-picture.patch | 26 - .../0012-Modify-protocol-defaults.patch | 48 + .../instantbird/0013-Modify-IRC-defaults.patch | 65 + .../0013-Modify-protocol-defaults.patch | 48 - .../instantbird/0014-Modify-IRC-defaults.patch | 65 - projects/instantbird/0014-Modify-themes.patch | 78 + .../instantbird/0015-Modify-XMPP-defaults.patch | 48 + projects/instantbird/0015-Modify-themes.patch | 78 - .../instantbird/0016-Modify-XMPP-defaults.patch | 48 - projects/instantbird/0016-Remove-logging-UI.patch | 43 + projects/instantbird/0017-Cert-override.patch | 64 + projects/instantbird/0017-Remove-logging-UI.patch | 43 - projects/instantbird/0018-Cert-override.patch | 64 - .../0018-Display-all-traffic-over-Tor.patch | 38 + .../0019-Display-all-traffic-over-Tor.patch | 38 - .../instantbird/0019-Trac-17480-Content-sink.patch | 111 + .../0020-SASL-ECDSA-NIST256P-CHALLENGE.patch | 8919 ++++++++++++++++++++ .../instantbird/0020-Trac-17480-Content-sink.patch | 111 - ...-msg-is-not-defined-error-in-irc.js-chang.patch | 29 + .../0021-SASL-ECDSA-NIST256P-CHALLENGE.patch | 8919 -------------------- ...-msg-is-not-defined-error-in-irc.js-chang.patch | 29 - ...Contact-list-entries-should-adapt-their-h.patch | 322 + ...1187281-Only-show-close-button-on-Windows.patch | 25 + ...Contact-list-entries-should-adapt-their-h.patch | 322 - ...1187281-Only-show-close-button-on-Windows.patch | 25 - ...-Remove-old-Yahoo-Messenger-support.-r-al.patch | 2398 ++++++ ...-Remove-old-Yahoo-Messenger-support.-r-al.patch | 2398 ------ ...-Use-built-in-functions-instead-of-an-svg.patch | 57 + ...-Add-a-pref-to-disable-JavaScript-in-brow.patch | 52 + ...-Use-built-in-functions-instead-of-an-svg.patch | 57 - ...-Add-a-pref-to-disable-JavaScript-in-brow.patch | 52 - projects/instantbird/config | 39 +- ...0001-Trac-19910-Prevents-STARTTLS-in-XMPP.patch | 2 +- .../mozilla/0002-Trac-16475-Block-flash-too.patch | 2 +- ...Avoid-the-need-to-download-the-font-Osaka.patch | 4 +- ...Update-OS-X-toolchain-to-work-with-ESR-45.patch | 2 +- projects/mozilla/0005-OSX-package-as-tar.bz2.patch | 2 +- projects/mozilla/0006-Updater-fixups-for-TM.patch | 2 +- ...ing-exceptions-even-w-inPrivateBrowsingMo.patch | 2 +- projects/mozilla/config | 2 +- projects/tor-browser/config | 2 +- ...emove-special-handling-for-Instantbird-Th.patch | 71 - ...-Set-CurProcD-for-Thunderbird-Instantbird.patch | 42 - projects/tor-launcher/build | 2 - projects/tor-launcher/config | 4 +- rbm.conf | 2 +- tools/update-responses/config.yml | 2 +- 63 files changed, 17977 insertions(+), 18132 deletions(-)
diff --git a/ChangeLog b/ChangeLog index a84147b..decc29e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ -Tor Messenger 0.3.0b3 -- +Tor Messenger 0.4.0b1 -- * All Platforms + * Use the tor-browser-45.7.0esr-6.5-1-build1 tag on tor-browser + * Use the THUNDERBIRD_45_7_0_RELEASE tag on comm-esr45 + * Update tor-browser to 6.5 + * Update tor-launcher to 0.2.10.3 * Windows * Fix automatic generation of complete MAR files * Trac 21231: Enable intl-api diff --git a/projects/instantbird/0001-Set-Tor-Messenger-preferences.patch b/projects/instantbird/0001-Set-Tor-Messenger-preferences.patch index 4843fbb..c3d47cf 100644 --- a/projects/instantbird/0001-Set-Tor-Messenger-preferences.patch +++ b/projects/instantbird/0001-Set-Tor-Messenger-preferences.patch @@ -1,14 +1,14 @@ -From 5f249d152ab95c0a71ff80cbb4c6b8d6acca2154 Mon Sep 17 00:00:00 2001 +From 3f6a583ee1ea833dbf46ebc957917993a4736946 Mon Sep 17 00:00:00 2001 From: Sukhbir Singh sukhbir@torproject.org Date: Mon, 10 Oct 2016 19:48:41 -0700 -Subject: [PATCH 01/27] Set Tor Messenger preferences +Subject: [PATCH 01/26] Set Tor Messenger preferences
--- - im/app/profile/all-instantbird.js | 427 ++++++++++++++++++++++++++++++++++++-- - 1 file changed, 405 insertions(+), 22 deletions(-) + im/app/profile/all-instantbird.js | 425 ++++++++++++++++++++++++++++++++++++-- + 1 file changed, 403 insertions(+), 22 deletions(-)
diff --git a/im/app/profile/all-instantbird.js b/im/app/profile/all-instantbird.js -index b7a397017..45a6bec79 100644 +index b7a397017..7b91410f9 100644 --- a/im/app/profile/all-instantbird.js +++ b/im/app/profile/all-instantbird.js @@ -1,3 +1,54 @@ @@ -183,7 +183,7 @@ index b7a397017..45a6bec79 100644
// We have an Error Console menu item by default so let's display chrome errors pref("javascript.options.showInConsole", true); -@@ -300,14 +362,335 @@ pref("browser.tabs.tabClipWidth", 140); +@@ -300,14 +362,333 @@ pref("browser.tabs.tabClipWidth", 140); // 3 at the end of the tabstrip pref("browser.tabs.closeButtons", 1);
@@ -318,8 +318,6 @@ index b7a397017..45a6bec79 100644 +pref("webgl.disable-fail-if-major-performance-caveat", true); +pref("dom.battery.enabled", false); // fingerprinting due to differing OS implementations +pref("dom.network.enabled",false); // fingerprinting due to differing OS implementations -+pref("browser.display.max_font_attempts",10); -+pref("browser.display.max_font_count",10); +pref("gfx.downloadable_fonts.fallback_delay", -1); +pref("general.appname.override", "Netscape"); +pref("general.appversion.override", "5.0 (Windows)"); @@ -355,6 +353,7 @@ index b7a397017..45a6bec79 100644 +// bug 18950 for more details. +pref("browser.reader.detectedFirstArticle", true); +pref("reader.parse-on-load.enabled", false); ++pref("privacy.use_utc_timezone", true); + +// Third party stuff +//pref("network.cookie.cookieBehavior", 1); // TM @@ -496,9 +495,8 @@ index b7a397017..45a6bec79 100644 +pref("media.audio_data.enabled", false); + +// If true, remote JAR files will not be opened, regardless of content type -+// Patch done by Jeff Gibat (iSEC). We bind it to the security slider but allow -+// jar: in default mode. -+pref("network.jar.block-remote-files", false); ++// Patch written by Jeff Gibat (iSEC). ++pref("network.jar.block-remote-files", true); + +// Enable TLS 1.1 and 1.2: +// https://trac.torproject.org/projects/tor/ticket/11253 diff --git a/projects/instantbird/0002-Trac-16489-Prevent-account-autologin.patch b/projects/instantbird/0002-Trac-16489-Prevent-account-autologin.patch index 42676ec..01dec0c 100644 --- a/projects/instantbird/0002-Trac-16489-Prevent-account-autologin.patch +++ b/projects/instantbird/0002-Trac-16489-Prevent-account-autologin.patch @@ -1,7 +1,7 @@ -From 2097122d0d75213f13a2b69c45f4c1e91ea8264d Mon Sep 17 00:00:00 2001 +From 93d819d685fa99d607a71d370c8f45f2e99d5493 Mon Sep 17 00:00:00 2001 From: Arlo Breault arlolra@gmail.com Date: Mon, 16 Nov 2015 20:37:53 -0800 -Subject: [PATCH 02/27] Trac 16489: Prevent account autologin +Subject: [PATCH 02/26] Trac 16489: Prevent account autologin
--- chat/components/src/imAccounts.js | 2 +- 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 index 494672e..a8ecd56 100644 --- 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 @@ -1,7 +1,7 @@ -From 9156c76d9d9632392b2cc6069d5606525b0bf933 Mon Sep 17 00:00:00 2001 +From 2c8933abb0b1eec048c0205cf49729856e8c84e7 Mon Sep 17 00:00:00 2001 From: aleth aleth@instantbird.org Date: Sat, 30 Jan 2016 20:56:38 +0100 -Subject: [PATCH 03/27] Trac 17896: Support "Special Characters" input prompt +Subject: [PATCH 03/26] 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 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 index 4138a9f..882602d 100644 --- 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 @@ -1,7 +1,7 @@ -From 266389c24e1e4eb65f0c40abe414d4b4471992d3 Mon Sep 17 00:00:00 2001 +From 71ced3fd410481505db5506ba0107cdd21438db7 Mon Sep 17 00:00:00 2001 From: Arlo Breault arlolra@gmail.com Date: Tue, 2 Feb 2016 16:04:51 -0800 -Subject: [PATCH 04/27] Trac 17494: Better error reporting for failed outgoing +Subject: [PATCH 04/26] Trac 17494: Better error reporting for failed outgoing messages
* Bug 1245325 - Better error reporting for failed outgoing messages. r=clokep @@ -35,7 +35,7 @@ index 7f824e534..293ab01d4 100644 # 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 67cab7743..0022be35f 100644 +index 7c3fcd7e6..282575938 100644 --- a/chat/protocols/xmpp/xmpp.jsm +++ b/chat/protocols/xmpp/xmpp.jsm @@ -679,11 +679,18 @@ var XMPPConversationPrototype = { diff --git a/projects/instantbird/0005-Trac-13312-OTR-over-Twitter-DMs.patch b/projects/instantbird/0005-Trac-13312-OTR-over-Twitter-DMs.patch index e7c829f..bd3d4b8 100644 --- a/projects/instantbird/0005-Trac-13312-OTR-over-Twitter-DMs.patch +++ b/projects/instantbird/0005-Trac-13312-OTR-over-Twitter-DMs.patch @@ -1,7 +1,7 @@ -From 298868aee8d58055e6e210a922cf55beec70db4f Mon Sep 17 00:00:00 2001 +From 41c6168d9c347a34c67249cdab427736df0c3930 Mon Sep 17 00:00:00 2001 From: Arlo Breault arlolra@gmail.com Date: Tue, 15 Mar 2016 17:40:42 -0700 -Subject: [PATCH 05/27] Trac 13312: OTR over Twitter DMs +Subject: [PATCH 05/26] Trac 13312: OTR over Twitter DMs
--- chat/components/src/imConversations.js | 3 +- 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 index 2391576..c47f16d 100644 --- 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 @@ -1,7 +1,7 @@ -From 6372d7ec1de855dd5ce01c732412e4882651e83b Mon Sep 17 00:00:00 2001 +From c632159066e0cdc81d7ac5b69e4d7fb1aea3922a Mon Sep 17 00:00:00 2001 From: Nihanth Subramanya nhnt11@gmail.com Date: Sun, 9 Oct 2016 21:53:04 -0700 -Subject: [PATCH 06/27] Bug 1218193 - Fix tab strip background colour on OS X. +Subject: [PATCH 06/26] Bug 1218193 - Fix tab strip background colour on OS X. r=aleth
--- 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 index 691159a..a1a6cc9 100644 --- a/projects/instantbird/0007-Bug-1246431-XMPP-createConversation-should-handle-in.patch +++ b/projects/instantbird/0007-Bug-1246431-XMPP-createConversation-should-handle-in.patch @@ -1,7 +1,7 @@ -From 47cb0f9b3ca87aea8dcaf0e578f4fbeab6efb9c9 Mon Sep 17 00:00:00 2001 +From bb331ed68d8150a72ee30734891f02e824c08a6d Mon Sep 17 00:00:00 2001 From: Arlo Breault arlolra@gmail.com Date: Sun, 9 Oct 2016 21:57:07 -0700 -Subject: [PATCH 07/27] Bug 1246431 - XMPP createConversation should handle +Subject: [PATCH 07/26] Bug 1246431 - XMPP createConversation should handle incoming messages from the server properly. r=aleth
--- @@ -9,7 +9,7 @@ Subject: [PATCH 07/27] Bug 1246431 - XMPP createConversation should handle 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/chat/protocols/xmpp/xmpp.jsm b/chat/protocols/xmpp/xmpp.jsm -index 0022be35f..4420a1d17 100644 +index 282575938..71f777009 100644 --- a/chat/protocols/xmpp/xmpp.jsm +++ b/chat/protocols/xmpp/xmpp.jsm @@ -2108,7 +2108,7 @@ var XMPPAccountPrototype = { 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 deleted file mode 100644 index ecdefbe..0000000 --- a/projects/instantbird/0008-Bug-1298574-Set-_userVCard-own-property-when-downloa.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 834f9254f3d0eb39c26c430fcefb6f661f2bc2e9 Mon Sep 17 00:00:00 2001 -From: Arlo Breault arlolra@gmail.com -Date: Sun, 28 Aug 2016 08:57:41 -0700 -Subject: [PATCH 08/27] 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 4420a1d17..71f777009 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.11.0 - diff --git a/projects/instantbird/0008-XMPP-in-band-registration.patch b/projects/instantbird/0008-XMPP-in-band-registration.patch new file mode 100644 index 0000000..c617e2c --- /dev/null +++ b/projects/instantbird/0008-XMPP-in-band-registration.patch @@ -0,0 +1,396 @@ +From 5b90c85e4c5e3d7d49006ee299417d9ceeca62ac Mon Sep 17 00:00:00 2001 +From: Sukhbir Singh sukhbir@torproject.org +Date: Mon, 10 Oct 2016 18:42:25 -0700 +Subject: [PATCH 08/26] 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 293ab01d4..237d20c92 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 24618ee0c..246ec2b7c 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 ed3b8f0f7..7c26d0d6e 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 9eb5352a6..759f42b38 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 98d9a09a9..20ea9dce7 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 000000000..52852f045 +--- /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 000000000..e2bd36750 +--- /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 43d0f19e3..c46fb2f95 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.11.0 + diff --git a/projects/instantbird/0009-Remove-search-from-UI.patch b/projects/instantbird/0009-Remove-search-from-UI.patch new file mode 100644 index 0000000..8165fee --- /dev/null +++ b/projects/instantbird/0009-Remove-search-from-UI.patch @@ -0,0 +1,64 @@ +From beecf3b5d4a6f682eab932640068097a297ae943 Mon Sep 17 00:00:00 2001 +From: Sukhbir Singh sukhbir@torproject.org +Date: Mon, 10 Oct 2016 18:47:48 -0700 +Subject: [PATCH 09/26] 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 5261b793f..f667793be 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 fad67c190..cfe2405ea 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.11.0 + diff --git a/projects/instantbird/0009-XMPP-in-band-registration.patch b/projects/instantbird/0009-XMPP-in-band-registration.patch deleted file mode 100644 index c1a3b5b..0000000 --- a/projects/instantbird/0009-XMPP-in-band-registration.patch +++ /dev/null @@ -1,396 +0,0 @@ -From 8ecb2062a225865364f01b702da30d2578931b9e Mon Sep 17 00:00:00 2001 -From: Sukhbir Singh sukhbir@torproject.org -Date: Mon, 10 Oct 2016 18:42:25 -0700 -Subject: [PATCH 09/27] 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 293ab01d4..237d20c92 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 24618ee0c..246ec2b7c 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 ed3b8f0f7..7c26d0d6e 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 9eb5352a6..759f42b38 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 98d9a09a9..20ea9dce7 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 000000000..52852f045 ---- /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 000000000..e2bd36750 ---- /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 43d0f19e3..c46fb2f95 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.11.0 - diff --git a/projects/instantbird/0010-Add-Tor-Messenger-branding.patch b/projects/instantbird/0010-Add-Tor-Messenger-branding.patch new file mode 100644 index 0000000..3ef898e --- /dev/null +++ b/projects/instantbird/0010-Add-Tor-Messenger-branding.patch @@ -0,0 +1,5134 @@ +From 21890c548091d7f43e89f2df1816c468f2a2cdf5 Mon Sep 17 00:00:00 2001 +From: Sukhbir Singh sukhbir@torproject.org +Date: Mon, 10 Oct 2016 18:56:27 -0700 +Subject: [PATCH 10/26] 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@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 | 80 +++ + 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, 1695 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@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 615e4e6b8..ac61e6134 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 000000000..b4309568e +--- /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 000000000..4683827fa +--- /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 000000000..7e580518b +--- /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;1VaOZlo$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 +T2@aidK4l{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@2x.png b/im/branding/messenger/content/about-logo@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 +zcmZvCWmHt(_xB7#haeKt3P^W%Bdv7DfON|s9YZ52B^}ZY5<|lP(k(HBln6+J#LztR +z{k?hK{O?-#-gEEz?0wEYd#`hLoX?u?ln8JsaRC4Tfr_$%HUI#WLA8HjW1^lwc^@X! +z3mqb-qKl2X0<f*4QQtW3%0>_r9`WA|lw-;ELH(rgR5bL|akKUGw)C(8czb(uIk-AO +zK3KZjaJhNdWgkmW0syZ7Dhjf?J~>CLz8Ta5nH!rH*7^n($;QYCBDq&G*k(0k(Nv$u +zpdlDEJAC}Gp+WPylQW;iW^c<*+7F3|G^aj@!G6J)E1b_DMnXKlUU@Rap%ec_^IWfy +zs$%26O0<`q-LI`>=c{7tLHh1HR5bF@w|DGU4aY@u%V56_CzAU=9wn*~s{k!OT8noY +zcyX1}-;*fKcEvBS_DTF+E$<QP0t%wpJzaJkaBB3%Hu(e|ffyRgT2a*b^2Sx5WsRel +zH%q>k4u=GfWyD&HKuzk+ne@GNEhFBUj}Kc-3qx!*gLg4!xPq7$_64vhxqm4#jcV*t +znpqkw%_{6&&ufI*#4Z<pVZuymEfm7h;n=g3m(vH-C;rFkN)-;2fia<<DF-7~VNE1= +z)78KQ#~K6igbwGreA7T3&`5nYlWHuA#y3Dz5Qo_-l5n@+(gCgx)?7Sd`|^yWD$TZH +zp)*6>m)l%8HrG;El|&c^YIE4O8+}AUByQF_(EW3lb)tg0Tbdllu}1qA!{S^(Z*3Nj +zX@=S>R^ek3z|fY`!lwR(H#Z_iEd-A>pVqva7_MgDHQfKSB}m|m-62aKKnxg@*{Z_V +z*E?pO8OP#6`)%1$ab3|2mn+ff$w$CfEL+}&%cFrmx8I3Y-V(akostF@36O(a7hTva +z*)?y?h4-Xi>9`jvq96{Ydb|@ekK|1|lz;xgritM%C_n8k-_Gf@u-w;EF&-uZ4ACeN +zL<TO$X~t(5806urc`Tasvh0Cn*%!eKU48%F0PCX#xys&c-W#Oevhna8UMc9}Wpz*w +z-R=GIgN3iY)G{On#A<G7zhz^-`jq-e%=7B-3LB7YA5>;_oVcr@R*loaTgbx*AWMo$ +z=lKEou>N+h4j^dRqI98L<TDNFJTd2wzqAy7`$q{4{M_F3U9N}Ky4*n>=%L>=aadW^ +z;aKB#tp<@ddiNjZEgCr5bw(sbzfBk*{g$8p@G3f|>D&C#+0`6jtwgLm3S*7pqfEvX +zn_EWn^u#hZSHD94uWTcbWIfa1<bmrD7Co*4z+ZG*2W#5=?9%ApO<E5Y^^?6@)4;QB +z;5v+q?jE7yks+*gcbh)t2OBQBJlAgy?fzt+^3=H0s1mXIaz-2n3bZ#J;o0u+E^OsP +zG2E~>j64Z6_6r*r!|4ESANP`ek4^J3P&<vK#o$lds&zCy4$yGgb0%T9DKh+5=3VaW +z;1P@)AbJQRiP@EPq7rCvFkVT$@vbVZnFz3OQfAcKHHgO~#(~so6V-{_>t)t`jISza +zr*w2GC{@)m0W}L|Ejub|kZxb#26AX^J{(=@EYf+&|4<s;-PTi}Oy?)tew6L4u3t&U +zTaN;1WIbraJYWgj5%zV5)%V~`_cr%yP1liO&iB^$^4J$xO#>!2#Pllbej!u6$i|(N +zxo|pO_pwZ*Ydtq<{n>>+;l}z+os+Ys{u8tFdd1RrtY<<Ybl`$9eGW`{OxCxAh&amH +zm!j0azt@|jefKK4{@3YuQd>_&kJ7mA7A_JG_mO~QzvY7yRX{xmb~NX_f}`;!k7Z4Z +z$Fm+Mx=4xbEupY%LpkfGyR5wmH|5b9cNG8!bT^LyR@UQ>6~i65`gN_Tsc#TzIi^1W +zqZwH3A4@-gXK1<qG8||vn&=uTEcR`x>FanLtZ2G;u(k|Chf92V<|P3zrSURpcXEu3 +zKk1D`f~Tb7xwZ-rREP*(2FrWHf$swp`032e-Xos~4pH)=Rv8|`c&EQg9e2uFZ&>Gd +z{$1603sS8!C(G6e*MhbN;eS%Vf9kFL_NtnfHO!j8lqUVIDsv>WRRzTY-J@W(+%nQi +zsY4i`3D)0EP=7@;@w%;Gf406iCWRRu{&C=Ak7h5Xg+GK$;M9E4<ufr3R1{_EG^2sW +znehYip9*mFyDNOXV>7$y8+0h5MwnSkb9714hfJuqbJ;V?!We)&YRH;WnAkQK+T^oF +zny4(xZOVyuf^Ery=czvUOu5*z@AP#e+bhcbhGr@tyF&Gn<N68_=x`2!+Sj$qtBUZP +z`epa>fs1R#(<QC{I_OLN%=Ux!TadidQw|0JHGUO_)@vY-ym1k&>E>G4??ImZ_r9mM +zloOTBwklcmRi(JL8V2ej3mofsIlpg~AJ>?<a%GgTo0THb;rNoRd{^={m(r11NdJ|M +z5}PdfH&T{uB=MBrM7){stMR^h40N5B`sZu04P!*l&;xlugteY^^I2G-wJpsA<|ZXZ +zJ*<DT6b%wUDNJyOS>02HLF1=~d(5XYAcB&D7;rb;Dj{XW>c*={W!-h+8cF`uF?r;b +z6X_m)by)0VXfFs9xKeyNA8~G1nn&31v-}GnWALGlx1fO@Mtu=puzwNY<5IFymn_%F +z()Mh;(m-8`7p_VwuH$owSZL&g8#Blf7nW*KKu)mvu4(K;qsU+P)<yeDbvBrur;`iP +ze1@{k$GJEA*D>mGO58+T6@HBHPYaC-t90up^EnpOQ1$x4Lh<QgGZ~@>1~IB0)J-^@ +zx)GMb?7sjO!v;&@bZhUJco?H^*G#dv>!w4Ps7NDFDtMoRRTOGu@@r>vqSY4D4MWR_ +zWcZCcVd~an93V7*q5hs=Vr=Zqby{Tty2MR&W+e&KksN8@!D=e<FZQtXqs^gd$tA?_ +zan+uHn`@@Cx!0ES%9mA{X`CSmsvBjLa_GB5?sJ{I_EC(kHq($gR$jujTVGdB@%q61 +zypSXZQfc-3EJPQ%bi?1-0jj7#t%-+y9G_ylfXl}(^CQbFW}I2Rzd50CnO?>};+$S^ +zq%{vI-DAP3bQ&+JB&&2RD9yhKs?fxp6xHB86FJa3nxR?yj5i6+zswpnea?u+MqAn6 +zHsW^*GB?tq?B!kpMm>{(ybz!ZPaP2bye!<?+&tz;zAfVt{MW#acE0&Fr`p)`rg@;= +zFGh=I`|`@TRs0G!lbSbZG1uE9)q{c;IyA=}_HP%f?Y1cmZ~e~JPSreRW~D^x$&Cpk +zR<jZz?BEUXOA!)Btnk&WwE@%XKQ{|0wJ@inT$UTqIfEp;e>umk@DQ`dTd2Qbet`VG +zDKg9-Je81$gvZ3Ehj)ojFwjQH_FE2PL+HL|6iZy6<DFV?HMK{!s<I-<PNke`BC)^F +zzB;}3a9mF7z<B9cm2lJ{m?*7ds-l*H^FsaVsL9{gDP;=|?d9=IZL>2}$Giw@OE;Y0 +z&hShXmL)FVsSS7KU70-=$?vy1Jy3=>){(qFJx{I=#Ov(B^$OH%?<Euy{<sc0c_bC8 +z<*cQ3*5Q|ES=_hPCGAcKoG{*dPIN;H{=iTxHfcr}*P=I+Z!zus2-n}sJeOQ-o;TgU +zwaL+Ohl5{=l2umryMF$7r9M#nqMCF)r~Gu#Tsq=m!I9-d(g{#(sGa-+?{&?(vKD$z +z=|lbFrx$=R(d!V3AHH^i&MUgqUB?4e0$4``ESFX4BKa_Vzs%SGz+BAKB3nmSzq&7u +zP6J4&$A$KD0oe&Tutwv(_rt+-z^h-dV(rtP+WvK*nrm^Vi1apPEI4YjM<3XRjavNk +zgHp)*O*hdk^jLPk)hh%Eb(03UorclW?**EaRE-eURAL84^=Xsr0sao;_{x;THy~-J +zJ86FM3D;Pz*v=lDGj`yE{lcga;VXFNo!TaNecg3+jXEB_v7UfARWr+~!)-S(<f6`? +zn=l*EOS`0dhFvpZ+tkWgob<cY*05zpfA5w}CHYI&Fedy?U#F@m_lOfoi)}Y2oEc8w +z*7ptD;@{PqG$?^ne+Os1M?9=KcaN8lvo6E7<PRU&62LIUV;7(&H2Qe3(u;gd#(8nS +zY#dtCLUKdvY()N!NMa5@n{yR!ZuG7=H+js!8uY5X(Is_x%~D7JH#t32!%enOa?wvM +zbK!K&FXiyHy<2VL`CfUN*pO<k4MziTTFC?lN(IYkE|8t+#tAyA>76&?3ZR2k6Lupy +zUDDg=4DE3z?M>yAYT~$DlklP5(n@KeepEI+RPL?`HQBLFHwG1FlKl207v>yPN1g8+ +ze_i3S*By9}jsOhB>whz{+%wzwV>z#r{+j3k`K!}|lJc#w0#04)KN;gfuYGimQcd&d +zDF8G_@0+xa7iiF7ElPYiCN&xr(RnEQ2=;crJX*7}OYW4*)xOpqGhhT2yj{Y9iiaIM +z94%U1trA5v2CBKg7-|+mqT!iysdEKXY_lf=iE0v?wGNNFddKBm#7Ugp-mqz_EYgf0 +zy8;f^oVG#y87`Tl3MgKYNfBJLi24&59!a=a!)Sk&q<H9o(aHD5l9}Pbx2EiG(!VKV +z%1mPrLMJ#kFzOejGI{p$!fCqgFw;Z9tcqU`66{*jlE*YrtmH@oX3uvPz<$AZ-Vu$1 +zBC1zM*rj<pWa7bUHSD;LK#N+GnBVKsYnuf#?t-J9VQOm>H#cK8YCw18`{X2X&2&)m +z>F9#Mir?_mG2Peyp02g^b$=}d?|<h5u9PSXfmniw0eFnjdoNsSn6Pp0LT?LHjD1#p +zeuBmgQDmF_$^Zj+NvFR_1&*Ub&WBB!@}>xccV>(&K(~pseb^B2f=~hn8lr-cD%wu3 +zf6XVTs{O&5B@3uYE(I9G3(^W?RQoKTNT@5*mga&kLq&JG&6WlH($^#7=)@?NmSPA{ +zDPd!KWy=7#O~6mHVMzvR>Rf9S-^~wu;cx#?ovO|bdEo4_CH`FFh07(4vJ@8F?qpag +zCEFWPo27CJa8Cm8p~h6OX-c~5^grGx`Wupf?<v|mK3^`-#zMAaTmV4#@?6B2P)Vrj +zsQxW#y0k{+=;>cdDVTe27kEK)_gGisDP6ZO8z$d=+h!{SPPZf{dXFpb0l$V>79Alr +z+j*R$;}Nm9RS|My`Y4tBbZm_GP$Iyyl`5z&t0cRfU#hbk$98v74}Gf!7?(pK>Q*O& +zM&k#-hgw3aWU>^2>O7Zm(u0%pa=300X`y4fj3DsXw;$rrv<r+OBR@;LJ4^z?Qsk}( +zk8507p?7d)UQ11?X(?)?()`(8n))yjF)w^wa*3s{^_=E7MWOo-@y+};s{OHiXgRqk +zLz3@tDAFAY`P{%Rukz9KrFU|P9))B^Kyt1J%>~3umCGWD07~g{WIn>m%tC?B`dqb_ +zmsv(n2B-KfzD`^{-)-zWzsC<kxLkH9T&;(BgPxa0^97n($W}(4#ZyS{yeK55B$RZl +zRx%CAnPv{7rvh|c&G8lV>)*`2*ZKi!FD71seBg1ls_#81PvRN;=}NPVNL*xX>r@m1 +zaEXKo!Iy2^HPUcG3$Jzc`ahP*^Z>qg1S<DdJ1nRodxPP|d;eQ8G`Uwe0!LMNc!q^D +z|IQX{y5Ez$Ko1kRK{sKS1{gLK0NJauN6m^s1^+JbgvPwhG6MbFM+6m5*x1IwLo-7d +zjgu`^kInA;x>ekv9nNItlk_wICrrO59K+QoryrUFbDxEri1t`8<du3q&wi`j=#aJ3 +zfATG3XLGi}M>tb1{~7t~mVlz+&XvK+Vs=45_H_q_Eq@Z=Cu=ip<noZdP2`6>^zm$w +zh&YB%P+q*Zonk8B%o%-O40;9i@EP`^NdS@O;OI5T{SX@p3F!y-kw8XFD1JX{Q;LUD +zq|^kR9{t35a?K`9?HI;_tFD`%H!aqdS#X;A(Oz*y&~uSRJy+^inYBDT>(y{Ro`43q +zZyJs6KUmaUB#PPbM^h_G0nFEA*q4L2iNM!H0~mI!)NPbp*xMOnzdkbe{_uOr%akz@ +zcdM<3lRlvZ^S?i7roISvXhv=D746WXoTr1W^_L1}LvfK1JJ!5ljUt;RzlGm=OdrOe +zveP}2=)G3Nbx<`sd9&a#Qr2#}WWVSDWdQolq;mH{YoAet=B4bM_irD2CxcE{<uyZr +zM*)nksX3JVw8jhLN7c7dy1A>UWwCOO-*@F_xUGi)v$HMEBUyWE4>0!6XgJVZl6`V? +zk$lJH5zXg1ot>Sn{-NJr#^qZ-=GsTW$n4#OpWZde7ZN0o-0!=aLH3M|R&UDr68D!+ +z-?}xD)<MU1!0a=!2CN36!mEW6>t2dluYmQlQb()OhHdK@gIIdI#V-nA#%JT~S*d9k +z)e)q1e2K@R^36hB{klH`E+wX=?4|Yv#S(nWC+psgA9hj2ravm2WjVGUO1$I~iKbI{ +zINZPevkzd42`3KTBh}whMM6~1vkMMZ+mssr`r4l`2==e#*3YX_BG&YNSpJR!A8@=0 +zJ0MA)6e_xhvCf&KiOswFf@-duVk7B0BB*OEvAX<ad!BoCF+{S}wrVaAq-T9djI82% +z#&iwDDVZlAzQ<KV1Cuw}rSyI5M(-^nr86zd@UF1>{ZSUd(NIDnpdJ}J1#A6rgnjD| +zp-N^CtK?*31b7v#t8fCJMQVAE3+h-;W|yF;O>s5M){$}b04Ph#U%9=K{9d~DqylbM +zjP9Ih|CmshQQJ%h&KhUP^~`DG2->k(^e>2xie}jPaprCtMo;_Kk@oW4xJuwHSw!5e +zF=|e!;=O}-;|K^UQC=RL>VRZyeY)7X&EMY9Y2z?+bV2{?9<_EYWL|Gpgve*&`D@@Q +z_WpgniF?Ktyy>%hp9sH$-`Qln2?=KcpH7<XJ3JfzuwuE1d|}S-Os8243Mh%=ouX$a +zDJ)xxI<g!yAd!Wo+KujInQ<J4VtxWSQZ$%^_}h*$AmNGZq+7L@X-c2b;k9B`Wns^3 +zwdJ4LPH2v2;3i7qaCa4`F!s4>-B1WA@H(|0Q3vfgTp-EDzX%w}qJoo%(89L+BMn9T +z9dn#?vtpmWT81$7lzLc;nI}F~VR=6K)?j!SpW<peI1(AgV?y+1bNz^$9?zh)PUg%E +zt!#D%7#x81m20NSD1+YQm|ZsVnRbrQgz3M?_Yc;OadR#Gu8OJ3fWx`g$e_yARjgF& +zQSGCCr!j#kDZ-UC?qBN19)!>`1o=oFr}2Y*ko-Pfzw6sMR1m~mHZQ3pUP5sXXQU8$ +z5E$4i>%}s$oYBc@cKRm&4})C1W_mpfvGE{r7^#qi4u7|-2Z<5m)*~CF#>jt)le??; +zEU`VaT5Q5e=Cjv!7EArjf4={)9<lnRJQ=X4;`D^3XX}lg3Mvz1dFKSM=s&0ujI{`h +zr~2;EqiJnZr|)=tf15hrRiWrd3<&uzXC<%ktb;~K6nDRjb-yh0$t{TRYhC!|fuMNH +zZvLFE^}C{V#vP0AV7BZ&SG7460J;PsSN;dFd>oY%ZPZY&kZb6?TVH8>mRSc$)H8>s +zYN_VU=S@$U7&`qbt*@otp}m5#J>CSv;-wcPo?$6W={WzwH(3ko?N`^1ER~P>s;^;! +zwe8U%pv;>3czo~oq+}_q5TJne3gGw-n-vh7b<h{SHQujD7jzkD?-KQuOv9<8u!MA3 +zTp*8dWHR-7BsDWDML82(vC+@LR_k;{SrI3%XNn3yM^$|sGE1BBm1@%T57Me!GsGp^ +zI8fQFM3l#Wzp9;pDf#-)E0uUCBuH?&uJoWl>k*_JJI1|Qrtfa&q`03g{7zBdo&4J{ +zmJH$(L+}kd?)zTbbpwkGY5q%3RMxC3b}s%YFSYO1LQ7kl<&(c+wy;eIdQTzw4ecu) +z@k7k$e+8DARk_@gxv%}bQ)85ofZ(3c&u}fv7Wvdp7fM%Slaq<$_*hl7Vt*)ajws(1 +z`@iW>eQCEU<yEFI>JrwUD91_b)?Z7T824Cfxx>a4w9@YyH*97N+Tf&&(#v6=eNrG> +zp81vXuPeCwN_UO0gO@%SwQrYISC%7|>8QQL6;wpRwY{B~FSjse7b(3yC~PVS0UVDe +zSbqo9XVJTwdX{^`pKO$V_8deS2}G<?YWd6%K+8oH$t;PD&+xM%MsQDNViIC-5`O0Y +z{ENX7x}GG|9so{y`(Wh~xX-%urL$9!4<Phk{za7i&}*9WuNf*3qoYyf!uYyYcym>p +z_MLymPb!8T`k~L!Syack1~J-$_<Vz$$Q{K(rAN^jl7Z7l(G&mrS04F*5;dE>3}I_Y +z>V%A!#HYlk^HB!+>X!j0xT)=E86l=@yW5)lbt2ujlfN=64EkJSvCUEL)w7@*6Eq)V +z2eS5B<X^p6(JxN21_)*YP*uo@Fqcj7Ry(=<L<9>LAjZnA(aOMV<lAU#&?Y$LJUiXM +zFZdS0O}__bKslkB2cke-o%#YqHbz+ksPiu54oDjyDW&3HfhTJQ$RWUI@yso$EKN2` +zOOx=ZpMRQoA#L4uQ%mkzr0|#C`^IzK(XmSBSn8GQH=p<H=KTn~kM~$)bB!x<G!*{! +z6kCA^Ni~Pbx$;Jt_r=jqJA@LI4vt*vMh{Ml26`pwUQJ?nNaikS$tUhZ7WI+B9EDme +z!=tuc&BYA_P$J&SQr$Ok>F?gQ<FUF>Xv_0f!i|t^{CIYxXM9#kT3)F@3QL$QDPo|i +z!q%iyn|sgRn|3Mtg6v`UNh-ii&(F8eI|&b3Fv%@*wOdHww`Yog)1J~|(MsQU4Q|h| +z3Ja;+-I8E2-SMdOl7N+cIFB;5|L(IHvu)jm8O8}er22hA0-q{+vwi(H`}&jKq2&#m +zUZ53RL2?0RsLUZZ9;FC&g+YixN6^#eJU%jobjWc?TK~>3N86E_2lM69&C6#PE6P&9 +zLkKE_M<mA#i4r9qtnv=ru^^AGgdPSbAJ+CO8Be4hb;P8^G!}Sc?n#awUQyAS_YraL +z9Mhi*fN3c6<h~QF`;VjJeO&BUds#@cFF^WfbpD~a?9M?Ev8VXScvB=M^-45ct#77s +z0O84!6Q;ubUD{|wYNVLHkGO&sT-ldf<C))k(w~=i)ur_2@8$9S>>}QwqHR(%F=+*$ +zJYe#qWQtw(eKdBAE<hpB8K4lFNA#RL6R>zKrnI^D9sYv&BAkfm8z95ee*S39UB!tJ +zRTGLHj-3<8h}Mz`+ZJ1f3UeY*g(9P>!MN+ifNGq>vgduF$|ran;n6}kP!u*9z!DzK +z@xNxwxC9*g=a-<K=LNX@hCj3AW!NS@W-4=qvlu<)UKDkbM<4`VAEwY2)Vm1q;J=I+ +zxoe?XjM+0={)3h#Q?>1<fRh4XaTX!J7I5diXszhL;sE8L2Vqbg<$CZ>uh{BK1M*Jp +zkv4E)C_iudH8}M23V)wSPC@w_cL+1ud!&{vQt8F1^xj?n^`n4I0B+;I?JM&HgG<dk +zB0gLW+#Py#;|IJ3i8^U__EY8puEg6OU_eRKNekMMZz}s}2D*$Eb|ViJC&74899~Ei +zFY>rS5bZjMd+2KW7roXMBOoS#07zTRV-i0Je0&{s-VK_&@Tlexsw4JN29Vs`GP&z! +zZPfwOJ*Dh$Pj%q$&+oHCWQ|~!o>?D$f=J{pSk`5~1ZB|byY1E$>;j|fkXk1bk~t}^ +zM2xFjNm4<W&n;1~n+%QHkl5@!U%>BYV4bXUuBq>m2T+U*+F~@vkg09Muh9S;C_P=* +z#2ARbYkSE&!MFG%QxNQzzO)#fdDrqK@%XNpJ{?X^@E?k~R2264;vgDPCaMpl&bBdm +z#Htq_gDCt^L5=ri*3ROj)Z~$q&0syp^5zHqH0&hO|ETu(Mw%`@x<Y7eyj$?@oMIIz +zP%8eH#I?E*je;Ls=W#60d>w#9Tz^5ANlG+xNQgh&`qiCqGF(U_7Q2gk_WD02YO~bh +zWG~ZpuB!!xU_cWO$0Q=7FDN!=0a+h#udTR;-hvE@MUk1NRE!Ej|4l6i!^7a;r|1!! +z#d*L6@Ml^1?WepWVtR&TBE3KIAZfJ6qV%ng>RDA~(D@8!UW4Sv$Mr@yJBD)+k=#W& +z5snt=>5$au$i;U$k=k^>pEVe3U(VihD3E*LaQrLbJ#ay68@&^Emn0rnfTDVnTg1ze +zy_HS!gn@P~xzZ!B<50?Hxr3hbE*bJ24K#y~U+3X-e4pcb?N`$03dNom0n24=u@7@* +z$Kd5es)UPSG}d~*WKtV@rw+ZxD;>(%gQb;C-)*Q+@wwCg-&NKBRa)tBt=}l0)DBgL +z`-o3@xT2GRPCV}(IWy8;E?raGzF$2y9j}ayg+68+v5+!p^{Q?VT6Y(2nT`+sk>}~C +z*_&*5#1*h=5Jc{<!{hJ|L=Wk%eH<TFc&N(UCK__ygJH|R7KhGDL6DH5>+30`*bXw4 +zYvPF&-ZH|4@syI$6+_qoxRxWFQnM2BTE>=$8fj)xuy^gR)|rUv>tua@u(>Gd`!#Se +z6HY&#?Wo-Hfs5(#-VDBb$6`l(DssxHKDbj$Vym)3lkwo~f49-eJo~onOliYFGzVdD +zN&~nTKMhP!Zz~a->Uwb=GM^m_J@BwMF%SlpAw8U5@({eRrURDl7^M@5b`Z=m3^O|% +z8f9G8!q7Gb;BFyV_<46oc<{mYqUQ#00)Bzy4M|rp&##o;o4^~=Q^}1(jwv;AKoxJu +zCsoYtdv0~Y@60d|*x-RzQVA!NOhqW;BCpr9;m^MD#y7O)k`A$rD)@S`kz7bVSo>Z4 +z-c=y^wcW;SMw5Qv4Tx!Da=bowNjn1;l-t)O<%a2swKlxbwmx+Ku5l@SF;YGQ?CUgq +z#NtE@nDr-V6&r$7iP2%<B61RqpiANmnFFHUfMCRt|LzB_Z-lm5lT#twHfQ(FA{mEV +zJ^ko~0R;Vrnn>r!DP%}g$a}Ja<A5X3f|cugY&=FlDI%n8Q<5hNQrCw*9TN)s%g_iV +zZ;;qkTMfqt05Ea>I}4zg(5XINk`sT?Rp(awtcQv2hv{#W^{(l`1C8>|nZfV!F3Cn4 +zGwwS3P(kP308e_rIYb0WtUfimFsKs-E#;V+kttk3Vy2j#oYaG4Y@Y32mK*@aq%FO^ +zjtwnY=U4bK^UzQE;n`4KNjcNMM+5uuj%V+7a!gSX91fc1wMV%8jJg8#LqxdekDl&^ +zk0!dQUWB_ChqbNySmkY7L$WvOuOtpQQoZ_m=!{^DfUAii(|<PSOr0TXEioLa<WMz; +zNS%L&2j{M(x~l(*>%gITdaRho!K$1W<iS}iN5#bO6_AG?nY?-t<&g2YS?Gb5|4qqV +zxvNFq->WBb=typ&b0?IdqREA>o*JU|+N3B138_XNh~^pCGlSeBR---Mpy*G~hEkSJ +zs(|N_&72{bzwYriDF1aJu8qdgce%B4(oK4P+*dEHK@PD5b`5ursi)YR-Y4I=`WF(y +zT&L5Ec0(Y4?*@D%GwWWBTp&+o&fhHg!zIR3GwyiKfd*DzPilI9jZggmj^_-F@w`Y1 +zR44S}EJY@1aI?+kkDLTp_w}RSa)YGD3OSoe9{E;ZH|A^2o;M6Qn?~J;TZ=Eg;X@TA +zA;Ewk<y*kZA@$6qBw61g=u^7oDjsh~`6VNU#Pm)1K(&D+2E@XRgNa2dyzN56+d|D- +zY8OZSy_5Ft2O(QpGhBYj;v@zv?PpcvzwP{BjT4!EWY<*V(e_L|7Cbs%JSYGvyAW$3 +zmamM+wq(H!wbP=#z{>;{)CQ61)Q8^cnXZ>^N!DX$C9d>Nb<zOOHh8tx|M03Ge^dfD +z-~~i<J^h*bdk>rR6FsZ1(ULJnTnn={L0Az_neFYQkc!7N{QP|SMy=~Qu#`aia+Hzm +z&(&OO@>c(UZ#G70yQN9adt0d*t50tv4xR_1%67R?JTIL5sW!W){n;5k=HvF#1g+L| +zg)KwfU}8LO_ex@8H_YQUUSEW)-hQ%6HiD(vj$_GK9PbR{9C%wJnyMvmtM{+ENSIE| +z5;E~_ItOkQnJLgmCUq{l<-piG6HCucAq@?L*O;YPX^BD`v2gEmS1ni9{^IFT#xxVW +z9hi(o7VkM*hZJt$-miHfb)J)3AHwsFK=jr=tJOk09O%*+FEW4d%Kgx9{C2*;`rqKO +zD~L(c`=Mi3dopMoKC(eQIbp!h1ep+|knm<^I<a6?LCgMf*%N}2t?LQ?OXuL&6YKyz +z8h&F(oAG?LmR%WT;TmAMgx#HkAa(AFx{a=M_fXI7pm+-B=U-I-<7>v_1n0Hs;1uXQ +zu!RB9W5!RHf3Taf(zS8CjjjTE3RR(ACMWkFd+y>(*oelMzScGziVpwPIXaY*vlgwQ +zPFWn5A*=$6JU_b$aZ57!Ik9OiMKchYmh18oar3lRdd)G&Sjs8b!`wI)kc5Q;ZS#dD +zn&)saWy;j5)p}f#k4Ia=Fi+3WD}zgSSt$ZVGZ~PgILkE|hcnaufB<a%;QBd^KJ_YM +zGSpZnq|{$k3>K>dvxN&uBxEM*qz#A~pmBe?TVvZ`Y&g)E1i-#LsYV4H{iyb9`?6+` +z<~*d%Ey_^-mNYss)5(GT943PXmU@gfD)ZIb?Frkl)Lwd`%6wzy0=I5?MA9a##u>R~ +zkL0v%@rd3A<rwkT+!>7j8uLWnbSI9mKs+LC%oS}{@E5(9ZF6Du3QTgluFq|k$GrOd +z8#x9$&*<QB)KX(fT@7a$BU8NNlOH87Q-#3#-oIvz7E-81^FNZ<T6;L#i4G9Gf-^?6 +z;z2|^Thn(1KD<2+4%y>f8%SF5Z_gMX%g0!-yfVRAaaAV_=E-z(VrxKUgS<~Xtgrsm +zCTH}1Nxx&+1^G>?wB#RpYaKXPY^3w1t0F#x77TKjs9E`4oA5|}?*0m|87M|%#TsF3 +zTKRpAI#>zI3`%xw@&_$Fsjnh2%(J&|zzf_Ka<|1mEFRfY_3?##d0slqXLJv>UoWQf +zYOkywG0AOaV8?f8$Sc3U6LldvyhumXVXyyx5X*Y=38c9%^r8M*a~*Yx44|U;PN7x~ +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 000000000..9a3c04eb3 +--- /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 +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 +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 +zcmeHO3v`p!mfq+5DTsP!&GHgJ5m9{L6S<;;;U)BMDTwkM6hT1b3i2$b<t>oD=p#+i +zrfJ#$Ev2Qe{Ar<3YI(oPv-v~0isR_LqqF9&J9nH}y6%h)>b=tWP8v$nrlmj=*R0h5 +z{rCR%KKt8epJzh4WZ}vfqJLbsBzD*fM7`f9yc%!vCyVZ`tW=yXMR6%kr$OoIg6MRX +zI=>=KV;Qhqg}W*WKPB#Tx(Xq?oE~D0&I*O9&J(%zE42R<@e0LRqcCUVQDRQlVMzOH +zi5Xlc6>?S+H@IA<73OkQ5vy>X2UdZWZXk{2M2-dkr3CY35upf3k#etd*LHiB#bmZ* +z+jkTdDO9nGs3cG6S!z$zFMR9uh*Y`f_-S(%uS?tE+=2Ex(ca}yGzCe^XGG-4nyA^a +zrs8c%9+5Lgk(}1(X$7(rIeY!~TsUt7YFD^*`D>*zpSd>Ajy~j4w!%x|XI993eoDCw +zy|a@|;RVrARWhHvxy*{(cH1aR;f1kL2W0-*hSE$xPAgdzUbZ&spv<PE3B-^Agjr`C +zmDz&)424`4uw^K$blC}+MQzDcOhh}OZ<~2qX20ESQK&K<)vzcmA?l3GrskRv#F2(Z +zFl{(5vk7L4l1l8j(*(oHJo(=6F}jyt7&>I=&|$+zj?0r-WU?7FDI^*$b;x1iBZfRa +zpiin+^T42|UmCkjreqU3os5X^i_MXx@E0HNXVpr520k}B2hGjGycNx9i(Td;2KRMn +z`M?*#vq7Dk4pS0QA-L_4Hkl27IA6>AJv$cSv|?dQB$!I4XUR<WaG{ppKO{U$re!82 +z0h7c9hvin8kA1RFv6emfGAwDLO+4CAjulP%muuNm;hE@mS-KLBGQd0^>hpaREgSes +zrc9fF7z~)lcxFI<wo=RbkIInQq+%mx1uUY?Z!=_iYOj{v4+|y0;DW(vR9Mk?i%ie# +zLz`D1%z?#eAT-zl?WJlhdnDW}vxpr=g*!;#3!uKz?|_z`gTofUPHIFL=OnXCPt<5x +zpD_>?19yq=v>n>WS}i?^=Txt^K#kCztktr<V<D8GIaL5nfO7vqEe*r70J@;tXp(8v +zAuSCCmV4cC4Zs%x4g{DbKo`6>0UQeOL4Y}Ff**k?3Fz}c2LR0zu7cj=0|%KfxaD47 +z0q^p`&*C{f9lj!gsp(AtMgUx5R3w+TY_wRw$n{~wML9XvE1Xk&=x_v%C<NRnU{?03 +z5#Ff66Y!o7CX|?*@LwtLkF;!nsDm+GX@c4I$TZ+6<^!Wq?dc-7GMJ8IQmhb`1DGqL +zQT`MWO3W3uD=HN@hHH=*#kWkDDwwUC1c;&SI|S1qG6#h4rV3c*r@&IBWsi==j9CYR +zD-rWV1e%l#%N~sT%b0%iM3R`n<igUij^7HCOUwH{F#@xB8m2rZei_zfYD5w&<yxul +zqc4oZ#GkaIX~AF-8zK^6%Fy!u1NvCBntqQwGd$c5j~ugt_2z;{Qe=YHqxWEWoNm~& +zPd@taLj(Hvf9Rn>Pdq(z_~>min+#v7f_Ec!kBo`&UT+#)A+tAjiiJ;3;5pOde7H+y +zi%Ttvu?a6(Z1CYunMZCETSk@GI&6v*|Ei3{XmGjAW;?JCIgNxpZ`YEc0>r)-wE?>l +zRism{!qyM604$N&lKf0~n#h5PzkHAhV3Eut-p$DpyVm~gKo>q{1X?JwS-CdFj6UWo +zeCsRsr+7h%&O&nw?NX#&Z$H;JsTs_m-HKGWRQF)K4-zyPM0?7VFyp*YkM~7HiWXUB +zB72w8tK6FQ;i^S*roK8p0sHoAGbUqQM`M&+HCC!ssMN4K4y#9iVk~TQ!l#J=wGowG +z*Hh8NWk;Gf0NR;DIG4PQw~ABA(X1v4Rh$mj?FrbOcR<g<9<Mledt32nMKL(@5fi6G +zX*{tKXJM0Jnc^zII9gHG6k<DFI{}+yDPqQ~@Its_a4IY$ITcXCk|s+NXU-g3Ok&?q +zDv)Fq4yTPtvL<5ktog5(QwnfrMLvb?_a4b+rPoGTo;Y>Z+__UGVx1mO^4iPjK8Lfy +zg`naHS6r?NXZ)10`;l}a_`burEz-S893D5j419i*%R(b%QP>5K>h`!3)LtG4Zv4G; +z<tvgJfjLy}Q7?Z=>}-7zM337;yixTiD!WvNyF$Z0m3iE!h&%^X!cF0*%G~Z+6zn8~ +zhH40BAe^m&!v&SjR*(m7<;2_|Lc>z}1bPv4ccFT(yYATG+Uot))rStBI9sIBW!w+k +zd1}v#hm{@Xq>VAD`kt|yldT1NPXOIXRKHEtoOam_F*$n8>g2rr7aS^ia6NG6sFJ(J +zvAIAm#UvFT&js-|%29cZeM709$L&06SIM1=lx!+LUmov*n{kiZrcxaS%#)?^(~dP& +zdj4Tay%kBG$J}#URemOK^#MKKP<YX*(iL10RDQ8w^+7$`v==}lZU`!?i94!i=_fN) +z+z&2isO&=a2|Zg=nyH#_*1Ih#I~I3Z&&=m6$P*U?4-n_-GkUi9Fc3Eu`6WCH&+FOR +zYKw|(;<y>b%gxu{vwYDzbLY&OJ!k&AOQQ4iEVja|QUh)WFxwpZun!i`njA4ARi_y< +zamIpZhn~e$m_UII=n5S3a`e)wcU~WzrQ?xrF3mynYO}f(oq|t^UC$R!8R>v&?y77M +zA2zAjA}^a%b|}`SXYY>B*YPnkqakj-U{Y~2K(7p0dbTL4P{&8l`XEbB*(Nms1C40e +zRy~WJR-$9!?*ZSNuF@s!-u3A!I}($LHsi{5Y}yBqHeEC#KiE9*Ndqu@grZ~PS7hp` +z*oc}p8gSKc!{-2yH!5{(+|mp^TYmvaJ&u(Iw6bLAY5HCr8?yvLdAbT14cOV$7Cp_} +zhZZX!Bwxp=1lodX9YtACo#RH8yK&B`ly26u<)aVi=uOy50DEvZKvmb9^)$Ig$3`xL +zU_}S$EVz$BSyHQ`sd#P{pa<YyDAQ`;x)MS?01>ww@|c4<nuq7<H1tS-MJ6;qq@yVS +zkERJO(S9e;cYuxuS_{<e4N?qr4$yF*N05=|94P>21C#-t6rgCo-v>@Kp=b5puvY-r +z`QSJ3+~Vz+NMUn&Q-no8ZK4MPv<eW(Mj>o@vumXfT`1z7F{%=72BO0C>x^(m6(++y +z&0AnGin#*)NXO)8z<ZH^+aM;(@t8E=sN~q?DD@W6iw5t-K*f~@mIIh9%TW8ubhT+Z +zu(~y=z^ip^;!2EFlG|$#b9J}CF|s4y!d!?w0?vzQ0t<7erNC6BW3Mj5d?^s~6icIS +zeKOEJIyT`w%*#{+qWVO_nyZQ33WH0>M@@boQ+e|lSlmg31-mCE36^r5G-}dZG3VDG +z2X8&ridd?pF^Mo{pex}SI?d<_GZ%hfhszPOiiPGzYgcT7*P-`Ree|MvZ%&;Q6&XHu +zTx8_L$<t>qT)IuqK7=pTdG7@(JFq6+>rGQD^epidEbdgXi5%Gy=fhokX1!=pjRHMy +zHTY1cp2rqpGod<c7*}kn<XopmRy4I7)jF05cRMz#EH8xZZgnA2BRB2@D$Ac>fnTwn +z$7G$fs<;whwq;H*0V@J#I)aVNgG+&XyUOcRCK`bkBDJG7)l558UjE*g6fZ;$8+N!| +zs&qPj#;7D8B--Liph|U?cgDs0z)UYlm&(+zJqhnl8ijb|5b0!6h1#pWrmD!1k-T}` +z>I7`T8w?*}B|FfuFK{1F>4M>09M+7$%qngJJ{dF6a~4~&=LTS>lRje#jK^^m@Ttk5 +z$4$VeCBo?5MyGsgoH*Go>}b{vFki{1Y~QrP`2%ilQ!jbXf1E}s#E+|<eBdUe8<!YU +zh$%ytEyORXo^62B^wRqHgczLuBJ^cD@j8ziXH8L(UK8_Sl5suGe^}g?^Th#ZReKfb +z_3Jh#q@-_J;XV7kwleDJcGr8{s_Hg)AbLFYB?be|eorE%;&)^aUJW?=Rd>UkpZzw{ +zgh^bZ*(zx?8ZK%6NRp(HG&vIEVV@DxXm-IWNe#rpc)3@+K&*#mpHxST^BRdX$B4oX +zOH9KL(MhN^bOt~7p(#HHp^~VFD&dV0za*8RCI6jNOr$ABd>$u$6iY>vFM*nK$;6q& +z3(yK@d)N+XyHK}F#Pi4@?S`}+VeFDqz&R4$+u>&=fE)z0N!2`C%7&CB)pDDZMK<X$ +z&ysNU)MQF0cqXD|P^NT>TP56Zq1W*YiNbISYcizs+zcArzr!-53)})3OADA=$URcL +zvIjCwT&Y3$YOp2X`8#fswvtKu1W(f7O$VM=@DInN^r^tYut90krO$Xe?0DM)$s~#A +zKYI~uggw%w&#%jPehxeKP3a5B21=KH?|c3MPqA4`f8a)xs#(&Y3&4aCJpTeC1f%q& +zSAeMr@wRIjK+_z+7b;zXfJRMx*ZD=vrc6vtS#o3?)|7oyZ_qD}H*QV6g(Rx-Dbm4( +zAk2)qm{ALh^f7vcTZKkc%#4a<NSE+T#&~$VPb(^ImazL_Brqx(TzxQVLN-!X(@1I3 +zDI4R6q0f-SpxLEk7)m4vS<F`H5JuZXJEV^U%*~ioRl+;Vt6)k&6*6vSnnFyQEGdIZ +zB*i;1GRY|-6eF~is!(1o<zuw7FrhP%7d9Ks2}tP@HX1zBKx?N{kWvsZ*DEDU*jRuh +zN!U>EjE7GiiNvTBYMita6Owo$?Ut;(5FHm&4C{{POBPNVd_dMiOu<azlEk-3M$Q;7 +z@s5aKz+%dgl7VTQlnS>3;$adh6fdAXv=tDRm?loTi*pUKmo#BD(BrWzHQytO0S-Ti +zC^y?MzM$BbS1cnMdlz-Tx+~CKf$j=)SD?EB-4*DrK&LA3>*rrv5|@(gD0dyMb{05H +zDQjkrdbmfYn%<ccdvr#^zR&)*G0^MUpU&pK|MER|M$kd)UXf|1{}PDU5BvGE;&&hF +zAj<8T*s!%nuKMwGsC;Id@~hh;3fSry!xtUW1u|aUKkx2<!EO~CxZ&eK@jHQin-`Av +zQg`+mR`}OWFtzLQdGwtWfxmvH-N>Cae4Wz&HY>p2{<5<q9r|50-FG_~M5rA`y%ppC +z7<%1m215?s3c*c%|Ml%#nu%d+f4phPTXZ;d3!BoAt}FeGEdR2olO+gCxT7U^gR!-A +z@WIZ^g5F14x9c+fKf`aHz;C|nGP<^b{<`*N3C#Y!ZL6+CiaK728@rM#V5}n@ZOCf_ +zHtAaMbo(cBeAhCy6Rqy=+L;6??KJ3W_}sk#6IjsIJnhEYgAYO5yheBVmfJ3WBR)cI +z{d(l<_T9VOa&1m)`nx{qa*~b$UVXk*0?8eD2f@}5=9j?GpMt>AVaN?F`8B~fa66=L +z{Nb4v39RYZHz?M+8~pc%a_%>GW<qlU>zlDq3g@o#-}8%fzp?Rp0e*?m7ll6CQ~>t- +zP*%Mq*HCW)V_QNYmGQrpc-ceB*^=zf;v8iE))ES>JQDoRgqG5eO`O9^{E*NpC&9lf +zw3L2qS8)ou{g4nVPZRqt#FTz?Z_s^ydZ?Av^mM2x{rD{OvY#GmrGQ3<n$nNYNn`x< +zP%C@sH=(BV<13>_{q#^P`J@dsr5|51_3+a}t*jsl@&_&*_vm$^+x>LC<G`J?4kW7V +zq-!wTzQIS5q59M#Q2zUH{x1w<2oZ)~Iiz7B;tE9b1o$=o9mo<A>|@Xq9SR9oAd)p+ +z{!M{Qp}>CX=jDGP6kLHg3cd71ztH=?zYX^Brv*wb_}DHVJw0_T_+)Jvn!AtRKWS?X +zK7udtUVlvuK3f}xuUdQz&+6NlgAH68f4%eK86NT(fM1Jh`MMbF{<eyLrA76TM~@J{ +z3H-0eT6Ug7{U+q6asKpVXjPsdtBYFE)2Sd6`iK9pHT~T`_&WquySAz|Jw*kT&_DRK +z<!$IG)!!wU+K=<v(ueRPps!yEK>zoD3ucd7#&!q%62!EYF2R%?Jp=Tf$QDe_8?pa= +zT0nN9f4bolM9JCSw}2i9B58BzFQeM&Jki_DPC*mCS=+%cTI2_f)))9khqm3$!|+vb +z`M<XZTy)JDJr-2@KO27C%oJEy)DHi(Gpn9jP<v-zMLIXPM_|$xXjveBkPq<s^nR!E +zcJD^tZh5=~O?x8yk2d@uZ~0BByQ0!B-}?RZkD2&vrxULst>{~k`y%w4V{hpEDRI@k +zx_2k2y)LU-^8Z}t*K_|Ezmhjqe(`fl_W<&>Z_g(_>EEtnZGUr+pX;JqmOXH@yI)*j +z+;j0y0mkE}Z$7WxJUs9T6F8PYHNI~&cZ&Q*n6QUN&Y1b$qL{UDYnRTS5%CYYr#sl- +zZZvBv>Ac;)Vi?rc6cS`(BYJ+j-;nKs43k#=g5+J0e|L!P3UpVXy8_)6=&nF_1^)k4 +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 000000000..929e7c998 +--- /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@2x.png (content/about-logo@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 000000000..4dc69f244 +--- /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 000000000..c09000fdb +--- /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 000000000..4fb707f30 +--- /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 000000000..e59008d87 +--- /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 000000000..bd8ad850b +--- /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 000000000..3434739f6 +--- /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 000000000..76e799c60 +--- /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 +zcmeI42Uru!_P`hHA{|0+0#Ze)VxdY)Na!FPX;MW&6cm*!DxxSL(kv(-h=2$ppr{C9 +z@6UeKzls%6FFvIxSoWQ;umpkJ<=y-L-g{p%-(i{To@{pJmosx_=1fd!j{=b1G!u@> +z@RtRDv*C{e5rrdy6vFif+}L052{@qa^gmt$Y=-~i0O9f34A~6(YM`sD>&cTRmo8m8 +zdGcgMMMYUzSxHF=93c;9;QZ64PeF%Zef|9Tv!kQy&71cRA3pEw{6g?uEUWg{?69Mw +z<L1qq04gIR!`Ih${`~oxnwoNQav~xke0+RxguJGv)?5P%Ds@44_^R00%?SyaDJg}C +ziTh$>Gs40)dwa**+C>|gglOq_D=0aOic^F|$wH!560-L4Y94|j<ff(@EDMKV!T()` +zA3uJqudh!_OS7}H15jLCT+^maGcYh9lgZA`&c42WKH)2^f;Q{;@09aDBs|qlQqfU; +zUa+oZ^gO5a7Jl1l5qVB4%iPx2`fNQDkaZ<&-<_z^r?J&<*Vg|t{`6;DjNP}MJb9U5 +zQCL=O^bEVZyU(9LpOTWIqoc#k&8?xK0T?49B9<;)8nJYlOVoC==n|didX44haFNvt +z2v4oubGs|^dS}Yzj-+$#>ly|?;lze!jJ&oVJ=(;wa0nKBlnkFed$xc7erPkn@Mg`L +z6&xJAxHp9_UgEekO?TOe>CtD0iiCDZSn`pA`(Jir7%z2fV!#-8{M|3+hr=}S%Pc89 +zMX)F=t2P>j*REZQi;IJfPF-CcdcV-#6cQTd7?G?SbxeI((?~+nSsId9a`5q23}XgZ +zV=u<v8a~G!ePy$}ARw~=NaE=5jCs)RJ$bb(3x{CA2{UYJYV!8>hQ^ahr3UsV`;hh8 +z5ml;@jm$-8W=z1EeTScQ1IGOOUv}N<0*u=(b*w)6%+PBK4~a~Yb#h54Us2hN)59`W +z;d$G$DhL*ZWz~o=Y-ngOGc)7o=kN7bzy^JNd;<(acPTG9O+<wBS9wQg)V%5ejKz=o +zFs`qCq;DH1sp7f3;-!1y32s44^PtQnMR(%sKj9>)kwqJ~9b{QJ1Pe}p;l+y=O-xKA +zB_&;5T|Ik~i%+mtXvwt2rwEGBoYk)3DJS3dRKM&7j0YZmNvgS{X|h;tUihYl4~b{n +z0b1zZ+kB$b85S`?IcL|LY{M|xt|(i(v4CJvSXS-N7(ROR$ji%1P*4yo5Ew$Dcr8;7 +zJ*p6Pg189H`^_ad>CA_3fU&B%E4k{jl8%p&({I@~I(A&^+<LKNV-p=C7^IAbpQNhS +z!qmFeb?@Pf<Lb(oHG5bV4#9#mW%%jSr*-SrVSS(zJvq<w*(e`!Tt2jJR3dD&-qA1N +z;-~NREnUfnPRl4cxkhG#HRj#>vhyEZ=~o9Zt~t@BMOiB(W#^uBbXD!!1qrp0F<AtQ +z!m?^i8J3rq^YZc<8ymw25YkNVEpoxfaFJb9&9Avc%A*)RgJqzB#atXPR5$}_Jj#ox +zZmTbT=twH85tp@zPOCinqWjR(uYhsi-L9NojL8=|HuPE}n4e|nULIkx)7nz!_#>f9 +z(^wV`!Ge#>@cHxS=H}+g%F2}9q`M$qI<T5i1ZFH&pC8LBVNWt%FB?<?mt+>zD2AU@ +zi#mhJ)Zki@$p%4rcXhK^n%8d|c9)1sQqs!LHNO8=*V04B_~dI5hVf?S_N$$Y7(J3s +z@sKFmlvTb#n+X<$Wz|MzxOeYf2?+@p&RbYm=sK>D3OLFrLM9t!bwk02Tvhu{o0h<@ +z;3ef*0)~fKpmJE9nCS))RbSfj5@;S>*40QW*h$FHN-y2N-tpt?hwkIgKbJrFkbk`; +zyQz8W@ki?`?yWj-V`=W?pp0`q$@Q)qjyuO!8F-{39D3gVi7X3;V8KUV`10jTeSLjX +zQ&aFrwQ1oJew7k_M{pt8<nT#4#2#(Iyhk{CZ*Alex0m-Rlk+$rrWYxt;qSij7(Pny +z+;W;nz)VESMpD5^Si)M6WG*UUE+%O%E^R3xV<9PPAth%ar$|;(qbaL{Sd&C&%E%c; +zMW<{^%B!opNU$g@t2P2dm{60Ek#To-*R)(H=2I@}a~KzrYay2i4Tb_ZK*+4F`(Wyy +z%`0RvO)oGu??UDcx|_1P=5=_%jb(=(gLi@}uR8XgN6<`Pf6m;&Y2Lhfwzjq|E-v5z +zTUl96o;(>=uUHn#s0uzD!=9cV@IhfvZ(-{$>Ty8CyPQ#`NV_`3RrYdwA5--*s_bDz +z;Vn(87->bvtdsXDn(4#8+&f(`Xs`%Ko5XD*r{zD>KAs%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 000000000..f223f061e +--- /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 25070608b..a065c8e88 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 000000000..e265f239c +--- /dev/null ++++ b/im/content/aboutDialog.js +@@ -0,0 +1,80 @@ ++/* 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 " + ++ version + ")"; ++ } ++#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 aa3b80ec9..ba924b9ad 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_default_footer&ref=firefox_about&utm_campaign=firefox_about&tm_source=firefox&tm_medium=referral&utm_content=20140929_FireFoxAbout">&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 000000000..e4315b04a +--- /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 20ea9dce7..b3d9e492f 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 ecd8d9d24..187cf5c3e 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_default_footer&ref=firefox_about&utm_campaign=firefox_about&utm_source=firefox&utm_medium=referral&utm_content=20140929_FireFoxAbout. --> ++<!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 15ec569c1..4a2d35d8a 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.11.0 + diff --git a/projects/instantbird/0010-Remove-search-from-UI.patch b/projects/instantbird/0010-Remove-search-from-UI.patch deleted file mode 100644 index dd777d6..0000000 --- a/projects/instantbird/0010-Remove-search-from-UI.patch +++ /dev/null @@ -1,64 +0,0 @@ -From bf059fabc88ff728d65d226fb6cb158e0d8e3759 Mon Sep 17 00:00:00 2001 -From: Sukhbir Singh sukhbir@torproject.org -Date: Mon, 10 Oct 2016 18:47:48 -0700 -Subject: [PATCH 10/27] 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 5261b793f..f667793be 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 fad67c190..cfe2405ea 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.11.0 - diff --git a/projects/instantbird/0011-Account-picture.patch b/projects/instantbird/0011-Account-picture.patch new file mode 100644 index 0000000..f89bd00 --- /dev/null +++ b/projects/instantbird/0011-Account-picture.patch @@ -0,0 +1,26 @@ +From 25cc9f7781966e98788b6b5cd04e51cbdd03c962 Mon Sep 17 00:00:00 2001 +From: Sukhbir Singh sukhbir@torproject.org +Date: Mon, 10 Oct 2016 19:24:09 -0700 +Subject: [PATCH 11/26] 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 b90fddadb..f29a48b99 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.11.0 + diff --git a/projects/instantbird/0011-Add-Tor-Messenger-branding.patch b/projects/instantbird/0011-Add-Tor-Messenger-branding.patch deleted file mode 100644 index bc2056e..0000000 --- a/projects/instantbird/0011-Add-Tor-Messenger-branding.patch +++ /dev/null @@ -1,5134 +0,0 @@ -From 72f56373a20dd93e1976dd953e9a9c77076b7275 Mon Sep 17 00:00:00 2001 -From: Sukhbir Singh sukhbir@torproject.org -Date: Mon, 10 Oct 2016 18:56:27 -0700 -Subject: [PATCH 11/27] 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@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 | 80 +++ - 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, 1695 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@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 615e4e6b8..ac61e6134 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 000000000..b4309568e ---- /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 000000000..4683827fa ---- /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 000000000..7e580518b ---- /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;1VaOZlo$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 -T2@aidK4l{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@2x.png b/im/branding/messenger/content/about-logo@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 000000000..9a3c04eb3 ---- /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 -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 -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 000000000..929e7c998 ---- /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@2x.png (content/about-logo@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 000000000..4dc69f244 ---- /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 000000000..c09000fdb ---- /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 000000000..4fb707f30 ---- /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 000000000..e59008d87 ---- /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 000000000..bd8ad850b ---- /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 -zcmXtA1yCH%(>>hX-QAs_!QDN$bHRhVLxAA!!QI_0aKSCOySw{$zkk(tRdZW=ceUFy -z)6@O7=e>(mRhB_PBt!%N04Q>@lIq}N;C~Gs7W_UaVmbysK)Z;`X~KhFzVH@5!RH80 -zvU)B60L;;U4Pus-Xczn;fvc3RtA?YMtB2_iOMr)m2P@FQ*2Ub^$&%IahjrG45Fr3S -z4v>=+)AY<f%kj!K(8_r1J>1ZLoi&_))$X>qJPS1mh8~Cw{3(fHp@BVwfj3PsE;z|w -zNJYN&mwys@HyH6}8Ts!9DR&A4Ie59hqyop9iAJ+N9&Xi-8@C_Ml@*npm96oBp4#4z -zY!$7|?u%Q&DX&SF+*@Lb;yuTwPq<!;0u#U_aiGh~w(EJf|L@-IKW3fi5A@jr@Q0Gy -z#9J0$l`eTdr2`)^LeXyn=K@)`Xnw=71NN{r-Ad70_zj36;-HuS9+MYAcg=ZFxvxYJ -z8+7R6LWl;4^v6o!=w{Ic^k~>PIPZ$^7*ONaKhd!Uazjsp90AS869QL+SJuq=y&rlE -z_h){eR#07!=;CWAzSSiq;aZj281T@Z=go_{o$f3Nvd|QNcuVJ=n+pmG7E#GWvg6e= -z+YgDv`IVlkP+Mv91z`S|dJuoGpa!JV?f0cWet^x;ho|U)T|;piMB#H<woEg{hYdGH -zj~?<os|P*3Uk0c!rf_O$y=%$IjV!LLtaKD7OTR$oac?<bF}ji?ysBTF^9yMT2h%_Q -zR&?##blM>geS&oIFf=3qh~zmg`DaZGS7=qX-A)Q-@Hyt1;Scl3#F6@qUOp~PxFB^_ -zVQxbB!)OBF>i&IZn=z1O|GL_Cg!Y^QUxfS0cz%9<&Fe6SKS$Zf?|!}ul$w@y8{_C3 -zqQKe?J;$x0jDjlkxW;@<2eGM0c0<m-O0z$O#F=TD`1Cmdk1gI7l+jn^nt=)paO`-R -z%~K{vl$^CBe_w_<gLwdS2GKHD-jE1Q;q<9M1qHU9x2)E!o{wj6MNDMz&24VRfp$lH -zHo%sb!N0V%9P7C4bDRJQ#MjOfZWa>U`z@|NsUbqqU4j~e8Uu&E#-NLXja+l!<IO@* -znp4%{dCicewz0LPN|41?+QAJ+-vQKNc#?V=$uA3ySa)K3_U->**nGe6xPE;{Mn(N` -zQeJv<kmY!DoA;TW<<J2fzwOm_i6;;?Ar7y7i0+4b`w&f8I(MLuywjDv`h*7G8Dfj7 -zuf0#Nq9V0(-9d;Htvyftr|F>_!}0NPes_0HPft(zn)=Wz<y;Wc+*BP|G_q|VU2$@~ -z(9|=<7GFih_sy4u*0QQ93n!;|S!!_!38+Tvse@(fJj?yj6!0im|5LIx&q|*G@?gcy -z*KYN0`c6<;eolq-Z&i$rjtYzaT+)1lxzbrfLKj~OiVmy{iavAiEG#SgxwB)|Wpr7# -zEAugF!#!GK*eP4APPcOn8z>V57noL*T!Ox%xW&-tbz0rp;QM@2b;VU&Tpad#(HS>8 -ztA5dbNQx~r@&K<WVXgHfO&kIHB|CF0iEi`H7+dc^ZNR%Nw$!qLp58Np(i|!uA0J(b -zcyO-(l`1@k4!kqlbO~_fQb9q1&DPG&m07PLw4<Y=Yd|HB@9fiw-?tzXEmi57fjI^p -zS9}fa4Z+F(fGcl==}ne8xPYG7pe>$CCiV*K?g98fnqa7leOK=jFRz(Wh<;#c&T#u- -zZZt5HuDP`}KxXltvX3_f?!9sbApSEc(2+6f2ap{fduV6~8yB~L9yfySRj?@e?(wnF -z<!}<~sp;9d9|q59H-_&3$DbN=#KE}NUzml3#lUq&%D`jYO^+qM_NZeLE#OHaGc!}M -zcQYVn>d@!mZvs{KkHqev$8K13@odIW&rz$!ZVvmErZ`r^4$blGFG(is={Wu`ZEDTF -z%)~;TSCYaP>1E~R+jDszccBAul9c}z7Ito*J#R+nyuc0AU4tGB9z|lMxnx=Dn<=p4 -zq@<*L8KO2GeoX~;gplG-q4>|mii!#m*I79_HEr$iiVCb8zKf5A1#MV3xVXbYWq75z -zw*6H7X*WOdZR-y<R#xdb?u*{f4+J??b@c(T^TYr%8&_6WYg<>(VH9Wk0yZ(e!sjDU -ze2^~TAj7ihcX@I&H#cJ;`v2j%!4#7p$(M+T-JMfL)iH2}0ee9broWXwH{p;&D^>Ac -zKOEWK$Ll3oYleRN4;tmtBuz%Q{1PC|T&aqOk~C6REj)RsE`*(PyMYHUFR%B(ct*(B -z{wShr1Ea{Hci{&c3k%7DYqkwEB*di1>lp)r=&dkej8$!;)dZpc(;!)*;=!XRFjLyx -zoT>yk88u|K-%-;^K=??8b%_L7WczL}{xi+i*7lIqs4M*|Ir~Dr2Ib)2-ILQ(ppA_u -zXi7-WcaMsUB12JG@98<S92_!kCmj8gNCe&Yx^-4Oej_6zGtarL>+9(7nQ~p_Vts{I -zgX$^*uAB@HORE_g3e#*WYcT;NDHG(#^uK)@Z34~>yH3TzMGW@O7AwR>UvV9so$clN -zTx|EeUKF;rdMx!^TwILnlulT=yuSOp6<BQv-$Nr(h(N9#x_5@S9E|rLyON%|4cn8^ -zt%#Doyu3IG<c#MCrUeB-eEar|_M9i1!yNY7^Q{d*6px74&SZBuhMSw4J>bLF+s9|Q -z%Zuyl?C$j$yOM?iH71t!l}8?+GK?&2H2Bhm=PFK0N@_fv!(3k4NJKFVT7x39q9Qpt -znLM=b@^Sa^l>i@~oETN5OpcI{Q2FN-SG@Y{zkiY%8XE3d>ka|4$F409^<Xp1DQmYP -zsrtTS{JBZdfuzx;kQZUN{@9HUeZk5G|5$<^Tfm_;+fFGj3Ijhzdb!aWZLUOV3=?#C -zJF~PT>*2wtq@-lNF=y47!@hkObnM>wS=rQdCpXCcf*C2P<Ky!hN|g$V15`>Ouu~b9 -zP%()2qv_hm7k%Z6{Ma4)xBe`kP^yxrtf!~9p%AlZr$oJVEgQegHx!gt6)*ig)`VS_ -zn-J`RG?!ik5WPqPDlfi0f>BXX3y2in*iv8CHa0dC1b({;b#Xyf;ficQ^_741@~$MK -z7o!N{Ni~9}cg|V3>>6(9<YRBl&!?!pqBEbijQz5}D@q!7NT`q`uBC+|B{e7$$@K`1 -zxkZ(g(UO!LCtcvHdPqDu_ilckgVQyidbuW>)85tg;QH6^oFU>Gbba6R0WrGbd2#cL -z|Im{u8Kl_(#1Qfc|EO%_kCE59gIq4WbHY{aNpNs*3R!)a{ocw6-8*U;eI73u@)l=j -z#TioyIywlm?4NYO-~x;-_U9pAAI=LK8g4=njNv&{RaLL5zmnHUEZ#e4X~iwswK$M} -zS;puu$1rKOfo6r1ucqsR4UJERsD^h3keaZ@16tB)4{F_iEIcmEsp@GcXlZHnkZ~4+ -z{t7!%y5&VnM4)0s#}Jl~!PG8-zr*o)ID=r8s4Fdv`1tU*n#zqC+{SnJH8nLgf^>Cr -zo7vciO}>$Y@1;YB_nkYvzu-bH)Sqh_ghM4hGEL+W4H*HOK@TYc%dF_AhOP-o@tdqa -z>nn1Zn0mw(d>z?VIqhVd9|;$fC6A_#j>-p~GDHb*c5Y4rJda&nzM3pB;Kb9^+NyHm -zozb5@Fd!a^4i1_wYr8!5XNzsNi>wuum2s^rAcxl8y?gIR#;Doyith?wPel8z!b5K1 -z3!Z1lCv+zfiQVxq-D@{O?Oz6Xsrh^)ax~MwsFAOHxk}$IaS73omvjX>X)jq~n;%Nm -z8NdnW=;ETJwH0rUyK!+$rYSWw^^C)u0v#Sa*6}fuJW5y$H0q-qd0Z*-F+k|x{p=ZT -z6pBC2SR!936WW>z3wOcuag_(o4t~TTSEgN_f%D=}A~84`X<}d4p~Q%nVzo{otf&}Z -zR_cQ3mc5h1UpIH&e0YNxSn%vDE%%S$@OOt|dD5Y@R|T}~-T8@`b?X3~>#@L0yXA&3 -zaOi2VTMjne<BLK<L@X;S>)UqP`qAF7+S%E;-0Db1Lqqd#aS=@r#H|E|c{V^G!EHx- -z@6fTUa>a87rFv#bPKtc-O$3$-<TFp-_ica(+Boc2$YAf^uwtThP=7<`lF1pQrsGCL -zpowF40=mPvKCfD6eCxtZZ!rMmxY08+Gh%LT_eC#9yI+1_MnXGwUBmX9#A`B236WZ# -zE>xQ%mUne!|Ch3PCD`$)(czu$j%KQcMA_NDs;Hp(`T1dePev|ErW1bx@D8&3?>q71 -z(qTrHyV=j;D+SIEK>1=+)tQ?VUA01F7&}0fK#+e4{CYw=nhBMSCug>qw_Cx=%uMXY -zL;+m_Y;ZYLHekggAtBMT6(r*nCp?BCLzv?}K06!#s6Bm22We|*SvD(CV-n!1r`EFo -z1Ox<*j*jpjdoE#$k|_)q$@-$=vN><GT2BdBec4oF`u=>sbpaYj{z1Ki^aD)sH2RXu -zjU)u+ub}ObtdHq}>UEhb9kQ~rjxR5#E~apd4nD^}c7wop!z7b-Vq(H>v&T=DC`XYt -z&I@^aJrtOUw_?|#AGg1@O=!}r3yVBNh4ht^>fK&c!rmVi=6H7{p{_7#I!FW;;CVKP -zHjY<C5Iq$BT;E@@Z)j);h5}$fHvook46Lk^7ndg|0yW}5Tie3wYL?eus1Z<L&s6IO -zV3~G%Uqy}B4U?p-cV;|9!RWg=sV1!NCB7=w`b@xhg-%^WqpmLsYRM0q;}S&r(J>lT -zVA6`lF~E-eO<(_u>(O+XyQcg|0+o!aR*GJum71nzGEN&XGjwpf{H=$9f-t7R@6{bM -z@{h691Q|qU&8aA2m^c}7#GrYr7gc;E1S{yr4zgGxuuYHvg^zPJ^v}nSpGiBg%gZqi -zMB~T<8x9Ii1cl|jy?HGyEzYZ!b;H|W=*cby?j3vW*u7^zx6;n_6GG=lWH>Ohw5hpy -z9eRyx*@YRrYK!|4)qG$?svh%dXC`8~Nn+I7YOQrWFanVXnIQrHjdjBmw66ahI9hFA -zd)6)6{n@?lWlVW95?j1?#Kpz^=mF<j^$N~H2;76^QZuF0WZe(}sswQpa<$ebmyU6B -z)k)Ui4oI8al`SHZWw=YJrw3y&-jhm@-Fr}_ceUpy&UNBur)q-ndhm*ehsFrk|7idD -zNOyf=<!wifR$~mvWth-<CfZ;?9&9V<?0khv`l2mI6!2U?%@vz_y*3m=q9z}0U{0ob -z7CyxSdA}so6EIjW775yI4Hu^Xg~CDJ{)M*R6UT(3#-uY3#p8Q4{o`g}B=}1vm_V$p -zz&SDQgO3;wKit{W*m%>X(*YWrJl!MiYl+_nB$L+weU;$AT2K>%u0H!mjEF9Z&J+wt -z5b51#v!JMmTJZ2Ie9+=4iAVC4VIXddv?FSm_^zgsLU&v>Ej349m{g!?iGc>%ez!9t -zDieDtd>1dhvxE%yWeR}5d1V&1*B9v_?sDS2GPne|d>uMEDj$k&lL?-mv(?tiHgDEa -zNW(?Z+09K+vL*Hf4#Zsy0H?p&=3f&1*arCDT!`0A)nBOKYY=3Ocf$3RgQ81AZa#k+ -z#tZ()7!iR?g{o?4aj%-&Kv^o7IYQZ8hQz|?`vH)Pa*2yBsq>IV(Cgg#+QDlJd624` -zw=0I>w9Vb-M!?JfcP^Zl%PEqrOlMT<F`h6Ajy5VPDn^(2bH_z3Ef0n{v8hOgi)^Xt -z2XQ@?W{}9_KTG1qP-pCgM-??t3BpO#Y~*|p*9ga1C#|(&rDMoM8qpmDp+p3*<kzwC -zZXF7L{|<yf!e#fkFi;jarY=#+3SSj|5#!oLcm^Y4adY!s4!GVfELnyzA8+qT@Cxv% -zW`ki$Ir9Ab)_~ZD>hwEJjYIv_hr%2kHix~@<_9(4YGr%P`)L7qm6Eh+{4Kw!iJOUE -zON)V#(QKp3D>*gQtZ}*Fm3EZZtaWvhtB^fGwhB@@4rERc1UGUBJNfkoc9~28c^Qzb -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 000000000..3434739f6 ---- /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 000000000..76e799c60 ---- /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 -zcmeI42Uru!_P`hHA{|0+0#Ze)VxdY)Na!FPX;MW&6cm*!DxxSL(kv(-h=2$ppr{C9 -z@6UeKzls%6FFvIxSoWQ;umpkJ<=y-L-g{p%-(i{To@{pJmosx_=1fd!j{=b1G!u@> -z@RtRDv*C{e5rrdy6vFif+}L052{@qa^gmt$Y=-~i0O9f34A~6(YM`sD>&cTRmo8m8 -zdGcgMMMYUzSxHF=93c;9;QZ64PeF%Zef|9Tv!kQy&71cRA3pEw{6g?uEUWg{?69Mw -z<L1qq04gIR!`Ih${`~oxnwoNQav~xke0+RxguJGv)?5P%Ds@44_^R00%?SyaDJg}C -ziTh$>Gs40)dwa**+C>|gglOq_D=0aOic^F|$wH!560-L4Y94|j<ff(@EDMKV!T()` -zA3uJqudh!_OS7}H15jLCT+^maGcYh9lgZA`&c42WKH)2^f;Q{;@09aDBs|qlQqfU; -zUa+oZ^gO5a7Jl1l5qVB4%iPx2`fNQDkaZ<&-<_z^r?J&<*Vg|t{`6;DjNP}MJb9U5 -zQCL=O^bEVZyU(9LpOTWIqoc#k&8?xK0T?49B9<;)8nJYlOVoC==n|didX44haFNvt -z2v4oubGs|^dS}Yzj-+$#>ly|?;lze!jJ&oVJ=(;wa0nKBlnkFed$xc7erPkn@Mg`L -z6&xJAxHp9_UgEekO?TOe>CtD0iiCDZSn`pA`(Jir7%z2fV!#-8{M|3+hr=}S%Pc89 -zMX)F=t2P>j*REZQi;IJfPF-CcdcV-#6cQTd7?G?SbxeI((?~+nSsId9a`5q23}XgZ -zV=u<v8a~G!ePy$}ARw~=NaE=5jCs)RJ$bb(3x{CA2{UYJYV!8>hQ^ahr3UsV`;hh8 -z5ml;@jm$-8W=z1EeTScQ1IGOOUv}N<0*u=(b*w)6%+PBK4~a~Yb#h54Us2hN)59`W -z;d$G$DhL*ZWz~o=Y-ngOGc)7o=kN7bzy^JNd;<(acPTG9O+<wBS9wQg)V%5ejKz=o -zFs`qCq;DH1sp7f3;-!1y32s44^PtQnMR(%sKj9>)kwqJ~9b{QJ1Pe}p;l+y=O-xKA -zB_&;5T|Ik~i%+mtXvwt2rwEGBoYk)3DJS3dRKM&7j0YZmNvgS{X|h;tUihYl4~b{n -z0b1zZ+kB$b85S`?IcL|LY{M|xt|(i(v4CJvSXS-N7(ROR$ji%1P*4yo5Ew$Dcr8;7 -zJ*p6Pg189H`^_ad>CA_3fU&B%E4k{jl8%p&({I@~I(A&^+<LKNV-p=C7^IAbpQNhS -z!qmFeb?@Pf<Lb(oHG5bV4#9#mW%%jSr*-SrVSS(zJvq<w*(e`!Tt2jJR3dD&-qA1N -z;-~NREnUfnPRl4cxkhG#HRj#>vhyEZ=~o9Zt~t@BMOiB(W#^uBbXD!!1qrp0F<AtQ -z!m?^i8J3rq^YZc<8ymw25YkNVEpoxfaFJb9&9Avc%A*)RgJqzB#atXPR5$}_Jj#ox -zZmTbT=twH85tp@zPOCinqWjR(uYhsi-L9NojL8=|HuPE}n4e|nULIkx)7nz!_#>f9 -z(^wV`!Ge#>@cHxS=H}+g%F2}9q`M$qI<T5i1ZFH&pC8LBVNWt%FB?<?mt+>zD2AU@ -zi#mhJ)Zki@$p%4rcXhK^n%8d|c9)1sQqs!LHNO8=*V04B_~dI5hVf?S_N$$Y7(J3s -z@sKFmlvTb#n+X<$Wz|MzxOeYf2?+@p&RbYm=sK>D3OLFrLM9t!bwk02Tvhu{o0h<@ -z;3ef*0)~fKpmJE9nCS))RbSfj5@;S>*40QW*h$FHN-y2N-tpt?hwkIgKbJrFkbk`; -zyQz8W@ki?`?yWj-V`=W?pp0`q$@Q)qjyuO!8F-{39D3gVi7X3;V8KUV`10jTeSLjX -zQ&aFrwQ1oJew7k_M{pt8<nT#4#2#(Iyhk{CZ*Alex0m-Rlk+$rrWYxt;qSij7(Pny -z+;W;nz)VESMpD5^Si)M6WG*UUE+%O%E^R3xV<9PPAth%ar$|;(qbaL{Sd&C&%E%c; -zMW<{^%B!opNU$g@t2P2dm{60Ek#To-*R)(H=2I@}a~KzrYay2i4Tb_ZK*+4F`(Wyy -z%`0RvO)oGu??UDcx|_1P=5=_%jb(=(gLi@}uR8XgN6<`Pf6m;&Y2Lhfwzjq|E-v5z -zTUl96o;(>=uUHn#s0uzD!=9cV@IhfvZ(-{$>Ty8CyPQ#`NV_`3RrYdwA5--*s_bDz -z;Vn(87->bvtdsXDn(4#8+&f(`Xs`%Ko5XD*r{zD>KAs%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 000000000..f223f061e ---- /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 25070608b..a065c8e88 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 000000000..e265f239c ---- /dev/null -+++ b/im/content/aboutDialog.js -@@ -0,0 +1,80 @@ -+/* 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 " + -+ version + ")"; -+ } -+#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 aa3b80ec9..ba924b9ad 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_default_footer&ref=firefox_about&utm_campaign=firefox_about&tm_source=firefox&tm_medium=referral&utm_content=20140929_FireFoxAbout">&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 000000000..e4315b04a ---- /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 20ea9dce7..b3d9e492f 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 ecd8d9d24..187cf5c3e 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_default_footer&ref=firefox_about&utm_campaign=firefox_about&utm_source=firefox&utm_medium=referral&utm_content=20140929_FireFoxAbout. --> -+<!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 15ec569c1..4a2d35d8a 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.11.0 - diff --git a/projects/instantbird/0012-Account-picture.patch b/projects/instantbird/0012-Account-picture.patch deleted file mode 100644 index 1205946..0000000 --- a/projects/instantbird/0012-Account-picture.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 4247688327fc2d92c05197bfc8f7a0877c8b31a4 Mon Sep 17 00:00:00 2001 -From: Sukhbir Singh sukhbir@torproject.org -Date: Mon, 10 Oct 2016 19:24:09 -0700 -Subject: [PATCH 12/27] 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 b90fddadb..f29a48b99 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.11.0 - diff --git a/projects/instantbird/0012-Modify-protocol-defaults.patch b/projects/instantbird/0012-Modify-protocol-defaults.patch new file mode 100644 index 0000000..f18c794 --- /dev/null +++ b/projects/instantbird/0012-Modify-protocol-defaults.patch @@ -0,0 +1,48 @@ +From 9a17214a4da6b331941d472510cee846ec112979 Mon Sep 17 00:00:00 2001 +From: Sukhbir Singh sukhbir@torproject.org +Date: Mon, 10 Oct 2016 19:25:34 -0700 +Subject: [PATCH 12/26] 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 759f42b38..a3069061a 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 d552a232b..7d371bd21 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.11.0 + diff --git a/projects/instantbird/0013-Modify-IRC-defaults.patch b/projects/instantbird/0013-Modify-IRC-defaults.patch new file mode 100644 index 0000000..66b4cd4 --- /dev/null +++ b/projects/instantbird/0013-Modify-IRC-defaults.patch @@ -0,0 +1,65 @@ +From 08da489af04a8077148865d4671e88e01162a413 Mon Sep 17 00:00:00 2001 +From: Sukhbir Singh sukhbir@torproject.org +Date: Mon, 10 Oct 2016 19:31:58 -0700 +Subject: [PATCH 13/26] 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 35165e9a9..c2167a5ec 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 28eb374f4..120be10ee 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.11.0 + diff --git a/projects/instantbird/0013-Modify-protocol-defaults.patch b/projects/instantbird/0013-Modify-protocol-defaults.patch deleted file mode 100644 index f4a4bf4..0000000 --- a/projects/instantbird/0013-Modify-protocol-defaults.patch +++ /dev/null @@ -1,48 +0,0 @@ -From e5e4d83560b705e54b64c547b3d0159e559c4c92 Mon Sep 17 00:00:00 2001 -From: Sukhbir Singh sukhbir@torproject.org -Date: Mon, 10 Oct 2016 19:25:34 -0700 -Subject: [PATCH 13/27] 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 759f42b38..a3069061a 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 d552a232b..7d371bd21 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.11.0 - diff --git a/projects/instantbird/0014-Modify-IRC-defaults.patch b/projects/instantbird/0014-Modify-IRC-defaults.patch deleted file mode 100644 index 96cedfb..0000000 --- a/projects/instantbird/0014-Modify-IRC-defaults.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 469c5845459bd9427c0020cb616e1ef4e26ac4c3 Mon Sep 17 00:00:00 2001 -From: Sukhbir Singh sukhbir@torproject.org -Date: Mon, 10 Oct 2016 19:31:58 -0700 -Subject: [PATCH 14/27] 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 35165e9a9..c2167a5ec 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 28eb374f4..120be10ee 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.11.0 - diff --git a/projects/instantbird/0014-Modify-themes.patch b/projects/instantbird/0014-Modify-themes.patch new file mode 100644 index 0000000..25594e8 --- /dev/null +++ b/projects/instantbird/0014-Modify-themes.patch @@ -0,0 +1,78 @@ +From d65e732c91cb71fa6383ac314a5544b4045e9a01 Mon Sep 17 00:00:00 2001 +From: Sukhbir Singh sukhbir@torproject.org +Date: Mon, 10 Oct 2016 19:36:38 -0700 +Subject: [PATCH 14/26] 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 a7e38bba4..c5c781a97 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:nameInstantbird (default)</em:name> + em:descriptionThe default theme.</em:description> ++ em:updateURLdata: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 5c5d594cb..4a9d6afd0 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 454e36696..18ba1f95c 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.11.0 + diff --git a/projects/instantbird/0015-Modify-XMPP-defaults.patch b/projects/instantbird/0015-Modify-XMPP-defaults.patch new file mode 100644 index 0000000..039d9a3 --- /dev/null +++ b/projects/instantbird/0015-Modify-XMPP-defaults.patch @@ -0,0 +1,48 @@ +From 0ee19d29c6d38d5f945ec65e60c42f2f86bb679b Mon Sep 17 00:00:00 2001 +From: Sukhbir Singh sukhbir@torproject.org +Date: Mon, 10 Oct 2016 19:38:49 -0700 +Subject: [PATCH 15/26] 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 8bce0c9b4..642f4561d 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 265445a18..a5635cae3 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.11.0 + diff --git a/projects/instantbird/0015-Modify-themes.patch b/projects/instantbird/0015-Modify-themes.patch deleted file mode 100644 index 5edd9be..0000000 --- a/projects/instantbird/0015-Modify-themes.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 0b72c7881c1dfc220fd3b8be2a502b34c4763c15 Mon Sep 17 00:00:00 2001 -From: Sukhbir Singh sukhbir@torproject.org -Date: Mon, 10 Oct 2016 19:36:38 -0700 -Subject: [PATCH 15/27] 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 a7e38bba4..c5c781a97 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:nameInstantbird (default)</em:name> - em:descriptionThe default theme.</em:description> -+ em:updateURLdata: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 5c5d594cb..4a9d6afd0 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 454e36696..18ba1f95c 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.11.0 - diff --git a/projects/instantbird/0016-Modify-XMPP-defaults.patch b/projects/instantbird/0016-Modify-XMPP-defaults.patch deleted file mode 100644 index 9f1a760..0000000 --- a/projects/instantbird/0016-Modify-XMPP-defaults.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 365390f7a795255a6d5c8f1a4e27f44f9b24aeb8 Mon Sep 17 00:00:00 2001 -From: Sukhbir Singh sukhbir@torproject.org -Date: Mon, 10 Oct 2016 19:38:49 -0700 -Subject: [PATCH 16/27] 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 8bce0c9b4..642f4561d 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 265445a18..a5635cae3 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.11.0 - diff --git a/projects/instantbird/0016-Remove-logging-UI.patch b/projects/instantbird/0016-Remove-logging-UI.patch new file mode 100644 index 0000000..e547d03 --- /dev/null +++ b/projects/instantbird/0016-Remove-logging-UI.patch @@ -0,0 +1,43 @@ +From 1486a399e93f612eb41a2ce3a54d6642ec940c8f Mon Sep 17 00:00:00 2001 +From: Sukhbir Singh sukhbir@torproject.org +Date: Mon, 10 Oct 2016 19:50:48 -0700 +Subject: [PATCH 16/26] 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 7c9db1cdd..2d7b2701e 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.11.0 + diff --git a/projects/instantbird/0017-Cert-override.patch b/projects/instantbird/0017-Cert-override.patch new file mode 100644 index 0000000..2a8de75 --- /dev/null +++ b/projects/instantbird/0017-Cert-override.patch @@ -0,0 +1,64 @@ +From ef9f118d22410cc5d051740a83f774387c4bbf8d Mon Sep 17 00:00:00 2001 +From: Sukhbir Singh sukhbir@torproject.org +Date: Mon, 10 Oct 2016 19:56:46 -0700 +Subject: [PATCH 17/26] 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 000000000..4e616f6cf +--- /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 46bc16bd1..b7d4ebd4b 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 25dd67617..5f06e784c 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 1174b3dfd..3e35a2e1b 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.11.0 + diff --git a/projects/instantbird/0017-Remove-logging-UI.patch b/projects/instantbird/0017-Remove-logging-UI.patch deleted file mode 100644 index 481fd27..0000000 --- a/projects/instantbird/0017-Remove-logging-UI.patch +++ /dev/null @@ -1,43 +0,0 @@ -From b7da961febb3d93eb7a056394f61683ba64d3b1c Mon Sep 17 00:00:00 2001 -From: Sukhbir Singh sukhbir@torproject.org -Date: Mon, 10 Oct 2016 19:50:48 -0700 -Subject: [PATCH 17/27] 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 7c9db1cdd..2d7b2701e 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.11.0 - diff --git a/projects/instantbird/0018-Cert-override.patch b/projects/instantbird/0018-Cert-override.patch deleted file mode 100644 index 63155f0..0000000 --- a/projects/instantbird/0018-Cert-override.patch +++ /dev/null @@ -1,64 +0,0 @@ -From aebafcab4731aaf8aad4d36ee08b1f205af8e449 Mon Sep 17 00:00:00 2001 -From: Sukhbir Singh sukhbir@torproject.org -Date: Mon, 10 Oct 2016 19:56:46 -0700 -Subject: [PATCH 18/27] 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 000000000..4e616f6cf ---- /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 46bc16bd1..b7d4ebd4b 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 25dd67617..5f06e784c 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 1174b3dfd..3e35a2e1b 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.11.0 - diff --git a/projects/instantbird/0018-Display-all-traffic-over-Tor.patch b/projects/instantbird/0018-Display-all-traffic-over-Tor.patch new file mode 100644 index 0000000..4b38188 --- /dev/null +++ b/projects/instantbird/0018-Display-all-traffic-over-Tor.patch @@ -0,0 +1,38 @@ +From a8afc6259faa65ef53b61ece6c4f954c5c0f89b1 Mon Sep 17 00:00:00 2001 +From: Sukhbir Singh sukhbir@torproject.org +Date: Mon, 10 Oct 2016 19:58:31 -0700 +Subject: [PATCH 18/26] 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 a3069061a..3c3a4179b 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 c46fb2f95..6b49c84fa 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.11.0 + diff --git a/projects/instantbird/0019-Display-all-traffic-over-Tor.patch b/projects/instantbird/0019-Display-all-traffic-over-Tor.patch deleted file mode 100644 index 8eeda8f..0000000 --- a/projects/instantbird/0019-Display-all-traffic-over-Tor.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 1bdd9493ad25fbaf63afdd6d26dd3f43a169932a Mon Sep 17 00:00:00 2001 -From: Sukhbir Singh sukhbir@torproject.org -Date: Mon, 10 Oct 2016 19:58:31 -0700 -Subject: [PATCH 19/27] 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 a3069061a..3c3a4179b 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 c46fb2f95..6b49c84fa 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.11.0 - diff --git a/projects/instantbird/0019-Trac-17480-Content-sink.patch b/projects/instantbird/0019-Trac-17480-Content-sink.patch new file mode 100644 index 0000000..f08a374 --- /dev/null +++ b/projects/instantbird/0019-Trac-17480-Content-sink.patch @@ -0,0 +1,111 @@ +From 4cbffef65c77ae2fa4ecf480a5b38c79200a898f Mon Sep 17 00:00:00 2001 +From: Arlo Breault arlolra@gmail.com +Date: Wed, 5 Oct 2016 11:09:25 -0700 +Subject: [PATCH 19/26] Trac 17480: Content sink + +--- + chat/modules/imContentSink.jsm | 33 ++++++--------------------------- + im/content/preferences/content.xul | 2 +- + 2 files changed, 7 insertions(+), 28 deletions(-) + +diff --git a/chat/modules/imContentSink.jsm b/chat/modules/imContentSink.jsm +index abd95fc71..fa32442e4 100644 +--- a/chat/modules/imContentSink.jsm ++++ b/chat/modules/imContentSink.jsm +@@ -42,7 +42,7 @@ this.EXPORTED_SYMBOLS = [ + * See the 3 examples of rulesets below. + */ + +-var kAllowedURLs = aValue => /^(https?|ftp|mailto):/.test(aValue); ++var kAllowedURLs = aValue => /^(https?|mailto):/.test(aValue); + var kAllowedMozClasses = + aClassName => aClassName == "moz-txt-underscore" || + aClassName == "moz-txt-tag" || +@@ -60,11 +60,6 @@ var kStrictMode = { + attrs: { }, + + tags: { +- 'a': { +- 'title': true, +- 'href': kAllowedURLs, +- 'class': kAllowedAnchorClasses +- }, + 'br': true, + 'p': true + }, +@@ -74,12 +69,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, +@@ -90,24 +82,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 +@@ -162,7 +141,7 @@ var kPermissiveMode = { + }; + + var kModePref = "messenger.options.filterMode"; +-var kModes = [kStrictMode, kStandardMode, kPermissiveMode]; ++var kModes = [kStrictMode, kStandardMode]; + + var gGlobalRuleset = null; + +@@ -188,8 +167,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 3b8ccfa2b..ba41da76a 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.11.0 + diff --git a/projects/instantbird/0020-SASL-ECDSA-NIST256P-CHALLENGE.patch b/projects/instantbird/0020-SASL-ECDSA-NIST256P-CHALLENGE.patch new file mode 100644 index 0000000..385a63d --- /dev/null +++ b/projects/instantbird/0020-SASL-ECDSA-NIST256P-CHALLENGE.patch @@ -0,0 +1,8919 @@ +From e5d30254bb7da7ac6286b8f3e5f062072c170d9d Mon Sep 17 00:00:00 2001 +From: Arlo Breault arlolra@gmail.com +Date: Sun, 2 Oct 2016 08:46:55 -0700 +Subject: [PATCH 20/26] SASL ECDSA-NIST256P-CHALLENGE + +--- + chat/components/src/imAccounts.js | 1 + + chat/protocols/irc/elliptic.jsm | 8748 +++++++++++++++++++++++++++++++++++++ + chat/protocols/irc/ircSASL.jsm | 87 +- + chat/protocols/irc/moz.build | 1 + + 4 files changed, 8823 insertions(+), 14 deletions(-) + create mode 100644 chat/protocols/irc/elliptic.jsm + +diff --git a/chat/components/src/imAccounts.js b/chat/components/src/imAccounts.js +index 5bfea57f2..da8525ffd 100644 +--- a/chat/components/src/imAccounts.js ++++ b/chat/components/src/imAccounts.js +@@ -193,6 +193,7 @@ function imAccount(aKey, aName, aPrplId) + + imAccount.prototype = { + __proto__: ClassInfo(["imIAccount", "prplIAccount"], "im account object"), ++ get wrappedJSObject() { return this; }, + + name: "", + id: "", +diff --git a/chat/protocols/irc/elliptic.jsm b/chat/protocols/irc/elliptic.jsm +new file mode 100644 +index 000000000..bccab018c +--- /dev/null ++++ b/chat/protocols/irc/elliptic.jsm +@@ -0,0 +1,8748 @@ ++/* This software is licensed under the MIT License. ++ * ++ * Copyright Fedor Indutny, 2014. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this software and associated documentation files (the "Software"), to deal ++ * in the Software without restriction, including without limitation the rights ++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++ * copies of the Software, and to permit persons to whom the Software is ++ * furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ * SOFTWARE. ++ */ ++ ++this.EXPORTED_SYMBOLS = ["elliptic"]; ++ ++var window = {}; ++ ++// The code below is imported from indutny's elliptic.js. The original version ++// of this file can be found at ++// https://github.com/indutny/elliptic/blob/master/dist/elliptic.js ++ ++(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.elliptic = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ ++(function (module, exports) { ++ 'use strict'; ++ ++ // Utils ++ function assert (val, msg) { ++ if (!val) throw new Error(msg || 'Assertion failed'); ++ } ++ ++ // Could use `inherits` module, but don't want to move from single file ++ // architecture yet. ++ function inherits (ctor, superCtor) { ++ ctor.super_ = superCtor; ++ var TempCtor = function () {}; ++ TempCtor.prototype = superCtor.prototype; ++ ctor.prototype = new TempCtor(); ++ ctor.prototype.constructor = ctor; ++ } ++ ++ // BN ++ ++ function BN (number, base, endian) { ++ if (BN.isBN(number)) { ++ return number; ++ } ++ ++ this.negative = 0; ++ this.words = null; ++ this.length = 0; ++ ++ // Reduction context ++ this.red = null; ++ ++ if (number !== null) { ++ if (base === 'le' || base === 'be') { ++ endian = base; ++ base = 10; ++ } ++ ++ this._init(number || 0, base || 10, endian || 'be'); ++ } ++ } ++ if (typeof module === 'object') { ++ module.exports = BN; ++ } else { ++ exports.BN = BN; ++ } ++ ++ BN.BN = BN; ++ BN.wordSize = 26; ++ ++ var Buffer; ++ try { ++ Buffer = require('buf' + 'fer').Buffer; ++ } catch (e) { ++ } ++ ++ BN.isBN = function isBN (num) { ++ if (num instanceof BN) { ++ return true; ++ } ++ ++ return num !== null && typeof num === 'object' && ++ num.constructor.wordSize === BN.wordSize && Array.isArray(num.words); ++ }; ++ ++ BN.max = function max (left, right) { ++ if (left.cmp(right) > 0) return left; ++ return right; ++ }; ++ ++ BN.min = function min (left, right) { ++ if (left.cmp(right) < 0) return left; ++ return right; ++ }; ++ ++ BN.prototype._init = function init (number, base, endian) { ++ if (typeof number === 'number') { ++ return this._initNumber(number, base, endian); ++ } ++ ++ if (typeof number === 'object') { ++ return this._initArray(number, base, endian); ++ } ++ ++ if (base === 'hex') { ++ base = 16; ++ } ++ assert(base === (base | 0) && base >= 2 && base <= 36); ++ ++ number = number.toString().replace(/\s+/g, ''); ++ var start = 0; ++ if (number[0] === '-') { ++ start++; ++ } ++ ++ if (base === 16) { ++ this._parseHex(number, start); ++ } else { ++ this._parseBase(number, base, start); ++ } ++ ++ if (number[0] === '-') { ++ this.negative = 1; ++ } ++ ++ this.strip(); ++ ++ if (endian !== 'le') return; ++ ++ this._initArray(this.toArray(), base, endian); ++ }; ++ ++ BN.prototype._initNumber = function _initNumber (number, base, endian) { ++ if (number < 0) { ++ this.negative = 1; ++ number = -number; ++ } ++ if (number < 0x4000000) { ++ this.words = [ number & 0x3ffffff ]; ++ this.length = 1; ++ } else if (number < 0x10000000000000) { ++ this.words = [ ++ number & 0x3ffffff, ++ (number / 0x4000000) & 0x3ffffff ++ ]; ++ this.length = 2; ++ } else { ++ assert(number < 0x20000000000000); // 2 ^ 53 (unsafe) ++ this.words = [ ++ number & 0x3ffffff, ++ (number / 0x4000000) & 0x3ffffff, ++ 1 ++ ]; ++ this.length = 3; ++ } ++ ++ if (endian !== 'le') return; ++ ++ // Reverse the bytes ++ this._initArray(this.toArray(), base, endian); ++ }; ++ ++ BN.prototype._initArray = function _initArray (number, base, endian) { ++ // Perhaps a Uint8Array ++ assert(typeof number.length === 'number'); ++ if (number.length <= 0) { ++ this.words = [ 0 ]; ++ this.length = 1; ++ return this; ++ } ++ ++ this.length = Math.ceil(number.length / 3); ++ this.words = new Array(this.length); ++ for (var i = 0; i < this.length; i++) { ++ this.words[i] = 0; ++ } ++ ++ var j, w; ++ var off = 0; ++ if (endian === 'be') { ++ for (i = number.length - 1, j = 0; i >= 0; i -= 3) { ++ w = number[i] | (number[i - 1] << 8) | (number[i - 2] << 16); ++ this.words[j] |= (w << off) & 0x3ffffff; ++ this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff; ++ off += 24; ++ if (off >= 26) { ++ off -= 26; ++ j++; ++ } ++ } ++ } else if (endian === 'le') { ++ for (i = 0, j = 0; i < number.length; i += 3) { ++ w = number[i] | (number[i + 1] << 8) | (number[i + 2] << 16); ++ this.words[j] |= (w << off) & 0x3ffffff; ++ this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff; ++ off += 24; ++ if (off >= 26) { ++ off -= 26; ++ j++; ++ } ++ } ++ } ++ return this.strip(); ++ }; ++ ++ function parseHex (str, start, end) { ++ var r = 0; ++ var len = Math.min(str.length, end); ++ for (var i = start; i < len; i++) { ++ var c = str.charCodeAt(i) - 48; ++ ++ r <<= 4; ++ ++ // 'a' - 'f' ++ if (c >= 49 && c <= 54) { ++ r |= c - 49 + 0xa; ++ ++ // 'A' - 'F' ++ } else if (c >= 17 && c <= 22) { ++ r |= c - 17 + 0xa; ++ ++ // '0' - '9' ++ } else { ++ r |= c & 0xf; ++ } ++ } ++ return r; ++ } ++ ++ BN.prototype._parseHex = function _parseHex (number, start) { ++ // Create possibly bigger array to ensure that it fits the number ++ this.length = Math.ceil((number.length - start) / 6); ++ this.words = new Array(this.length); ++ for (var i = 0; i < this.length; i++) { ++ this.words[i] = 0; ++ } ++ ++ var j, w; ++ // Scan 24-bit chunks and add them to the number ++ var off = 0; ++ for (i = number.length - 6, j = 0; i >= start; i -= 6) { ++ w = parseHex(number, i, i + 6); ++ this.words[j] |= (w << off) & 0x3ffffff; ++ // NOTE: `0x3fffff` is intentional here, 26bits max shift + 24bit hex limb ++ this.words[j + 1] |= w >>> (26 - off) & 0x3fffff; ++ off += 24; ++ if (off >= 26) { ++ off -= 26; ++ j++; ++ } ++ } ++ if (i + 6 !== start) { ++ w = parseHex(number, start, i + 6); ++ this.words[j] |= (w << off) & 0x3ffffff; ++ this.words[j + 1] |= w >>> (26 - off) & 0x3fffff; ++ } ++ this.strip(); ++ }; ++ ++ function parseBase (str, start, end, mul) { ++ var r = 0; ++ var len = Math.min(str.length, end); ++ for (var i = start; i < len; i++) { ++ var c = str.charCodeAt(i) - 48; ++ ++ r *= mul; ++ ++ // 'a' ++ if (c >= 49) { ++ r += c - 49 + 0xa; ++ ++ // 'A' ++ } else if (c >= 17) { ++ r += c - 17 + 0xa; ++ ++ // '0' - '9' ++ } else { ++ r += c; ++ } ++ } ++ return r; ++ } ++ ++ BN.prototype._parseBase = function _parseBase (number, base, start) { ++ // Initialize as zero ++ this.words = [ 0 ]; ++ this.length = 1; ++ ++ // Find length of limb in base ++ for (var limbLen = 0, limbPow = 1; limbPow <= 0x3ffffff; limbPow *= base) { ++ limbLen++; ++ } ++ limbLen--; ++ limbPow = (limbPow / base) | 0; ++ ++ var total = number.length - start; ++ var mod = total % limbLen; ++ var end = Math.min(total, total - mod) + start; ++ ++ var word = 0; ++ for (var i = start; i < end; i += limbLen) { ++ word = parseBase(number, i, i + limbLen, base); ++ ++ this.imuln(limbPow); ++ if (this.words[0] + word < 0x4000000) { ++ this.words[0] += word; ++ } else { ++ this._iaddn(word); ++ } ++ } ++ ++ if (mod !== 0) { ++ var pow = 1; ++ word = parseBase(number, i, number.length, base); ++ ++ for (i = 0; i < mod; i++) { ++ pow *= base; ++ } ++ ++ this.imuln(pow); ++ if (this.words[0] + word < 0x4000000) { ++ this.words[0] += word; ++ } else { ++ this._iaddn(word); ++ } ++ } ++ }; ++ ++ BN.prototype.copy = function copy (dest) { ++ dest.words = new Array(this.length); ++ for (var i = 0; i < this.length; i++) { ++ dest.words[i] = this.words[i]; ++ } ++ dest.length = this.length; ++ dest.negative = this.negative; ++ dest.red = this.red; ++ }; ++ ++ BN.prototype.clone = function clone () { ++ var r = new BN(null); ++ this.copy(r); ++ return r; ++ }; ++ ++ BN.prototype._expand = function _expand (size) { ++ while (this.length < size) { ++ this.words[this.length++] = 0; ++ } ++ return this; ++ }; ++ ++ // Remove leading `0` from `this` ++ BN.prototype.strip = function strip () { ++ while (this.length > 1 && this.words[this.length - 1] === 0) { ++ this.length--; ++ } ++ return this._normSign(); ++ }; ++ ++ BN.prototype._normSign = function _normSign () { ++ // -0 = 0 ++ if (this.length === 1 && this.words[0] === 0) { ++ this.negative = 0; ++ } ++ return this; ++ }; ++ ++ BN.prototype.inspect = function inspect () { ++ return (this.red ? '<BN-R: ' : '<BN: ') + this.toString(16) + '>'; ++ }; ++ ++ /* ++ ++ var zeros = []; ++ var groupSizes = []; ++ var groupBases = []; ++ ++ var s = ''; ++ var i = -1; ++ while (++i < BN.wordSize) { ++ zeros[i] = s; ++ s += '0'; ++ } ++ groupSizes[0] = 0; ++ groupSizes[1] = 0; ++ groupBases[0] = 0; ++ groupBases[1] = 0; ++ var base = 2 - 1; ++ while (++base < 36 + 1) { ++ var groupSize = 0; ++ var groupBase = 1; ++ while (groupBase < (1 << BN.wordSize) / base) { ++ groupBase *= base; ++ groupSize += 1; ++ } ++ groupSizes[base] = groupSize; ++ groupBases[base] = groupBase; ++ } ++ ++ */ ++ ++ var zeros = [ ++ '', ++ '0', ++ '00', ++ '000', ++ '0000', ++ '00000', ++ '000000', ++ '0000000', ++ '00000000', ++ '000000000', ++ '0000000000', ++ '00000000000', ++ '000000000000', ++ '0000000000000', ++ '00000000000000', ++ '000000000000000', ++ '0000000000000000', ++ '00000000000000000', ++ '000000000000000000', ++ '0000000000000000000', ++ '00000000000000000000', ++ '000000000000000000000', ++ '0000000000000000000000', ++ '00000000000000000000000', ++ '000000000000000000000000', ++ '0000000000000000000000000' ++ ]; ++ ++ var groupSizes = [ ++ 0, 0, ++ 25, 16, 12, 11, 10, 9, 8, ++ 8, 7, 7, 7, 7, 6, 6, ++ 6, 6, 6, 6, 6, 5, 5, ++ 5, 5, 5, 5, 5, 5, 5, ++ 5, 5, 5, 5, 5, 5, 5 ++ ]; ++ ++ var groupBases = [ ++ 0, 0, ++ 33554432, 43046721, 16777216, 48828125, 60466176, 40353607, 16777216, ++ 43046721, 10000000, 19487171, 35831808, 62748517, 7529536, 11390625, ++ 16777216, 24137569, 34012224, 47045881, 64000000, 4084101, 5153632, ++ 6436343, 7962624, 9765625, 11881376, 14348907, 17210368, 20511149, ++ 24300000, 28629151, 33554432, 39135393, 45435424, 52521875, 60466176 ++ ]; ++ ++ BN.prototype.toString = function toString (base, padding) { ++ base = base || 10; ++ padding = padding | 0 || 1; ++ ++ var out; ++ if (base === 16 || base === 'hex') { ++ out = ''; ++ var off = 0; ++ var carry = 0; ++ for (var i = 0; i < this.length; i++) { ++ var w = this.words[i]; ++ var word = (((w << off) | carry) & 0xffffff).toString(16); ++ carry = (w >>> (24 - off)) & 0xffffff; ++ if (carry !== 0 || i !== this.length - 1) { ++ out = zeros[6 - word.length] + word + out; ++ } else { ++ out = word + out; ++ } ++ off += 2; ++ if (off >= 26) { ++ off -= 26; ++ i--; ++ } ++ } ++ if (carry !== 0) { ++ out = carry.toString(16) + out; ++ } ++ while (out.length % padding !== 0) { ++ out = '0' + out; ++ } ++ if (this.negative !== 0) { ++ out = '-' + out; ++ } ++ return out; ++ } ++ ++ if (base === (base | 0) && base >= 2 && base <= 36) { ++ // var groupSize = Math.floor(BN.wordSize * Math.LN2 / Math.log(base)); ++ var groupSize = groupSizes[base]; ++ // var groupBase = Math.pow(base, groupSize); ++ var groupBase = groupBases[base]; ++ out = ''; ++ var c = this.clone(); ++ c.negative = 0; ++ while (!c.isZero()) { ++ var r = c.modn(groupBase).toString(base); ++ c = c.idivn(groupBase); ++ ++ if (!c.isZero()) { ++ out = zeros[groupSize - r.length] + r + out; ++ } else { ++ out = r + out; ++ } ++ } ++ if (this.isZero()) { ++ out = '0' + out; ++ } ++ while (out.length % padding !== 0) { ++ out = '0' + out; ++ } ++ if (this.negative !== 0) { ++ out = '-' + out; ++ } ++ return out; ++ } ++ ++ assert(false, 'Base should be between 2 and 36'); ++ }; ++ ++ BN.prototype.toNumber = function toNumber () { ++ var ret = this.words[0]; ++ if (this.length === 2) { ++ ret += this.words[1] * 0x4000000; ++ } else if (this.length === 3 && this.words[2] === 0x01) { ++ // NOTE: at this stage it is known that the top bit is set ++ ret += 0x10000000000000 + (this.words[1] * 0x4000000); ++ } else if (this.length > 2) { ++ assert(false, 'Number can only safely store up to 53 bits'); ++ } ++ return (this.negative !== 0) ? -ret : ret; ++ }; ++ ++ BN.prototype.toJSON = function toJSON () { ++ return this.toString(16); ++ }; ++ ++ BN.prototype.toBuffer = function toBuffer (endian, length) { ++ assert(typeof Buffer !== 'undefined'); ++ return this.toArrayLike(Buffer, endian, length); ++ }; ++ ++ BN.prototype.toArray = function toArray (endian, length) { ++ return this.toArrayLike(Array, endian, length); ++ }; ++ ++ BN.prototype.toArrayLike = function toArrayLike (ArrayType, endian, length) { ++ var byteLength = this.byteLength(); ++ var reqLength = length || Math.max(1, byteLength); ++ assert(byteLength <= reqLength, 'byte array longer than desired length'); ++ assert(reqLength > 0, 'Requested array length <= 0'); ++ ++ this.strip(); ++ var littleEndian = endian === 'le'; ++ var res = new ArrayType(reqLength); ++ ++ var b, i; ++ var q = this.clone(); ++ if (!littleEndian) { ++ // Assume big-endian ++ for (i = 0; i < reqLength - byteLength; i++) { ++ res[i] = 0; ++ } ++ ++ for (i = 0; !q.isZero(); i++) { ++ b = q.andln(0xff); ++ q.iushrn(8); ++ ++ res[reqLength - i - 1] = b; ++ } ++ } else { ++ for (i = 0; !q.isZero(); i++) { ++ b = q.andln(0xff); ++ q.iushrn(8); ++ ++ res[i] = b; ++ } ++ ++ for (; i < reqLength; i++) { ++ res[i] = 0; ++ } ++ } ++ ++ return res; ++ }; ++ ++ if (Math.clz32) { ++ BN.prototype._countBits = function _countBits (w) { ++ return 32 - Math.clz32(w); ++ }; ++ } else { ++ BN.prototype._countBits = function _countBits (w) { ++ var t = w; ++ var r = 0; ++ if (t >= 0x1000) { ++ r += 13; ++ t >>>= 13; ++ } ++ if (t >= 0x40) { ++ r += 7; ++ t >>>= 7; ++ } ++ if (t >= 0x8) { ++ r += 4; ++ t >>>= 4; ++ } ++ if (t >= 0x02) { ++ r += 2; ++ t >>>= 2; ++ } ++ return r + t; ++ }; ++ } ++ ++ BN.prototype._zeroBits = function _zeroBits (w) { ++ // Short-cut ++ if (w === 0) return 26; ++ ++ var t = w; ++ var r = 0; ++ if ((t & 0x1fff) === 0) { ++ r += 13; ++ t >>>= 13; ++ } ++ if ((t & 0x7f) === 0) { ++ r += 7; ++ t >>>= 7; ++ } ++ if ((t & 0xf) === 0) { ++ r += 4; ++ t >>>= 4; ++ } ++ if ((t & 0x3) === 0) { ++ r += 2; ++ t >>>= 2; ++ } ++ if ((t & 0x1) === 0) { ++ r++; ++ } ++ return r; ++ }; ++ ++ // Return number of used bits in a BN ++ BN.prototype.bitLength = function bitLength () { ++ var w = this.words[this.length - 1]; ++ var hi = this._countBits(w); ++ return (this.length - 1) * 26 + hi; ++ }; ++ ++ function toBitArray (num) { ++ var w = new Array(num.bitLength()); ++ ++ for (var bit = 0; bit < w.length; bit++) { ++ var off = (bit / 26) | 0; ++ var wbit = bit % 26; ++ ++ w[bit] = (num.words[off] & (1 << wbit)) >>> wbit; ++ } ++ ++ return w; ++ } ++ ++ // Number of trailing zero bits ++ BN.prototype.zeroBits = function zeroBits () { ++ if (this.isZero()) return 0; ++ ++ var r = 0; ++ for (var i = 0; i < this.length; i++) { ++ var b = this._zeroBits(this.words[i]); ++ r += b; ++ if (b !== 26) break; ++ } ++ return r; ++ }; ++ ++ BN.prototype.byteLength = function byteLength () { ++ return Math.ceil(this.bitLength() / 8); ++ }; ++ ++ BN.prototype.toTwos = function toTwos (width) { ++ if (this.negative !== 0) { ++ return this.abs().inotn(width).iaddn(1); ++ } ++ return this.clone(); ++ }; ++ ++ BN.prototype.fromTwos = function fromTwos (width) { ++ if (this.testn(width - 1)) { ++ return this.notn(width).iaddn(1).ineg(); ++ } ++ return this.clone(); ++ }; ++ ++ BN.prototype.isNeg = function isNeg () { ++ return this.negative !== 0; ++ }; ++ ++ // Return negative clone of `this` ++ BN.prototype.neg = function neg () { ++ return this.clone().ineg(); ++ }; ++ ++ BN.prototype.ineg = function ineg () { ++ if (!this.isZero()) { ++ this.negative ^= 1; ++ } ++ ++ return this; ++ }; ++ ++ // Or `num` with `this` in-place ++ BN.prototype.iuor = function iuor (num) { ++ while (this.length < num.length) { ++ this.words[this.length++] = 0; ++ } ++ ++ for (var i = 0; i < num.length; i++) { ++ this.words[i] = this.words[i] | num.words[i]; ++ } ++ ++ return this.strip(); ++ }; ++ ++ BN.prototype.ior = function ior (num) { ++ assert((this.negative | num.negative) === 0); ++ return this.iuor(num); ++ }; ++ ++ // Or `num` with `this` ++ BN.prototype.or = function or (num) { ++ if (this.length > num.length) return this.clone().ior(num); ++ return num.clone().ior(this); ++ }; ++ ++ BN.prototype.uor = function uor (num) { ++ if (this.length > num.length) return this.clone().iuor(num); ++ return num.clone().iuor(this); ++ }; ++ ++ // And `num` with `this` in-place ++ BN.prototype.iuand = function iuand (num) { ++ // b = min-length(num, this) ++ var b; ++ if (this.length > num.length) { ++ b = num; ++ } else { ++ b = this; ++ } ++ ++ for (var i = 0; i < b.length; i++) { ++ this.words[i] = this.words[i] & num.words[i]; ++ } ++ ++ this.length = b.length; ++ ++ return this.strip(); ++ }; ++ ++ BN.prototype.iand = function iand (num) { ++ assert((this.negative | num.negative) === 0); ++ return this.iuand(num); ++ }; ++ ++ // And `num` with `this` ++ BN.prototype.and = function and (num) { ++ if (this.length > num.length) return this.clone().iand(num); ++ return num.clone().iand(this); ++ }; ++ ++ BN.prototype.uand = function uand (num) { ++ if (this.length > num.length) return this.clone().iuand(num); ++ return num.clone().iuand(this); ++ }; ++ ++ // Xor `num` with `this` in-place ++ BN.prototype.iuxor = function iuxor (num) { ++ // a.length > b.length ++ var a; ++ var b; ++ if (this.length > num.length) { ++ a = this; ++ b = num; ++ } else { ++ a = num; ++ b = this; ++ } ++ ++ for (var i = 0; i < b.length; i++) { ++ this.words[i] = a.words[i] ^ b.words[i]; ++ } ++ ++ if (this !== a) { ++ for (; i < a.length; i++) { ++ this.words[i] = a.words[i]; ++ } ++ } ++ ++ this.length = a.length; ++ ++ return this.strip(); ++ }; ++ ++ BN.prototype.ixor = function ixor (num) { ++ assert((this.negative | num.negative) === 0); ++ return this.iuxor(num); ++ }; ++ ++ // Xor `num` with `this` ++ BN.prototype.xor = function xor (num) { ++ if (this.length > num.length) return this.clone().ixor(num); ++ return num.clone().ixor(this); ++ }; ++ ++ BN.prototype.uxor = function uxor (num) { ++ if (this.length > num.length) return this.clone().iuxor(num); ++ return num.clone().iuxor(this); ++ }; ++ ++ // Not ``this`` with ``width`` bitwidth ++ BN.prototype.inotn = function inotn (width) { ++ assert(typeof width === 'number' && width >= 0); ++ ++ var bytesNeeded = Math.ceil(width / 26) | 0; ++ var bitsLeft = width % 26; ++ ++ // Extend the buffer with leading zeroes ++ this._expand(bytesNeeded); ++ ++ if (bitsLeft > 0) { ++ bytesNeeded--; ++ } ++ ++ // Handle complete words ++ for (var i = 0; i < bytesNeeded; i++) { ++ this.words[i] = ~this.words[i] & 0x3ffffff; ++ } ++ ++ // Handle the residue ++ if (bitsLeft > 0) { ++ this.words[i] = ~this.words[i] & (0x3ffffff >> (26 - bitsLeft)); ++ } ++ ++ // And remove leading zeroes ++ return this.strip(); ++ }; ++ ++ BN.prototype.notn = function notn (width) { ++ return this.clone().inotn(width); ++ }; ++ ++ // Set `bit` of `this` ++ BN.prototype.setn = function setn (bit, val) { ++ assert(typeof bit === 'number' && bit >= 0); ++ ++ var off = (bit / 26) | 0; ++ var wbit = bit % 26; ++ ++ this._expand(off + 1); ++ ++ if (val) { ++ this.words[off] = this.words[off] | (1 << wbit); ++ } else { ++ this.words[off] = this.words[off] & ~(1 << wbit); ++ } ++ ++ return this.strip(); ++ }; ++ ++ // Add `num` to `this` in-place ++ BN.prototype.iadd = function iadd (num) { ++ var r; ++ ++ // negative + positive ++ if (this.negative !== 0 && num.negative === 0) { ++ this.negative = 0; ++ r = this.isub(num); ++ this.negative ^= 1; ++ return this._normSign(); ++ ++ // positive + negative ++ } else if (this.negative === 0 && num.negative !== 0) { ++ num.negative = 0; ++ r = this.isub(num); ++ num.negative = 1; ++ return r._normSign(); ++ } ++ ++ // a.length > b.length ++ var a, b; ++ if (this.length > num.length) { ++ a = this; ++ b = num; ++ } else { ++ a = num; ++ b = this; ++ } ++ ++ var carry = 0; ++ for (var i = 0; i < b.length; i++) { ++ r = (a.words[i] | 0) + (b.words[i] | 0) + carry; ++ this.words[i] = r & 0x3ffffff; ++ carry = r >>> 26; ++ } ++ for (; carry !== 0 && i < a.length; i++) { ++ r = (a.words[i] | 0) + carry; ++ this.words[i] = r & 0x3ffffff; ++ carry = r >>> 26; ++ } ++ ++ this.length = a.length; ++ if (carry !== 0) { ++ this.words[this.length] = carry; ++ this.length++; ++ // Copy the rest of the words ++ } else if (a !== this) { ++ for (; i < a.length; i++) { ++ this.words[i] = a.words[i]; ++ } ++ } ++ ++ return this; ++ }; ++ ++ // Add `num` to `this` ++ BN.prototype.add = function add (num) { ++ var res; ++ if (num.negative !== 0 && this.negative === 0) { ++ num.negative = 0; ++ res = this.sub(num); ++ num.negative ^= 1; ++ return res; ++ } else if (num.negative === 0 && this.negative !== 0) { ++ this.negative = 0; ++ res = num.sub(this); ++ this.negative = 1; ++ return res; ++ } ++ ++ if (this.length > num.length) return this.clone().iadd(num); ++ ++ return num.clone().iadd(this); ++ }; ++ ++ // Subtract `num` from `this` in-place ++ BN.prototype.isub = function isub (num) { ++ // this - (-num) = this + num ++ if (num.negative !== 0) { ++ num.negative = 0; ++ var r = this.iadd(num); ++ num.negative = 1; ++ return r._normSign(); ++ ++ // -this - num = -(this + num) ++ } else if (this.negative !== 0) { ++ this.negative = 0; ++ this.iadd(num); ++ this.negative = 1; ++ return this._normSign(); ++ } ++ ++ // At this point both numbers are positive ++ var cmp = this.cmp(num); ++ ++ // Optimization - zeroify ++ if (cmp === 0) { ++ this.negative = 0; ++ this.length = 1; ++ this.words[0] = 0; ++ return this; ++ } ++ ++ // a > b ++ var a, b; ++ if (cmp > 0) { ++ a = this; ++ b = num; ++ } else { ++ a = num; ++ b = this; ++ } ++ ++ var carry = 0; ++ for (var i = 0; i < b.length; i++) { ++ r = (a.words[i] | 0) - (b.words[i] | 0) + carry; ++ carry = r >> 26; ++ this.words[i] = r & 0x3ffffff; ++ } ++ for (; carry !== 0 && i < a.length; i++) { ++ r = (a.words[i] | 0) + carry; ++ carry = r >> 26; ++ this.words[i] = r & 0x3ffffff; ++ } ++ ++ // Copy rest of the words ++ if (carry === 0 && i < a.length && a !== this) { ++ for (; i < a.length; i++) { ++ this.words[i] = a.words[i]; ++ } ++ } ++ ++ this.length = Math.max(this.length, i); ++ ++ if (a !== this) { ++ this.negative = 1; ++ } ++ ++ return this.strip(); ++ }; ++ ++ // Subtract `num` from `this` ++ BN.prototype.sub = function sub (num) { ++ return this.clone().isub(num); ++ }; ++ ++ function smallMulTo (self, num, out) { ++ out.negative = num.negative ^ self.negative; ++ var len = (self.length + num.length) | 0; ++ out.length = len; ++ len = (len - 1) | 0; ++ ++ // Peel one iteration (compiler can't do it, because of code complexity) ++ var a = self.words[0] | 0; ++ var b = num.words[0] | 0; ++ var r = a * b; ++ ++ var lo = r & 0x3ffffff; ++ var carry = (r / 0x4000000) | 0; ++ out.words[0] = lo; ++ ++ for (var k = 1; k < len; k++) { ++ // Sum all words with the same `i + j = k` and accumulate `ncarry`, ++ // note that ncarry could be >= 0x3ffffff ++ var ncarry = carry >>> 26; ++ var rword = carry & 0x3ffffff; ++ var maxJ = Math.min(k, num.length - 1); ++ for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) { ++ var i = (k - j) | 0; ++ a = self.words[i] | 0; ++ b = num.words[j] | 0; ++ r = a * b + rword; ++ ncarry += (r / 0x4000000) | 0; ++ rword = r & 0x3ffffff; ++ } ++ out.words[k] = rword | 0; ++ carry = ncarry | 0; ++ } ++ if (carry !== 0) { ++ out.words[k] = carry | 0; ++ } else { ++ out.length--; ++ } ++ ++ return out.strip(); ++ } ++ ++ // TODO(indutny): it may be reasonable to omit it for users who don't need ++ // to work with 256-bit numbers, otherwise it gives 20% improvement for 256-bit ++ // multiplication (like elliptic secp256k1). ++ var comb10MulTo = function comb10MulTo (self, num, out) { ++ var a = self.words; ++ var b = num.words; ++ var o = out.words; ++ var c = 0; ++ var lo; ++ var mid; ++ var hi; ++ var a0 = a[0] | 0; ++ var al0 = a0 & 0x1fff; ++ var ah0 = a0 >>> 13; ++ var a1 = a[1] | 0; ++ var al1 = a1 & 0x1fff; ++ var ah1 = a1 >>> 13; ++ var a2 = a[2] | 0; ++ var al2 = a2 & 0x1fff; ++ var ah2 = a2 >>> 13; ++ var a3 = a[3] | 0; ++ var al3 = a3 & 0x1fff; ++ var ah3 = a3 >>> 13; ++ var a4 = a[4] | 0; ++ var al4 = a4 & 0x1fff; ++ var ah4 = a4 >>> 13; ++ var a5 = a[5] | 0; ++ var al5 = a5 & 0x1fff; ++ var ah5 = a5 >>> 13; ++ var a6 = a[6] | 0; ++ var al6 = a6 & 0x1fff; ++ var ah6 = a6 >>> 13; ++ var a7 = a[7] | 0; ++ var al7 = a7 & 0x1fff; ++ var ah7 = a7 >>> 13; ++ var a8 = a[8] | 0; ++ var al8 = a8 & 0x1fff; ++ var ah8 = a8 >>> 13; ++ var a9 = a[9] | 0; ++ var al9 = a9 & 0x1fff; ++ var ah9 = a9 >>> 13; ++ var b0 = b[0] | 0; ++ var bl0 = b0 & 0x1fff; ++ var bh0 = b0 >>> 13; ++ var b1 = b[1] | 0; ++ var bl1 = b1 & 0x1fff; ++ var bh1 = b1 >>> 13; ++ var b2 = b[2] | 0; ++ var bl2 = b2 & 0x1fff; ++ var bh2 = b2 >>> 13; ++ var b3 = b[3] | 0; ++ var bl3 = b3 & 0x1fff; ++ var bh3 = b3 >>> 13; ++ var b4 = b[4] | 0; ++ var bl4 = b4 & 0x1fff; ++ var bh4 = b4 >>> 13; ++ var b5 = b[5] | 0; ++ var bl5 = b5 & 0x1fff; ++ var bh5 = b5 >>> 13; ++ var b6 = b[6] | 0; ++ var bl6 = b6 & 0x1fff; ++ var bh6 = b6 >>> 13; ++ var b7 = b[7] | 0; ++ var bl7 = b7 & 0x1fff; ++ var bh7 = b7 >>> 13; ++ var b8 = b[8] | 0; ++ var bl8 = b8 & 0x1fff; ++ var bh8 = b8 >>> 13; ++ var b9 = b[9] | 0; ++ var bl9 = b9 & 0x1fff; ++ var bh9 = b9 >>> 13; ++ ++ out.negative = self.negative ^ num.negative; ++ out.length = 19; ++ /* k = 0 */ ++ lo = Math.imul(al0, bl0); ++ mid = Math.imul(al0, bh0); ++ mid = (mid + Math.imul(ah0, bl0)) | 0; ++ hi = Math.imul(ah0, bh0); ++ var w0 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; ++ c = (((hi + (mid >>> 13)) | 0) + (w0 >>> 26)) | 0; ++ w0 &= 0x3ffffff; ++ /* k = 1 */ ++ lo = Math.imul(al1, bl0); ++ mid = Math.imul(al1, bh0); ++ mid = (mid + Math.imul(ah1, bl0)) | 0; ++ hi = Math.imul(ah1, bh0); ++ lo = (lo + Math.imul(al0, bl1)) | 0; ++ mid = (mid + Math.imul(al0, bh1)) | 0; ++ mid = (mid + Math.imul(ah0, bl1)) | 0; ++ hi = (hi + Math.imul(ah0, bh1)) | 0; ++ var w1 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; ++ c = (((hi + (mid >>> 13)) | 0) + (w1 >>> 26)) | 0; ++ w1 &= 0x3ffffff; ++ /* k = 2 */ ++ lo = Math.imul(al2, bl0); ++ mid = Math.imul(al2, bh0); ++ mid = (mid + Math.imul(ah2, bl0)) | 0; ++ hi = Math.imul(ah2, bh0); ++ lo = (lo + Math.imul(al1, bl1)) | 0; ++ mid = (mid + Math.imul(al1, bh1)) | 0; ++ mid = (mid + Math.imul(ah1, bl1)) | 0; ++ hi = (hi + Math.imul(ah1, bh1)) | 0; ++ lo = (lo + Math.imul(al0, bl2)) | 0; ++ mid = (mid + Math.imul(al0, bh2)) | 0; ++ mid = (mid + Math.imul(ah0, bl2)) | 0; ++ hi = (hi + Math.imul(ah0, bh2)) | 0; ++ var w2 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; ++ c = (((hi + (mid >>> 13)) | 0) + (w2 >>> 26)) | 0; ++ w2 &= 0x3ffffff; ++ /* k = 3 */ ++ lo = Math.imul(al3, bl0); ++ mid = Math.imul(al3, bh0); ++ mid = (mid + Math.imul(ah3, bl0)) | 0; ++ hi = Math.imul(ah3, bh0); ++ lo = (lo + Math.imul(al2, bl1)) | 0; ++ mid = (mid + Math.imul(al2, bh1)) | 0; ++ mid = (mid + Math.imul(ah2, bl1)) | 0; ++ hi = (hi + Math.imul(ah2, bh1)) | 0; ++ lo = (lo + Math.imul(al1, bl2)) | 0; ++ mid = (mid + Math.imul(al1, bh2)) | 0; ++ mid = (mid + Math.imul(ah1, bl2)) | 0; ++ hi = (hi + Math.imul(ah1, bh2)) | 0; ++ lo = (lo + Math.imul(al0, bl3)) | 0; ++ mid = (mid + Math.imul(al0, bh3)) | 0; ++ mid = (mid + Math.imul(ah0, bl3)) | 0; ++ hi = (hi + Math.imul(ah0, bh3)) | 0; ++ var w3 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; ++ c = (((hi + (mid >>> 13)) | 0) + (w3 >>> 26)) | 0; ++ w3 &= 0x3ffffff; ++ /* k = 4 */ ++ lo = Math.imul(al4, bl0); ++ mid = Math.imul(al4, bh0); ++ mid = (mid + Math.imul(ah4, bl0)) | 0; ++ hi = Math.imul(ah4, bh0); ++ lo = (lo + Math.imul(al3, bl1)) | 0; ++ mid = (mid + Math.imul(al3, bh1)) | 0; ++ mid = (mid + Math.imul(ah3, bl1)) | 0; ++ hi = (hi + Math.imul(ah3, bh1)) | 0; ++ lo = (lo + Math.imul(al2, bl2)) | 0; ++ mid = (mid + Math.imul(al2, bh2)) | 0; ++ mid = (mid + Math.imul(ah2, bl2)) | 0; ++ hi = (hi + Math.imul(ah2, bh2)) | 0; ++ lo = (lo + Math.imul(al1, bl3)) | 0; ++ mid = (mid + Math.imul(al1, bh3)) | 0; ++ mid = (mid + Math.imul(ah1, bl3)) | 0; ++ hi = (hi + Math.imul(ah1, bh3)) | 0; ++ lo = (lo + Math.imul(al0, bl4)) | 0; ++ mid = (mid + Math.imul(al0, bh4)) | 0; ++ mid = (mid + Math.imul(ah0, bl4)) | 0; ++ hi = (hi + Math.imul(ah0, bh4)) | 0; ++ var w4 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; ++ c = (((hi + (mid >>> 13)) | 0) + (w4 >>> 26)) | 0; ++ w4 &= 0x3ffffff; ++ /* k = 5 */ ++ lo = Math.imul(al5, bl0); ++ mid = Math.imul(al5, bh0); ++ mid = (mid + Math.imul(ah5, bl0)) | 0; ++ hi = Math.imul(ah5, bh0); ++ lo = (lo + Math.imul(al4, bl1)) | 0; ++ mid = (mid + Math.imul(al4, bh1)) | 0; ++ mid = (mid + Math.imul(ah4, bl1)) | 0; ++ hi = (hi + Math.imul(ah4, bh1)) | 0; ++ lo = (lo + Math.imul(al3, bl2)) | 0; ++ mid = (mid + Math.imul(al3, bh2)) | 0; ++ mid = (mid + Math.imul(ah3, bl2)) | 0; ++ hi = (hi + Math.imul(ah3, bh2)) | 0; ++ lo = (lo + Math.imul(al2, bl3)) | 0; ++ mid = (mid + Math.imul(al2, bh3)) | 0; ++ mid = (mid + Math.imul(ah2, bl3)) | 0; ++ hi = (hi + Math.imul(ah2, bh3)) | 0; ++ lo = (lo + Math.imul(al1, bl4)) | 0; ++ mid = (mid + Math.imul(al1, bh4)) | 0; ++ mid = (mid + Math.imul(ah1, bl4)) | 0; ++ hi = (hi + Math.imul(ah1, bh4)) | 0; ++ lo = (lo + Math.imul(al0, bl5)) | 0; ++ mid = (mid + Math.imul(al0, bh5)) | 0; ++ mid = (mid + Math.imul(ah0, bl5)) | 0; ++ hi = (hi + Math.imul(ah0, bh5)) | 0; ++ var w5 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; ++ c = (((hi + (mid >>> 13)) | 0) + (w5 >>> 26)) | 0; ++ w5 &= 0x3ffffff; ++ /* k = 6 */ ++ lo = Math.imul(al6, bl0); ++ mid = Math.imul(al6, bh0); ++ mid = (mid + Math.imul(ah6, bl0)) | 0; ++ hi = Math.imul(ah6, bh0); ++ lo = (lo + Math.imul(al5, bl1)) | 0; ++ mid = (mid + Math.imul(al5, bh1)) | 0; ++ mid = (mid + Math.imul(ah5, bl1)) | 0; ++ hi = (hi + Math.imul(ah5, bh1)) | 0; ++ lo = (lo + Math.imul(al4, bl2)) | 0; ++ mid = (mid + Math.imul(al4, bh2)) | 0; ++ mid = (mid + Math.imul(ah4, bl2)) | 0; ++ hi = (hi + Math.imul(ah4, bh2)) | 0; ++ lo = (lo + Math.imul(al3, bl3)) | 0; ++ mid = (mid + Math.imul(al3, bh3)) | 0; ++ mid = (mid + Math.imul(ah3, bl3)) | 0; ++ hi = (hi + Math.imul(ah3, bh3)) | 0; ++ lo = (lo + Math.imul(al2, bl4)) | 0; ++ mid = (mid + Math.imul(al2, bh4)) | 0; ++ mid = (mid + Math.imul(ah2, bl4)) | 0; ++ hi = (hi + Math.imul(ah2, bh4)) | 0; ++ lo = (lo + Math.imul(al1, bl5)) | 0; ++ mid = (mid + Math.imul(al1, bh5)) | 0; ++ mid = (mid + Math.imul(ah1, bl5)) | 0; ++ hi = (hi + Math.imul(ah1, bh5)) | 0; ++ lo = (lo + Math.imul(al0, bl6)) | 0; ++ mid = (mid + Math.imul(al0, bh6)) | 0; ++ mid = (mid + Math.imul(ah0, bl6)) | 0; ++ hi = (hi + Math.imul(ah0, bh6)) | 0; ++ var w6 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; ++ c = (((hi + (mid >>> 13)) | 0) + (w6 >>> 26)) | 0; ++ w6 &= 0x3ffffff; ++ /* k = 7 */ ++ lo = Math.imul(al7, bl0); ++ mid = Math.imul(al7, bh0); ++ mid = (mid + Math.imul(ah7, bl0)) | 0; ++ hi = Math.imul(ah7, bh0); ++ lo = (lo + Math.imul(al6, bl1)) | 0; ++ mid = (mid + Math.imul(al6, bh1)) | 0; ++ mid = (mid + Math.imul(ah6, bl1)) | 0; ++ hi = (hi + Math.imul(ah6, bh1)) | 0; ++ lo = (lo + Math.imul(al5, bl2)) | 0; ++ mid = (mid + Math.imul(al5, bh2)) | 0; ++ mid = (mid + Math.imul(ah5, bl2)) | 0; ++ hi = (hi + Math.imul(ah5, bh2)) | 0; ++ lo = (lo + Math.imul(al4, bl3)) | 0; ++ mid = (mid + Math.imul(al4, bh3)) | 0; ++ mid = (mid + Math.imul(ah4, bl3)) | 0; ++ hi = (hi + Math.imul(ah4, bh3)) | 0; ++ lo = (lo + Math.imul(al3, bl4)) | 0; ++ mid = (mid + Math.imul(al3, bh4)) | 0; ++ mid = (mid + Math.imul(ah3, bl4)) | 0; ++ hi = (hi + Math.imul(ah3, bh4)) | 0; ++ lo = (lo + Math.imul(al2, bl5)) | 0; ++ mid = (mid + Math.imul(al2, bh5)) | 0; ++ mid = (mid + Math.imul(ah2, bl5)) | 0; ++ hi = (hi + Math.imul(ah2, bh5)) | 0; ++ lo = (lo + Math.imul(al1, bl6)) | 0; ++ mid = (mid + Math.imul(al1, bh6)) | 0; ++ mid = (mid + Math.imul(ah1, bl6)) | 0; ++ hi = (hi + Math.imul(ah1, bh6)) | 0; ++ lo = (lo + Math.imul(al0, bl7)) | 0; ++ mid = (mid + Math.imul(al0, bh7)) | 0; ++ mid = (mid + Math.imul(ah0, bl7)) | 0; ++ hi = (hi + Math.imul(ah0, bh7)) | 0; ++ var w7 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; ++ c = (((hi + (mid >>> 13)) | 0) + (w7 >>> 26)) | 0; ++ w7 &= 0x3ffffff; ++ /* k = 8 */ ++ lo = Math.imul(al8, bl0); ++ mid = Math.imul(al8, bh0); ++ mid = (mid + Math.imul(ah8, bl0)) | 0; ++ hi = Math.imul(ah8, bh0); ++ lo = (lo + Math.imul(al7, bl1)) | 0; ++ mid = (mid + Math.imul(al7, bh1)) | 0; ++ mid = (mid + Math.imul(ah7, bl1)) | 0; ++ hi = (hi + Math.imul(ah7, bh1)) | 0; ++ lo = (lo + Math.imul(al6, bl2)) | 0; ++ mid = (mid + Math.imul(al6, bh2)) | 0; ++ mid = (mid + Math.imul(ah6, bl2)) | 0; ++ hi = (hi + Math.imul(ah6, bh2)) | 0; ++ lo = (lo + Math.imul(al5, bl3)) | 0; ++ mid = (mid + Math.imul(al5, bh3)) | 0; ++ mid = (mid + Math.imul(ah5, bl3)) | 0; ++ hi = (hi + Math.imul(ah5, bh3)) | 0; ++ lo = (lo + Math.imul(al4, bl4)) | 0; ++ mid = (mid + Math.imul(al4, bh4)) | 0; ++ mid = (mid + Math.imul(ah4, bl4)) | 0; ++ hi = (hi + Math.imul(ah4, bh4)) | 0; ++ lo = (lo + Math.imul(al3, bl5)) | 0; ++ mid = (mid + Math.imul(al3, bh5)) | 0; ++ mid = (mid + Math.imul(ah3, bl5)) | 0; ++ hi = (hi + Math.imul(ah3, bh5)) | 0; ++ lo = (lo + Math.imul(al2, bl6)) | 0; ++ mid = (mid + Math.imul(al2, bh6)) | 0; ++ mid = (mid + Math.imul(ah2, bl6)) | 0; ++ hi = (hi + Math.imul(ah2, bh6)) | 0; ++ lo = (lo + Math.imul(al1, bl7)) | 0; ++ mid = (mid + Math.imul(al1, bh7)) | 0; ++ mid = (mid + Math.imul(ah1, bl7)) | 0; ++ hi = (hi + Math.imul(ah1, bh7)) | 0; ++ lo = (lo + Math.imul(al0, bl8)) | 0; ++ mid = (mid + Math.imul(al0, bh8)) | 0; ++ mid = (mid + Math.imul(ah0, bl8)) | 0; ++ hi = (hi + Math.imul(ah0, bh8)) | 0; ++ var w8 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; ++ c = (((hi + (mid >>> 13)) | 0) + (w8 >>> 26)) | 0; ++ w8 &= 0x3ffffff; ++ /* k = 9 */ ++ lo = Math.imul(al9, bl0); ++ mid = Math.imul(al9, bh0); ++ mid = (mid + Math.imul(ah9, bl0)) | 0; ++ hi = Math.imul(ah9, bh0); ++ lo = (lo + Math.imul(al8, bl1)) | 0; ++ mid = (mid + Math.imul(al8, bh1)) | 0; ++ mid = (mid + Math.imul(ah8, bl1)) | 0; ++ hi = (hi + Math.imul(ah8, bh1)) | 0; ++ lo = (lo + Math.imul(al7, bl2)) | 0; ++ mid = (mid + Math.imul(al7, bh2)) | 0; ++ mid = (mid + Math.imul(ah7, bl2)) | 0; ++ hi = (hi + Math.imul(ah7, bh2)) | 0; ++ lo = (lo + Math.imul(al6, bl3)) | 0; ++ mid = (mid + Math.imul(al6, bh3)) | 0; ++ mid = (mid + Math.imul(ah6, bl3)) | 0; ++ hi = (hi + Math.imul(ah6, bh3)) | 0; ++ lo = (lo + Math.imul(al5, bl4)) | 0; ++ mid = (mid + Math.imul(al5, bh4)) | 0; ++ mid = (mid + Math.imul(ah5, bl4)) | 0; ++ hi = (hi + Math.imul(ah5, bh4)) | 0; ++ lo = (lo + Math.imul(al4, bl5)) | 0; ++ mid = (mid + Math.imul(al4, bh5)) | 0; ++ mid = (mid + Math.imul(ah4, bl5)) | 0; ++ hi = (hi + Math.imul(ah4, bh5)) | 0; ++ lo = (lo + Math.imul(al3, bl6)) | 0; ++ mid = (mid + Math.imul(al3, bh6)) | 0; ++ mid = (mid + Math.imul(ah3, bl6)) | 0; ++ hi = (hi + Math.imul(ah3, bh6)) | 0; ++ lo = (lo + Math.imul(al2, bl7)) | 0; ++ mid = (mid + Math.imul(al2, bh7)) | 0; ++ mid = (mid + Math.imul(ah2, bl7)) | 0; ++ hi = (hi + Math.imul(ah2, bh7)) | 0; ++ lo = (lo + Math.imul(al1, bl8)) | 0; ++ mid = (mid + Math.imul(al1, bh8)) | 0; ++ mid = (mid + Math.imul(ah1, bl8)) | 0; ++ hi = (hi + Math.imul(ah1, bh8)) | 0; ++ lo = (lo + Math.imul(al0, bl9)) | 0; ++ mid = (mid + Math.imul(al0, bh9)) | 0; ++ mid = (mid + Math.imul(ah0, bl9)) | 0; ++ hi = (hi + Math.imul(ah0, bh9)) | 0; ++ var w9 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; ++ c = (((hi + (mid >>> 13)) | 0) + (w9 >>> 26)) | 0; ++ w9 &= 0x3ffffff; ++ /* k = 10 */ ++ lo = Math.imul(al9, bl1); ++ mid = Math.imul(al9, bh1); ++ mid = (mid + Math.imul(ah9, bl1)) | 0; ++ hi = Math.imul(ah9, bh1); ++ lo = (lo + Math.imul(al8, bl2)) | 0; ++ mid = (mid + Math.imul(al8, bh2)) | 0; ++ mid = (mid + Math.imul(ah8, bl2)) | 0; ++ hi = (hi + Math.imul(ah8, bh2)) | 0; ++ lo = (lo + Math.imul(al7, bl3)) | 0; ++ mid = (mid + Math.imul(al7, bh3)) | 0; ++ mid = (mid + Math.imul(ah7, bl3)) | 0; ++ hi = (hi + Math.imul(ah7, bh3)) | 0; ++ lo = (lo + Math.imul(al6, bl4)) | 0; ++ mid = (mid + Math.imul(al6, bh4)) | 0; ++ mid = (mid + Math.imul(ah6, bl4)) | 0; ++ hi = (hi + Math.imul(ah6, bh4)) | 0; ++ lo = (lo + Math.imul(al5, bl5)) | 0; ++ mid = (mid + Math.imul(al5, bh5)) | 0; ++ mid = (mid + Math.imul(ah5, bl5)) | 0; ++ hi = (hi + Math.imul(ah5, bh5)) | 0; ++ lo = (lo + Math.imul(al4, bl6)) | 0; ++ mid = (mid + Math.imul(al4, bh6)) | 0; ++ mid = (mid + Math.imul(ah4, bl6)) | 0; ++ hi = (hi + Math.imul(ah4, bh6)) | 0; ++ lo = (lo + Math.imul(al3, bl7)) | 0; ++ mid = (mid + Math.imul(al3, bh7)) | 0; ++ mid = (mid + Math.imul(ah3, bl7)) | 0; ++ hi = (hi + Math.imul(ah3, bh7)) | 0; ++ lo = (lo + Math.imul(al2, bl8)) | 0; ++ mid = (mid + Math.imul(al2, bh8)) | 0; ++ mid = (mid + Math.imul(ah2, bl8)) | 0; ++ hi = (hi + Math.imul(ah2, bh8)) | 0; ++ lo = (lo + Math.imul(al1, bl9)) | 0; ++ mid = (mid + Math.imul(al1, bh9)) | 0; ++ mid = (mid + Math.imul(ah1, bl9)) | 0; ++ hi = (hi + Math.imul(ah1, bh9)) | 0; ++ var w10 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; ++ c = (((hi + (mid >>> 13)) | 0) + (w10 >>> 26)) | 0; ++ w10 &= 0x3ffffff; ++ /* k = 11 */ ++ lo = Math.imul(al9, bl2); ++ mid = Math.imul(al9, bh2); ++ mid = (mid + Math.imul(ah9, bl2)) | 0; ++ hi = Math.imul(ah9, bh2); ++ lo = (lo + Math.imul(al8, bl3)) | 0; ++ mid = (mid + Math.imul(al8, bh3)) | 0; ++ mid = (mid + Math.imul(ah8, bl3)) | 0; ++ hi = (hi + Math.imul(ah8, bh3)) | 0; ++ lo = (lo + Math.imul(al7, bl4)) | 0; ++ mid = (mid + Math.imul(al7, bh4)) | 0; ++ mid = (mid + Math.imul(ah7, bl4)) | 0; ++ hi = (hi + Math.imul(ah7, bh4)) | 0; ++ lo = (lo + Math.imul(al6, bl5)) | 0; ++ mid = (mid + Math.imul(al6, bh5)) | 0; ++ mid = (mid + Math.imul(ah6, bl5)) | 0; ++ hi = (hi + Math.imul(ah6, bh5)) | 0; ++ lo = (lo + Math.imul(al5, bl6)) | 0; ++ mid = (mid + Math.imul(al5, bh6)) | 0; ++ mid = (mid + Math.imul(ah5, bl6)) | 0; ++ hi = (hi + Math.imul(ah5, bh6)) | 0; ++ lo = (lo + Math.imul(al4, bl7)) | 0; ++ mid = (mid + Math.imul(al4, bh7)) | 0; ++ mid = (mid + Math.imul(ah4, bl7)) | 0; ++ hi = (hi + Math.imul(ah4, bh7)) | 0; ++ lo = (lo + Math.imul(al3, bl8)) | 0; ++ mid = (mid + Math.imul(al3, bh8)) | 0; ++ mid = (mid + Math.imul(ah3, bl8)) | 0; ++ hi = (hi + Math.imul(ah3, bh8)) | 0; ++ lo = (lo + Math.imul(al2, bl9)) | 0; ++ mid = (mid + Math.imul(al2, bh9)) | 0; ++ mid = (mid + Math.imul(ah2, bl9)) | 0; ++ hi = (hi + Math.imul(ah2, bh9)) | 0; ++ var w11 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; ++ c = (((hi + (mid >>> 13)) | 0) + (w11 >>> 26)) | 0; ++ w11 &= 0x3ffffff; ++ /* k = 12 */ ++ lo = Math.imul(al9, bl3); ++ mid = Math.imul(al9, bh3); ++ mid = (mid + Math.imul(ah9, bl3)) | 0; ++ hi = Math.imul(ah9, bh3); ++ lo = (lo + Math.imul(al8, bl4)) | 0; ++ mid = (mid + Math.imul(al8, bh4)) | 0; ++ mid = (mid + Math.imul(ah8, bl4)) | 0; ++ hi = (hi + Math.imul(ah8, bh4)) | 0; ++ lo = (lo + Math.imul(al7, bl5)) | 0; ++ mid = (mid + Math.imul(al7, bh5)) | 0; ++ mid = (mid + Math.imul(ah7, bl5)) | 0; ++ hi = (hi + Math.imul(ah7, bh5)) | 0; ++ lo = (lo + Math.imul(al6, bl6)) | 0; ++ mid = (mid + Math.imul(al6, bh6)) | 0; ++ mid = (mid + Math.imul(ah6, bl6)) | 0; ++ hi = (hi + Math.imul(ah6, bh6)) | 0; ++ lo = (lo + Math.imul(al5, bl7)) | 0; ++ mid = (mid + Math.imul(al5, bh7)) | 0; ++ mid = (mid + Math.imul(ah5, bl7)) | 0; ++ hi = (hi + Math.imul(ah5, bh7)) | 0; ++ lo = (lo + Math.imul(al4, bl8)) | 0; ++ mid = (mid + Math.imul(al4, bh8)) | 0; ++ mid = (mid + Math.imul(ah4, bl8)) | 0; ++ hi = (hi + Math.imul(ah4, bh8)) | 0; ++ lo = (lo + Math.imul(al3, bl9)) | 0; ++ mid = (mid + Math.imul(al3, bh9)) | 0; ++ mid = (mid + Math.imul(ah3, bl9)) | 0; ++ hi = (hi + Math.imul(ah3, bh9)) | 0; ++ var w12 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; ++ c = (((hi + (mid >>> 13)) | 0) + (w12 >>> 26)) | 0; ++ w12 &= 0x3ffffff; ++ /* k = 13 */ ++ lo = Math.imul(al9, bl4); ++ mid = Math.imul(al9, bh4); ++ mid = (mid + Math.imul(ah9, bl4)) | 0; ++ hi = Math.imul(ah9, bh4); ++ lo = (lo + Math.imul(al8, bl5)) | 0; ++ mid = (mid + Math.imul(al8, bh5)) | 0; ++ mid = (mid + Math.imul(ah8, bl5)) | 0; ++ hi = (hi + Math.imul(ah8, bh5)) | 0; ++ lo = (lo + Math.imul(al7, bl6)) | 0; ++ mid = (mid + Math.imul(al7, bh6)) | 0; ++ mid = (mid + Math.imul(ah7, bl6)) | 0; ++ hi = (hi + Math.imul(ah7, bh6)) | 0; ++ lo = (lo + Math.imul(al6, bl7)) | 0; ++ mid = (mid + Math.imul(al6, bh7)) | 0; ++ mid = (mid + Math.imul(ah6, bl7)) | 0; ++ hi = (hi + Math.imul(ah6, bh7)) | 0; ++ lo = (lo + Math.imul(al5, bl8)) | 0; ++ mid = (mid + Math.imul(al5, bh8)) | 0; ++ mid = (mid + Math.imul(ah5, bl8)) | 0; ++ hi = (hi + Math.imul(ah5, bh8)) | 0; ++ lo = (lo + Math.imul(al4, bl9)) | 0; ++ mid = (mid + Math.imul(al4, bh9)) | 0; ++ mid = (mid + Math.imul(ah4, bl9)) | 0; ++ hi = (hi + Math.imul(ah4, bh9)) | 0; ++ var w13 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; ++ c = (((hi + (mid >>> 13)) | 0) + (w13 >>> 26)) | 0; ++ w13 &= 0x3ffffff; ++ /* k = 14 */ ++ lo = Math.imul(al9, bl5); ++ mid = Math.imul(al9, bh5); ++ mid = (mid + Math.imul(ah9, bl5)) | 0; ++ hi = Math.imul(ah9, bh5); ++ lo = (lo + Math.imul(al8, bl6)) | 0; ++ mid = (mid + Math.imul(al8, bh6)) | 0; ++ mid = (mid + Math.imul(ah8, bl6)) | 0; ++ hi = (hi + Math.imul(ah8, bh6)) | 0; ++ lo = (lo + Math.imul(al7, bl7)) | 0; ++ mid = (mid + Math.imul(al7, bh7)) | 0; ++ mid = (mid + Math.imul(ah7, bl7)) | 0; ++ hi = (hi + Math.imul(ah7, bh7)) | 0; ++ lo = (lo + Math.imul(al6, bl8)) | 0; ++ mid = (mid + Math.imul(al6, bh8)) | 0; ++ mid = (mid + Math.imul(ah6, bl8)) | 0; ++ hi = (hi + Math.imul(ah6, bh8)) | 0; ++ lo = (lo + Math.imul(al5, bl9)) | 0; ++ mid = (mid + Math.imul(al5, bh9)) | 0; ++ mid = (mid + Math.imul(ah5, bl9)) | 0; ++ hi = (hi + Math.imul(ah5, bh9)) | 0; ++ var w14 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; ++ c = (((hi + (mid >>> 13)) | 0) + (w14 >>> 26)) | 0; ++ w14 &= 0x3ffffff; ++ /* k = 15 */ ++ lo = Math.imul(al9, bl6); ++ mid = Math.imul(al9, bh6); ++ mid = (mid + Math.imul(ah9, bl6)) | 0; ++ hi = Math.imul(ah9, bh6); ++ lo = (lo + Math.imul(al8, bl7)) | 0; ++ mid = (mid + Math.imul(al8, bh7)) | 0; ++ mid = (mid + Math.imul(ah8, bl7)) | 0; ++ hi = (hi + Math.imul(ah8, bh7)) | 0; ++ lo = (lo + Math.imul(al7, bl8)) | 0; ++ mid = (mid + Math.imul(al7, bh8)) | 0; ++ mid = (mid + Math.imul(ah7, bl8)) | 0; ++ hi = (hi + Math.imul(ah7, bh8)) | 0; ++ lo = (lo + Math.imul(al6, bl9)) | 0; ++ mid = (mid + Math.imul(al6, bh9)) | 0; ++ mid = (mid + Math.imul(ah6, bl9)) | 0; ++ hi = (hi + Math.imul(ah6, bh9)) | 0; ++ var w15 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; ++ c = (((hi + (mid >>> 13)) | 0) + (w15 >>> 26)) | 0; ++ w15 &= 0x3ffffff; ++ /* k = 16 */ ++ lo = Math.imul(al9, bl7); ++ mid = Math.imul(al9, bh7); ++ mid = (mid + Math.imul(ah9, bl7)) | 0; ++ hi = Math.imul(ah9, bh7); ++ lo = (lo + Math.imul(al8, bl8)) | 0; ++ mid = (mid + Math.imul(al8, bh8)) | 0; ++ mid = (mid + Math.imul(ah8, bl8)) | 0; ++ hi = (hi + Math.imul(ah8, bh8)) | 0; ++ lo = (lo + Math.imul(al7, bl9)) | 0; ++ mid = (mid + Math.imul(al7, bh9)) | 0; ++ mid = (mid + Math.imul(ah7, bl9)) | 0; ++ hi = (hi + Math.imul(ah7, bh9)) | 0; ++ var w16 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; ++ c = (((hi + (mid >>> 13)) | 0) + (w16 >>> 26)) | 0; ++ w16 &= 0x3ffffff; ++ /* k = 17 */ ++ lo = Math.imul(al9, bl8); ++ mid = Math.imul(al9, bh8); ++ mid = (mid + Math.imul(ah9, bl8)) | 0; ++ hi = Math.imul(ah9, bh8); ++ lo = (lo + Math.imul(al8, bl9)) | 0; ++ mid = (mid + Math.imul(al8, bh9)) | 0; ++ mid = (mid + Math.imul(ah8, bl9)) | 0; ++ hi = (hi + Math.imul(ah8, bh9)) | 0; ++ var w17 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; ++ c = (((hi + (mid >>> 13)) | 0) + (w17 >>> 26)) | 0; ++ w17 &= 0x3ffffff; ++ /* k = 18 */ ++ lo = Math.imul(al9, bl9); ++ mid = Math.imul(al9, bh9); ++ mid = (mid + Math.imul(ah9, bl9)) | 0; ++ hi = Math.imul(ah9, bh9); ++ var w18 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; ++ c = (((hi + (mid >>> 13)) | 0) + (w18 >>> 26)) | 0; ++ w18 &= 0x3ffffff; ++ o[0] = w0; ++ o[1] = w1; ++ o[2] = w2; ++ o[3] = w3; ++ o[4] = w4; ++ o[5] = w5; ++ o[6] = w6; ++ o[7] = w7; ++ o[8] = w8; ++ o[9] = w9; ++ o[10] = w10; ++ o[11] = w11; ++ o[12] = w12; ++ o[13] = w13; ++ o[14] = w14; ++ o[15] = w15; ++ o[16] = w16; ++ o[17] = w17; ++ o[18] = w18; ++ if (c !== 0) { ++ o[19] = c; ++ out.length++; ++ } ++ return out; ++ }; ++ ++ // Polyfill comb ++ if (!Math.imul) { ++ comb10MulTo = smallMulTo; ++ } ++ ++ function bigMulTo (self, num, out) { ++ out.negative = num.negative ^ self.negative; ++ out.length = self.length + num.length; ++ ++ var carry = 0; ++ var hncarry = 0; ++ for (var k = 0; k < out.length - 1; k++) { ++ // Sum all words with the same `i + j = k` and accumulate `ncarry`, ++ // note that ncarry could be >= 0x3ffffff ++ var ncarry = hncarry; ++ hncarry = 0; ++ var rword = carry & 0x3ffffff; ++ var maxJ = Math.min(k, num.length - 1); ++ for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) { ++ var i = k - j; ++ var a = self.words[i] | 0; ++ var b = num.words[j] | 0; ++ var r = a * b; ++ ++ var lo = r & 0x3ffffff; ++ ncarry = (ncarry + ((r / 0x4000000) | 0)) | 0; ++ lo = (lo + rword) | 0; ++ rword = lo & 0x3ffffff; ++ ncarry = (ncarry + (lo >>> 26)) | 0; ++ ++ hncarry += ncarry >>> 26; ++ ncarry &= 0x3ffffff; ++ } ++ out.words[k] = rword; ++ carry = ncarry; ++ ncarry = hncarry; ++ } ++ if (carry !== 0) { ++ out.words[k] = carry; ++ } else { ++ out.length--; ++ } ++ ++ return out.strip(); ++ } ++ ++ function jumboMulTo (self, num, out) { ++ var fftm = new FFTM(); ++ return fftm.mulp(self, num, out); ++ } ++ ++ BN.prototype.mulTo = function mulTo (num, out) { ++ var res; ++ var len = this.length + num.length; ++ if (this.length === 10 && num.length === 10) { ++ res = comb10MulTo(this, num, out); ++ } else if (len < 63) { ++ res = smallMulTo(this, num, out); ++ } else if (len < 1024) { ++ res = bigMulTo(this, num, out); ++ } else { ++ res = jumboMulTo(this, num, out); ++ } ++ ++ return res; ++ }; ++ ++ // Cooley-Tukey algorithm for FFT ++ // slightly revisited to rely on looping instead of recursion ++ ++ function FFTM (x, y) { ++ this.x = x; ++ this.y = y; ++ } ++ ++ FFTM.prototype.makeRBT = function makeRBT (N) { ++ var t = new Array(N); ++ var l = BN.prototype._countBits(N) - 1; ++ for (var i = 0; i < N; i++) { ++ t[i] = this.revBin(i, l, N); ++ } ++ ++ return t; ++ }; ++ ++ // Returns binary-reversed representation of `x` ++ FFTM.prototype.revBin = function revBin (x, l, N) { ++ if (x === 0 || x === N - 1) return x; ++ ++ var rb = 0; ++ for (var i = 0; i < l; i++) { ++ rb |= (x & 1) << (l - i - 1); ++ x >>= 1; ++ } ++ ++ return rb; ++ }; ++ ++ // Performs "tweedling" phase, therefore 'emulating' ++ // behaviour of the recursive algorithm ++ FFTM.prototype.permute = function permute (rbt, rws, iws, rtws, itws, N) { ++ for (var i = 0; i < N; i++) { ++ rtws[i] = rws[rbt[i]]; ++ itws[i] = iws[rbt[i]]; ++ } ++ }; ++ ++ FFTM.prototype.transform = function transform (rws, iws, rtws, itws, N, rbt) { ++ this.permute(rbt, rws, iws, rtws, itws, N); ++ ++ for (var s = 1; s < N; s <<= 1) { ++ var l = s << 1; ++ ++ var rtwdf = Math.cos(2 * Math.PI / l); ++ var itwdf = Math.sin(2 * Math.PI / l); ++ ++ for (var p = 0; p < N; p += l) { ++ var rtwdf_ = rtwdf; ++ var itwdf_ = itwdf; ++ ++ for (var j = 0; j < s; j++) { ++ var re = rtws[p + j]; ++ var ie = itws[p + j]; ++ ++ var ro = rtws[p + j + s]; ++ var io = itws[p + j + s]; ++ ++ var rx = rtwdf_ * ro - itwdf_ * io; ++ ++ io = rtwdf_ * io + itwdf_ * ro; ++ ro = rx; ++ ++ rtws[p + j] = re + ro; ++ itws[p + j] = ie + io; ++ ++ rtws[p + j + s] = re - ro; ++ itws[p + j + s] = ie - io; ++ ++ /* jshint maxdepth : false */ ++ if (j !== l) { ++ rx = rtwdf * rtwdf_ - itwdf * itwdf_; ++ ++ itwdf_ = rtwdf * itwdf_ + itwdf * rtwdf_; ++ rtwdf_ = rx; ++ } ++ } ++ } ++ } ++ }; ++ ++ FFTM.prototype.guessLen13b = function guessLen13b (n, m) { ++ var N = Math.max(m, n) | 1; ++ var odd = N & 1; ++ var i = 0; ++ for (N = N / 2 | 0; N; N = N >>> 1) { ++ i++; ++ } ++ ++ return 1 << i + 1 + odd; ++ }; ++ ++ FFTM.prototype.conjugate = function conjugate (rws, iws, N) { ++ if (N <= 1) return; ++ ++ for (var i = 0; i < N / 2; i++) { ++ var t = rws[i]; ++ ++ rws[i] = rws[N - i - 1]; ++ rws[N - i - 1] = t; ++ ++ t = iws[i]; ++ ++ iws[i] = -iws[N - i - 1]; ++ iws[N - i - 1] = -t; ++ } ++ }; ++ ++ FFTM.prototype.normalize13b = function normalize13b (ws, N) { ++ var carry = 0; ++ for (var i = 0; i < N / 2; i++) { ++ var w = Math.round(ws[2 * i + 1] / N) * 0x2000 + ++ Math.round(ws[2 * i] / N) + ++ carry; ++ ++ ws[i] = w & 0x3ffffff; ++ ++ if (w < 0x4000000) { ++ carry = 0; ++ } else { ++ carry = w / 0x4000000 | 0; ++ } ++ } ++ ++ return ws; ++ }; ++ ++ FFTM.prototype.convert13b = function convert13b (ws, len, rws, N) { ++ var carry = 0; ++ for (var i = 0; i < len; i++) { ++ carry = carry + (ws[i] | 0); ++ ++ rws[2 * i] = carry & 0x1fff; carry = carry >>> 13; ++ rws[2 * i + 1] = carry & 0x1fff; carry = carry >>> 13; ++ } ++ ++ // Pad with zeroes ++ for (i = 2 * len; i < N; ++i) { ++ rws[i] = 0; ++ } ++ ++ assert(carry === 0); ++ assert((carry & ~0x1fff) === 0); ++ }; ++ ++ FFTM.prototype.stub = function stub (N) { ++ var ph = new Array(N); ++ for (var i = 0; i < N; i++) { ++ ph[i] = 0; ++ } ++ ++ return ph; ++ }; ++ ++ FFTM.prototype.mulp = function mulp (x, y, out) { ++ var N = 2 * this.guessLen13b(x.length, y.length); ++ ++ var rbt = this.makeRBT(N); ++ ++ var _ = this.stub(N); ++ ++ var rws = new Array(N); ++ var rwst = new Array(N); ++ var iwst = new Array(N); ++ ++ var nrws = new Array(N); ++ var nrwst = new Array(N); ++ var niwst = new Array(N); ++ ++ var rmws = out.words; ++ rmws.length = N; ++ ++ this.convert13b(x.words, x.length, rws, N); ++ this.convert13b(y.words, y.length, nrws, N); ++ ++ this.transform(rws, _, rwst, iwst, N, rbt); ++ this.transform(nrws, _, nrwst, niwst, N, rbt); ++ ++ for (var i = 0; i < N; i++) { ++ var rx = rwst[i] * nrwst[i] - iwst[i] * niwst[i]; ++ iwst[i] = rwst[i] * niwst[i] + iwst[i] * nrwst[i]; ++ rwst[i] = rx; ++ } ++ ++ this.conjugate(rwst, iwst, N); ++ this.transform(rwst, iwst, rmws, _, N, rbt); ++ this.conjugate(rmws, _, N); ++ this.normalize13b(rmws, N); ++ ++ out.negative = x.negative ^ y.negative; ++ out.length = x.length + y.length; ++ return out.strip(); ++ }; ++ ++ // Multiply `this` by `num` ++ BN.prototype.mul = function mul (num) { ++ var out = new BN(null); ++ out.words = new Array(this.length + num.length); ++ return this.mulTo(num, out); ++ }; ++ ++ // Multiply employing FFT ++ BN.prototype.mulf = function mulf (num) { ++ var out = new BN(null); ++ out.words = new Array(this.length + num.length); ++ return jumboMulTo(this, num, out); ++ }; ++ ++ // In-place Multiplication ++ BN.prototype.imul = function imul (num) { ++ return this.clone().mulTo(num, this); ++ }; ++ ++ BN.prototype.imuln = function imuln (num) { ++ assert(typeof num === 'number'); ++ assert(num < 0x4000000); ++ ++ // Carry ++ var carry = 0; ++ for (var i = 0; i < this.length; i++) { ++ var w = (this.words[i] | 0) * num; ++ var lo = (w & 0x3ffffff) + (carry & 0x3ffffff); ++ carry >>= 26; ++ carry += (w / 0x4000000) | 0; ++ // NOTE: lo is 27bit maximum ++ carry += lo >>> 26; ++ this.words[i] = lo & 0x3ffffff; ++ } ++ ++ if (carry !== 0) { ++ this.words[i] = carry; ++ this.length++; ++ } ++ ++ return this; ++ }; ++ ++ BN.prototype.muln = function muln (num) { ++ return this.clone().imuln(num); ++ }; ++ ++ // `this` * `this` ++ BN.prototype.sqr = function sqr () { ++ return this.mul(this); ++ }; ++ ++ // `this` * `this` in-place ++ BN.prototype.isqr = function isqr () { ++ return this.imul(this.clone()); ++ }; ++ ++ // Math.pow(`this`, `num`) ++ BN.prototype.pow = function pow (num) { ++ var w = toBitArray(num); ++ if (w.length === 0) return new BN(1); ++ ++ // Skip leading zeroes ++ var res = this; ++ for (var i = 0; i < w.length; i++, res = res.sqr()) { ++ if (w[i] !== 0) break; ++ } ++ ++ if (++i < w.length) { ++ for (var q = res.sqr(); i < w.length; i++, q = q.sqr()) { ++ if (w[i] === 0) continue; ++ ++ res = res.mul(q); ++ } ++ } ++ ++ return res; ++ }; ++ ++ // Shift-left in-place ++ BN.prototype.iushln = function iushln (bits) { ++ assert(typeof bits === 'number' && bits >= 0); ++ var r = bits % 26; ++ var s = (bits - r) / 26; ++ var carryMask = (0x3ffffff >>> (26 - r)) << (26 - r); ++ var i; ++ ++ if (r !== 0) { ++ var carry = 0; ++ ++ for (i = 0; i < this.length; i++) { ++ var newCarry = this.words[i] & carryMask; ++ var c = ((this.words[i] | 0) - newCarry) << r; ++ this.words[i] = c | carry; ++ carry = newCarry >>> (26 - r); ++ } ++ ++ if (carry) { ++ this.words[i] = carry; ++ this.length++; ++ } ++ } ++ ++ if (s !== 0) { ++ for (i = this.length - 1; i >= 0; i--) { ++ this.words[i + s] = this.words[i]; ++ } ++ ++ for (i = 0; i < s; i++) { ++ this.words[i] = 0; ++ } ++ ++ this.length += s; ++ } ++ ++ return this.strip(); ++ }; ++ ++ BN.prototype.ishln = function ishln (bits) { ++ // TODO(indutny): implement me ++ assert(this.negative === 0); ++ return this.iushln(bits); ++ }; ++ ++ // Shift-right in-place ++ // NOTE: `hint` is a lowest bit before trailing zeroes ++ // NOTE: if `extended` is present - it will be filled with destroyed bits ++ BN.prototype.iushrn = function iushrn (bits, hint, extended) { ++ assert(typeof bits === 'number' && bits >= 0); ++ var h; ++ if (hint) { ++ h = (hint - (hint % 26)) / 26; ++ } else { ++ h = 0; ++ } ++ ++ var r = bits % 26; ++ var s = Math.min((bits - r) / 26, this.length); ++ var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r); ++ var maskedWords = extended; ++ ++ h -= s; ++ h = Math.max(0, h); ++ ++ // Extended mode, copy masked part ++ if (maskedWords) { ++ for (var i = 0; i < s; i++) { ++ maskedWords.words[i] = this.words[i]; ++ } ++ maskedWords.length = s; ++ } ++ ++ if (s === 0) { ++ // No-op, we should not move anything at all ++ } else if (this.length > s) { ++ this.length -= s; ++ for (i = 0; i < this.length; i++) { ++ this.words[i] = this.words[i + s]; ++ } ++ } else { ++ this.words[0] = 0; ++ this.length = 1; ++ } ++ ++ var carry = 0; ++ for (i = this.length - 1; i >= 0 && (carry !== 0 || i >= h); i--) { ++ var word = this.words[i] | 0; ++ this.words[i] = (carry << (26 - r)) | (word >>> r); ++ carry = word & mask; ++ } ++ ++ // Push carried bits as a mask ++ if (maskedWords && carry !== 0) { ++ maskedWords.words[maskedWords.length++] = carry; ++ } ++ ++ if (this.length === 0) { ++ this.words[0] = 0; ++ this.length = 1; ++ } ++ ++ return this.strip(); ++ }; ++ ++ BN.prototype.ishrn = function ishrn (bits, hint, extended) { ++ // TODO(indutny): implement me ++ assert(this.negative === 0); ++ return this.iushrn(bits, hint, extended); ++ }; ++ ++ // Shift-left ++ BN.prototype.shln = function shln (bits) { ++ return this.clone().ishln(bits); ++ }; ++ ++ BN.prototype.ushln = function ushln (bits) { ++ return this.clone().iushln(bits); ++ }; ++ ++ // Shift-right ++ BN.prototype.shrn = function shrn (bits) { ++ return this.clone().ishrn(bits); ++ }; ++ ++ BN.prototype.ushrn = function ushrn (bits) { ++ return this.clone().iushrn(bits); ++ }; ++ ++ // Test if n bit is set ++ BN.prototype.testn = function testn (bit) { ++ assert(typeof bit === 'number' && bit >= 0); ++ var r = bit % 26; ++ var s = (bit - r) / 26; ++ var q = 1 << r; ++ ++ // Fast case: bit is much higher than all existing words ++ if (this.length <= s) return false; ++ ++ // Check bit and return ++ var w = this.words[s]; ++ ++ return !!(w & q); ++ }; ++ ++ // Return only lowers bits of number (in-place) ++ BN.prototype.imaskn = function imaskn (bits) { ++ assert(typeof bits === 'number' && bits >= 0); ++ var r = bits % 26; ++ var s = (bits - r) / 26; ++ ++ assert(this.negative === 0, 'imaskn works only with positive numbers'); ++ ++ if (this.length <= s) { ++ return this; ++ } ++ ++ if (r !== 0) { ++ s++; ++ } ++ this.length = Math.min(s, this.length); ++ ++ if (r !== 0) { ++ var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r); ++ this.words[this.length - 1] &= mask; ++ } ++ ++ return this.strip(); ++ }; ++ ++ // Return only lowers bits of number ++ BN.prototype.maskn = function maskn (bits) { ++ return this.clone().imaskn(bits); ++ }; ++ ++ // Add plain number `num` to `this` ++ BN.prototype.iaddn = function iaddn (num) { ++ assert(typeof num === 'number'); ++ assert(num < 0x4000000); ++ if (num < 0) return this.isubn(-num); ++ ++ // Possible sign change ++ if (this.negative !== 0) { ++ if (this.length === 1 && (this.words[0] | 0) < num) { ++ this.words[0] = num - (this.words[0] | 0); ++ this.negative = 0; ++ return this; ++ } ++ ++ this.negative = 0; ++ this.isubn(num); ++ this.negative = 1; ++ return this; ++ } ++ ++ // Add without checks ++ return this._iaddn(num); ++ }; ++ ++ BN.prototype._iaddn = function _iaddn (num) { ++ this.words[0] += num; ++ ++ // Carry ++ for (var i = 0; i < this.length && this.words[i] >= 0x4000000; i++) { ++ this.words[i] -= 0x4000000; ++ if (i === this.length - 1) { ++ this.words[i + 1] = 1; ++ } else { ++ this.words[i + 1]++; ++ } ++ } ++ this.length = Math.max(this.length, i + 1); ++ ++ return this; ++ }; ++ ++ // Subtract plain number `num` from `this` ++ BN.prototype.isubn = function isubn (num) { ++ assert(typeof num === 'number'); ++ assert(num < 0x4000000); ++ if (num < 0) return this.iaddn(-num); ++ ++ if (this.negative !== 0) { ++ this.negative = 0; ++ this.iaddn(num); ++ this.negative = 1; ++ return this; ++ } ++ ++ this.words[0] -= num; ++ ++ if (this.length === 1 && this.words[0] < 0) { ++ this.words[0] = -this.words[0]; ++ this.negative = 1; ++ } else { ++ // Carry ++ for (var i = 0; i < this.length && this.words[i] < 0; i++) { ++ this.words[i] += 0x4000000; ++ this.words[i + 1] -= 1; ++ } ++ } ++ ++ return this.strip(); ++ }; ++ ++ BN.prototype.addn = function addn (num) { ++ return this.clone().iaddn(num); ++ }; ++ ++ BN.prototype.subn = function subn (num) { ++ return this.clone().isubn(num); ++ }; ++ ++ BN.prototype.iabs = function iabs () { ++ this.negative = 0; ++ ++ return this; ++ }; ++ ++ BN.prototype.abs = function abs () { ++ return this.clone().iabs(); ++ }; ++ ++ BN.prototype._ishlnsubmul = function _ishlnsubmul (num, mul, shift) { ++ var len = num.length + shift; ++ var i; ++ ++ this._expand(len); ++ ++ var w; ++ var carry = 0; ++ for (i = 0; i < num.length; i++) { ++ w = (this.words[i + shift] | 0) + carry; ++ var right = (num.words[i] | 0) * mul; ++ w -= right & 0x3ffffff; ++ carry = (w >> 26) - ((right / 0x4000000) | 0); ++ this.words[i + shift] = w & 0x3ffffff; ++ } ++ for (; i < this.length - shift; i++) { ++ w = (this.words[i + shift] | 0) + carry; ++ carry = w >> 26; ++ this.words[i + shift] = w & 0x3ffffff; ++ } ++ ++ if (carry === 0) return this.strip(); ++ ++ // Subtraction overflow ++ assert(carry === -1); ++ carry = 0; ++ for (i = 0; i < this.length; i++) { ++ w = -(this.words[i] | 0) + carry; ++ carry = w >> 26; ++ this.words[i] = w & 0x3ffffff; ++ } ++ this.negative = 1; ++ ++ return this.strip(); ++ }; ++ ++ BN.prototype._wordDiv = function _wordDiv (num, mode) { ++ var shift = this.length - num.length; ++ ++ var a = this.clone(); ++ var b = num; ++ ++ // Normalize ++ var bhi = b.words[b.length - 1] | 0; ++ var bhiBits = this._countBits(bhi); ++ shift = 26 - bhiBits; ++ if (shift !== 0) { ++ b = b.ushln(shift); ++ a.iushln(shift); ++ bhi = b.words[b.length - 1] | 0; ++ } ++ ++ // Initialize quotient ++ var m = a.length - b.length; ++ var q; ++ ++ if (mode !== 'mod') { ++ q = new BN(null); ++ q.length = m + 1; ++ q.words = new Array(q.length); ++ for (var i = 0; i < q.length; i++) { ++ q.words[i] = 0; ++ } ++ } ++ ++ var diff = a.clone()._ishlnsubmul(b, 1, m); ++ if (diff.negative === 0) { ++ a = diff; ++ if (q) { ++ q.words[m] = 1; ++ } ++ } ++ ++ for (var j = m - 1; j >= 0; j--) { ++ var qj = (a.words[b.length + j] | 0) * 0x4000000 + ++ (a.words[b.length + j - 1] | 0); ++ ++ // NOTE: (qj / bhi) is (0x3ffffff * 0x4000000 + 0x3ffffff) / 0x2000000 max ++ // (0x7ffffff) ++ qj = Math.min((qj / bhi) | 0, 0x3ffffff); ++ ++ a._ishlnsubmul(b, qj, j); ++ while (a.negative !== 0) { ++ qj--; ++ a.negative = 0; ++ a._ishlnsubmul(b, 1, j); ++ if (!a.isZero()) { ++ a.negative ^= 1; ++ } ++ } ++ if (q) { ++ q.words[j] = qj; ++ } ++ } ++ if (q) { ++ q.strip(); ++ } ++ a.strip(); ++ ++ // Denormalize ++ if (mode !== 'div' && shift !== 0) { ++ a.iushrn(shift); ++ } ++ ++ return { ++ div: q || null, ++ mod: a ++ }; ++ }; ++ ++ // NOTE: 1) `mode` can be set to `mod` to request mod only, ++ // to `div` to request div only, or be absent to ++ // request both div & mod ++ // 2) `positive` is true if unsigned mod is requested ++ BN.prototype.divmod = function divmod (num, mode, positive) { ++ assert(!num.isZero()); ++ ++ if (this.isZero()) { ++ return { ++ div: new BN(0), ++ mod: new BN(0) ++ }; ++ } ++ ++ var div, mod, res; ++ if (this.negative !== 0 && num.negative === 0) { ++ res = this.neg().divmod(num, mode); ++ ++ if (mode !== 'mod') { ++ div = res.div.neg(); ++ } ++ ++ if (mode !== 'div') { ++ mod = res.mod.neg(); ++ if (positive && mod.negative !== 0) { ++ mod.iadd(num); ++ } ++ } ++ ++ return { ++ div: div, ++ mod: mod ++ }; ++ } ++ ++ if (this.negative === 0 && num.negative !== 0) { ++ res = this.divmod(num.neg(), mode); ++ ++ if (mode !== 'mod') { ++ div = res.div.neg(); ++ } ++ ++ return { ++ div: div, ++ mod: res.mod ++ }; ++ } ++ ++ if ((this.negative & num.negative) !== 0) { ++ res = this.neg().divmod(num.neg(), mode); ++ ++ if (mode !== 'div') { ++ mod = res.mod.neg(); ++ if (positive && mod.negative !== 0) { ++ mod.isub(num); ++ } ++ } ++ ++ return { ++ div: res.div, ++ mod: mod ++ }; ++ } ++ ++ // Both numbers are positive at this point ++ ++ // Strip both numbers to approximate shift value ++ if (num.length > this.length || this.cmp(num) < 0) { ++ return { ++ div: new BN(0), ++ mod: this ++ }; ++ } ++ ++ // Very short reduction ++ if (num.length === 1) { ++ if (mode === 'div') { ++ return { ++ div: this.divn(num.words[0]), ++ mod: null ++ }; ++ } ++ ++ if (mode === 'mod') { ++ return { ++ div: null, ++ mod: new BN(this.modn(num.words[0])) ++ }; ++ } ++ ++ return { ++ div: this.divn(num.words[0]), ++ mod: new BN(this.modn(num.words[0])) ++ }; ++ } ++ ++ return this._wordDiv(num, mode); ++ }; ++ ++ // Find `this` / `num` ++ BN.prototype.div = function div (num) { ++ return this.divmod(num, 'div', false).div; ++ }; ++ ++ // Find `this` % `num` ++ BN.prototype.mod = function mod (num) { ++ return this.divmod(num, 'mod', false).mod; ++ }; ++ ++ BN.prototype.umod = function umod (num) { ++ return this.divmod(num, 'mod', true).mod; ++ }; ++ ++ // Find Round(`this` / `num`) ++ BN.prototype.divRound = function divRound (num) { ++ var dm = this.divmod(num); ++ ++ // Fast case - exact division ++ if (dm.mod.isZero()) return dm.div; ++ ++ var mod = dm.div.negative !== 0 ? dm.mod.isub(num) : dm.mod; ++ ++ var half = num.ushrn(1); ++ var r2 = num.andln(1); ++ var cmp = mod.cmp(half); ++ ++ // Round down ++ if (cmp < 0 || r2 === 1 && cmp === 0) return dm.div; ++ ++ // Round up ++ return dm.div.negative !== 0 ? dm.div.isubn(1) : dm.div.iaddn(1); ++ }; ++ ++ BN.prototype.modn = function modn (num) { ++ assert(num <= 0x3ffffff); ++ var p = (1 << 26) % num; ++ ++ var acc = 0; ++ for (var i = this.length - 1; i >= 0; i--) { ++ acc = (p * acc + (this.words[i] | 0)) % num; ++ } ++ ++ return acc; ++ }; ++ ++ // In-place division by number ++ BN.prototype.idivn = function idivn (num) { ++ assert(num <= 0x3ffffff); ++ ++ var carry = 0; ++ for (var i = this.length - 1; i >= 0; i--) { ++ var w = (this.words[i] | 0) + carry * 0x4000000; ++ this.words[i] = (w / num) | 0; ++ carry = w % num; ++ } ++ ++ return this.strip(); ++ }; ++ ++ BN.prototype.divn = function divn (num) { ++ return this.clone().idivn(num); ++ }; ++ ++ BN.prototype.egcd = function egcd (p) { ++ assert(p.negative === 0); ++ assert(!p.isZero()); ++ ++ var x = this; ++ var y = p.clone(); ++ ++ if (x.negative !== 0) { ++ x = x.umod(p); ++ } else { ++ x = x.clone(); ++ } ++ ++ // A * x + B * y = x ++ var A = new BN(1); ++ var B = new BN(0); ++ ++ // C * x + D * y = y ++ var C = new BN(0); ++ var D = new BN(1); ++ ++ var g = 0; ++ ++ while (x.isEven() && y.isEven()) { ++ x.iushrn(1); ++ y.iushrn(1); ++ ++g; ++ } ++ ++ var yp = y.clone(); ++ var xp = x.clone(); ++ ++ while (!x.isZero()) { ++ for (var i = 0, im = 1; (x.words[0] & im) === 0 && i < 26; ++i, im <<= 1); ++ if (i > 0) { ++ x.iushrn(i); ++ while (i-- > 0) { ++ if (A.isOdd() || B.isOdd()) { ++ A.iadd(yp); ++ B.isub(xp); ++ } ++ ++ A.iushrn(1); ++ B.iushrn(1); ++ } ++ } ++ ++ for (var j = 0, jm = 1; (y.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1); ++ if (j > 0) { ++ y.iushrn(j); ++ while (j-- > 0) { ++ if (C.isOdd() || D.isOdd()) { ++ C.iadd(yp); ++ D.isub(xp); ++ } ++ ++ C.iushrn(1); ++ D.iushrn(1); ++ } ++ } ++ ++ if (x.cmp(y) >= 0) { ++ x.isub(y); ++ A.isub(C); ++ B.isub(D); ++ } else { ++ y.isub(x); ++ C.isub(A); ++ D.isub(B); ++ } ++ } ++ ++ return { ++ a: C, ++ b: D, ++ gcd: y.iushln(g) ++ }; ++ }; ++ ++ // This is reduced incarnation of the binary EEA ++ // above, designated to invert members of the ++ // _prime_ fields F(p) at a maximal speed ++ BN.prototype._invmp = function _invmp (p) { ++ assert(p.negative === 0); ++ assert(!p.isZero()); ++ ++ var a = this; ++ var b = p.clone(); ++ ++ if (a.negative !== 0) { ++ a = a.umod(p); ++ } else { ++ a = a.clone(); ++ } ++ ++ var x1 = new BN(1); ++ var x2 = new BN(0); ++ ++ var delta = b.clone(); ++ ++ while (a.cmpn(1) > 0 && b.cmpn(1) > 0) { ++ for (var i = 0, im = 1; (a.words[0] & im) === 0 && i < 26; ++i, im <<= 1); ++ if (i > 0) { ++ a.iushrn(i); ++ while (i-- > 0) { ++ if (x1.isOdd()) { ++ x1.iadd(delta); ++ } ++ ++ x1.iushrn(1); ++ } ++ } ++ ++ for (var j = 0, jm = 1; (b.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1); ++ if (j > 0) { ++ b.iushrn(j); ++ while (j-- > 0) { ++ if (x2.isOdd()) { ++ x2.iadd(delta); ++ } ++ ++ x2.iushrn(1); ++ } ++ } ++ ++ if (a.cmp(b) >= 0) { ++ a.isub(b); ++ x1.isub(x2); ++ } else { ++ b.isub(a); ++ x2.isub(x1); ++ } ++ } ++ ++ var res; ++ if (a.cmpn(1) === 0) { ++ res = x1; ++ } else { ++ res = x2; ++ } ++ ++ if (res.cmpn(0) < 0) { ++ res.iadd(p); ++ } ++ ++ return res; ++ }; ++ ++ BN.prototype.gcd = function gcd (num) { ++ if (this.isZero()) return num.abs(); ++ if (num.isZero()) return this.abs(); ++ ++ var a = this.clone(); ++ var b = num.clone(); ++ a.negative = 0; ++ b.negative = 0; ++ ++ // Remove common factor of two ++ for (var shift = 0; a.isEven() && b.isEven(); shift++) { ++ a.iushrn(1); ++ b.iushrn(1); ++ } ++ ++ do { ++ while (a.isEven()) { ++ a.iushrn(1); ++ } ++ while (b.isEven()) { ++ b.iushrn(1); ++ } ++ ++ var r = a.cmp(b); ++ if (r < 0) { ++ // Swap `a` and `b` to make `a` always bigger than `b` ++ var t = a; ++ a = b; ++ b = t; ++ } else if (r === 0 || b.cmpn(1) === 0) { ++ break; ++ } ++ ++ a.isub(b); ++ } while (true); ++ ++ return b.iushln(shift); ++ }; ++ ++ // Invert number in the field F(num) ++ BN.prototype.invm = function invm (num) { ++ return this.egcd(num).a.umod(num); ++ }; ++ ++ BN.prototype.isEven = function isEven () { ++ return (this.words[0] & 1) === 0; ++ }; ++ ++ BN.prototype.isOdd = function isOdd () { ++ return (this.words[0] & 1) === 1; ++ }; ++ ++ // And first word and num ++ BN.prototype.andln = function andln (num) { ++ return this.words[0] & num; ++ }; ++ ++ // Increment at the bit position in-line ++ BN.prototype.bincn = function bincn (bit) { ++ assert(typeof bit === 'number'); ++ var r = bit % 26; ++ var s = (bit - r) / 26; ++ var q = 1 << r; ++ ++ // Fast case: bit is much higher than all existing words ++ if (this.length <= s) { ++ this._expand(s + 1); ++ this.words[s] |= q; ++ return this; ++ } ++ ++ // Add bit and propagate, if needed ++ var carry = q; ++ for (var i = s; carry !== 0 && i < this.length; i++) { ++ var w = this.words[i] | 0; ++ w += carry; ++ carry = w >>> 26; ++ w &= 0x3ffffff; ++ this.words[i] = w; ++ } ++ if (carry !== 0) { ++ this.words[i] = carry; ++ this.length++; ++ } ++ return this; ++ }; ++ ++ BN.prototype.isZero = function isZero () { ++ return this.length === 1 && this.words[0] === 0; ++ }; ++ ++ BN.prototype.cmpn = function cmpn (num) { ++ var negative = num < 0; ++ ++ if (this.negative !== 0 && !negative) return -1; ++ if (this.negative === 0 && negative) return 1; ++ ++ this.strip(); ++ ++ var res; ++ if (this.length > 1) { ++ res = 1; ++ } else { ++ if (negative) { ++ num = -num; ++ } ++ ++ assert(num <= 0x3ffffff, 'Number is too big'); ++ ++ var w = this.words[0] | 0; ++ res = w === num ? 0 : w < num ? -1 : 1; ++ } ++ if (this.negative !== 0) return -res | 0; ++ return res; ++ }; ++ ++ // Compare two numbers and return: ++ // 1 - if `this` > `num` ++ // 0 - if `this` == `num` ++ // -1 - if `this` < `num` ++ BN.prototype.cmp = function cmp (num) { ++ if (this.negative !== 0 && num.negative === 0) return -1; ++ if (this.negative === 0 && num.negative !== 0) return 1; ++ ++ var res = this.ucmp(num); ++ if (this.negative !== 0) return -res | 0; ++ return res; ++ }; ++ ++ // Unsigned comparison ++ BN.prototype.ucmp = function ucmp (num) { ++ // At this point both numbers have the same sign ++ if (this.length > num.length) return 1; ++ if (this.length < num.length) return -1; ++ ++ var res = 0; ++ for (var i = this.length - 1; i >= 0; i--) { ++ var a = this.words[i] | 0; ++ var b = num.words[i] | 0; ++ ++ if (a === b) continue; ++ if (a < b) { ++ res = -1; ++ } else if (a > b) { ++ res = 1; ++ } ++ break; ++ } ++ return res; ++ }; ++ ++ BN.prototype.gtn = function gtn (num) { ++ return this.cmpn(num) === 1; ++ }; ++ ++ BN.prototype.gt = function gt (num) { ++ return this.cmp(num) === 1; ++ }; ++ ++ BN.prototype.gten = function gten (num) { ++ return this.cmpn(num) >= 0; ++ }; ++ ++ BN.prototype.gte = function gte (num) { ++ return this.cmp(num) >= 0; ++ }; ++ ++ BN.prototype.ltn = function ltn (num) { ++ return this.cmpn(num) === -1; ++ }; ++ ++ BN.prototype.lt = function lt (num) { ++ return this.cmp(num) === -1; ++ }; ++ ++ BN.prototype.lten = function lten (num) { ++ return this.cmpn(num) <= 0; ++ }; ++ ++ BN.prototype.lte = function lte (num) { ++ return this.cmp(num) <= 0; ++ }; ++ ++ BN.prototype.eqn = function eqn (num) { ++ return this.cmpn(num) === 0; ++ }; ++ ++ BN.prototype.eq = function eq (num) { ++ return this.cmp(num) === 0; ++ }; ++ ++ // ++ // A reduce context, could be using montgomery or something better, depending ++ // on the `m` itself. ++ // ++ BN.red = function red (num) { ++ return new Red(num); ++ }; ++ ++ BN.prototype.toRed = function toRed (ctx) { ++ assert(!this.red, 'Already a number in reduction context'); ++ assert(this.negative === 0, 'red works only with positives'); ++ return ctx.convertTo(this)._forceRed(ctx); ++ }; ++ ++ BN.prototype.fromRed = function fromRed () { ++ assert(this.red, 'fromRed works only with numbers in reduction context'); ++ return this.red.convertFrom(this); ++ }; ++ ++ BN.prototype._forceRed = function _forceRed (ctx) { ++ this.red = ctx; ++ return this; ++ }; ++ ++ BN.prototype.forceRed = function forceRed (ctx) { ++ assert(!this.red, 'Already a number in reduction context'); ++ return this._forceRed(ctx); ++ }; ++ ++ BN.prototype.redAdd = function redAdd (num) { ++ assert(this.red, 'redAdd works only with red numbers'); ++ return this.red.add(this, num); ++ }; ++ ++ BN.prototype.redIAdd = function redIAdd (num) { ++ assert(this.red, 'redIAdd works only with red numbers'); ++ return this.red.iadd(this, num); ++ }; ++ ++ BN.prototype.redSub = function redSub (num) { ++ assert(this.red, 'redSub works only with red numbers'); ++ return this.red.sub(this, num); ++ }; ++ ++ BN.prototype.redISub = function redISub (num) { ++ assert(this.red, 'redISub works only with red numbers'); ++ return this.red.isub(this, num); ++ }; ++ ++ BN.prototype.redShl = function redShl (num) { ++ assert(this.red, 'redShl works only with red numbers'); ++ return this.red.shl(this, num); ++ }; ++ ++ BN.prototype.redMul = function redMul (num) { ++ assert(this.red, 'redMul works only with red numbers'); ++ this.red._verify2(this, num); ++ return this.red.mul(this, num); ++ }; ++ ++ BN.prototype.redIMul = function redIMul (num) { ++ assert(this.red, 'redMul works only with red numbers'); ++ this.red._verify2(this, num); ++ return this.red.imul(this, num); ++ }; ++ ++ BN.prototype.redSqr = function redSqr () { ++ assert(this.red, 'redSqr works only with red numbers'); ++ this.red._verify1(this); ++ return this.red.sqr(this); ++ }; ++ ++ BN.prototype.redISqr = function redISqr () { ++ assert(this.red, 'redISqr works only with red numbers'); ++ this.red._verify1(this); ++ return this.red.isqr(this); ++ }; ++ ++ // Square root over p ++ BN.prototype.redSqrt = function redSqrt () { ++ assert(this.red, 'redSqrt works only with red numbers'); ++ this.red._verify1(this); ++ return this.red.sqrt(this); ++ }; ++ ++ BN.prototype.redInvm = function redInvm () { ++ assert(this.red, 'redInvm works only with red numbers'); ++ this.red._verify1(this); ++ return this.red.invm(this); ++ }; ++ ++ // Return negative clone of `this` % `red modulo` ++ BN.prototype.redNeg = function redNeg () { ++ assert(this.red, 'redNeg works only with red numbers'); ++ this.red._verify1(this); ++ return this.red.neg(this); ++ }; ++ ++ BN.prototype.redPow = function redPow (num) { ++ assert(this.red && !num.red, 'redPow(normalNum)'); ++ this.red._verify1(this); ++ return this.red.pow(this, num); ++ }; ++ ++ // Prime numbers with efficient reduction ++ var primes = { ++ k256: null, ++ p224: null, ++ p192: null, ++ p25519: null ++ }; ++ ++ // Pseudo-Mersenne prime ++ function MPrime (name, p) { ++ // P = 2 ^ N - K ++ this.name = name; ++ this.p = new BN(p, 16); ++ this.n = this.p.bitLength(); ++ this.k = new BN(1).iushln(this.n).isub(this.p); ++ ++ this.tmp = this._tmp(); ++ } ++ ++ MPrime.prototype._tmp = function _tmp () { ++ var tmp = new BN(null); ++ tmp.words = new Array(Math.ceil(this.n / 13)); ++ return tmp; ++ }; ++ ++ MPrime.prototype.ireduce = function ireduce (num) { ++ // Assumes that `num` is less than `P^2` ++ // num = HI * (2 ^ N - K) + HI * K + LO = HI * K + LO (mod P) ++ var r = num; ++ var rlen; ++ ++ do { ++ this.split(r, this.tmp); ++ r = this.imulK(r); ++ r = r.iadd(this.tmp); ++ rlen = r.bitLength(); ++ } while (rlen > this.n); ++ ++ var cmp = rlen < this.n ? -1 : r.ucmp(this.p); ++ if (cmp === 0) { ++ r.words[0] = 0; ++ r.length = 1; ++ } else if (cmp > 0) { ++ r.isub(this.p); ++ } else { ++ r.strip(); ++ } ++ ++ return r; ++ }; ++ ++ MPrime.prototype.split = function split (input, out) { ++ input.iushrn(this.n, 0, out); ++ }; ++ ++ MPrime.prototype.imulK = function imulK (num) { ++ return num.imul(this.k); ++ }; ++ ++ function K256 () { ++ MPrime.call( ++ this, ++ 'k256', ++ 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f'); ++ } ++ inherits(K256, MPrime); ++ ++ K256.prototype.split = function split (input, output) { ++ // 256 = 9 * 26 + 22 ++ var mask = 0x3fffff; ++ ++ var outLen = Math.min(input.length, 9); ++ for (var i = 0; i < outLen; i++) { ++ output.words[i] = input.words[i]; ++ } ++ output.length = outLen; ++ ++ if (input.length <= 9) { ++ input.words[0] = 0; ++ input.length = 1; ++ return; ++ } ++ ++ // Shift by 9 limbs ++ var prev = input.words[9]; ++ output.words[output.length++] = prev & mask; ++ ++ for (i = 10; i < input.length; i++) { ++ var next = input.words[i] | 0; ++ input.words[i - 10] = ((next & mask) << 4) | (prev >>> 22); ++ prev = next; ++ } ++ prev >>>= 22; ++ input.words[i - 10] = prev; ++ if (prev === 0 && input.length > 10) { ++ input.length -= 10; ++ } else { ++ input.length -= 9; ++ } ++ }; ++ ++ K256.prototype.imulK = function imulK (num) { ++ // K = 0x1000003d1 = [ 0x40, 0x3d1 ] ++ num.words[num.length] = 0; ++ num.words[num.length + 1] = 0; ++ num.length += 2; ++ ++ // bounded at: 0x40 * 0x3ffffff + 0x3d0 = 0x100000390 ++ var lo = 0; ++ for (var i = 0; i < num.length; i++) { ++ var w = num.words[i] | 0; ++ lo += w * 0x3d1; ++ num.words[i] = lo & 0x3ffffff; ++ lo = w * 0x40 + ((lo / 0x4000000) | 0); ++ } ++ ++ // Fast length reduction ++ if (num.words[num.length - 1] === 0) { ++ num.length--; ++ if (num.words[num.length - 1] === 0) { ++ num.length--; ++ } ++ } ++ return num; ++ }; ++ ++ function P224 () { ++ MPrime.call( ++ this, ++ 'p224', ++ 'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001'); ++ } ++ inherits(P224, MPrime); ++ ++ function P192 () { ++ MPrime.call( ++ this, ++ 'p192', ++ 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff'); ++ } ++ inherits(P192, MPrime); ++ ++ function P25519 () { ++ // 2 ^ 255 - 19 ++ MPrime.call( ++ this, ++ '25519', ++ '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed'); ++ } ++ inherits(P25519, MPrime); ++ ++ P25519.prototype.imulK = function imulK (num) { ++ // K = 0x13 ++ var carry = 0; ++ for (var i = 0; i < num.length; i++) { ++ var hi = (num.words[i] | 0) * 0x13 + carry; ++ var lo = hi & 0x3ffffff; ++ hi >>>= 26; ++ ++ num.words[i] = lo; ++ carry = hi; ++ } ++ if (carry !== 0) { ++ num.words[num.length++] = carry; ++ } ++ return num; ++ }; ++ ++ // Exported mostly for testing purposes, use plain name instead ++ BN._prime = function prime (name) { ++ // Cached version of prime ++ if (primes[name]) return primes[name]; ++ ++ var prime; ++ if (name === 'k256') { ++ prime = new K256(); ++ } else if (name === 'p224') { ++ prime = new P224(); ++ } else if (name === 'p192') { ++ prime = new P192(); ++ } else if (name === 'p25519') { ++ prime = new P25519(); ++ } else { ++ throw new Error('Unknown prime ' + name); ++ } ++ primes[name] = prime; ++ ++ return prime; ++ }; ++ ++ // ++ // Base reduction engine ++ // ++ function Red (m) { ++ if (typeof m === 'string') { ++ var prime = BN._prime(m); ++ this.m = prime.p; ++ this.prime = prime; ++ } else { ++ assert(m.gtn(1), 'modulus must be greater than 1'); ++ this.m = m; ++ this.prime = null; ++ } ++ } ++ ++ Red.prototype._verify1 = function _verify1 (a) { ++ assert(a.negative === 0, 'red works only with positives'); ++ assert(a.red, 'red works only with red numbers'); ++ }; ++ ++ Red.prototype._verify2 = function _verify2 (a, b) { ++ assert((a.negative | b.negative) === 0, 'red works only with positives'); ++ assert(a.red && a.red === b.red, ++ 'red works only with red numbers'); ++ }; ++ ++ Red.prototype.imod = function imod (a) { ++ if (this.prime) return this.prime.ireduce(a)._forceRed(this); ++ return a.umod(this.m)._forceRed(this); ++ }; ++ ++ Red.prototype.neg = function neg (a) { ++ if (a.isZero()) { ++ return a.clone(); ++ } ++ ++ return this.m.sub(a)._forceRed(this); ++ }; ++ ++ Red.prototype.add = function add (a, b) { ++ this._verify2(a, b); ++ ++ var res = a.add(b); ++ if (res.cmp(this.m) >= 0) { ++ res.isub(this.m); ++ } ++ return res._forceRed(this); ++ }; ++ ++ Red.prototype.iadd = function iadd (a, b) { ++ this._verify2(a, b); ++ ++ var res = a.iadd(b); ++ if (res.cmp(this.m) >= 0) { ++ res.isub(this.m); ++ } ++ return res; ++ }; ++ ++ Red.prototype.sub = function sub (a, b) { ++ this._verify2(a, b); ++ ++ var res = a.sub(b); ++ if (res.cmpn(0) < 0) { ++ res.iadd(this.m); ++ } ++ return res._forceRed(this); ++ }; ++ ++ Red.prototype.isub = function isub (a, b) { ++ this._verify2(a, b); ++ ++ var res = a.isub(b); ++ if (res.cmpn(0) < 0) { ++ res.iadd(this.m); ++ } ++ return res; ++ }; ++ ++ Red.prototype.shl = function shl (a, num) { ++ this._verify1(a); ++ return this.imod(a.ushln(num)); ++ }; ++ ++ Red.prototype.imul = function imul (a, b) { ++ this._verify2(a, b); ++ return this.imod(a.imul(b)); ++ }; ++ ++ Red.prototype.mul = function mul (a, b) { ++ this._verify2(a, b); ++ return this.imod(a.mul(b)); ++ }; ++ ++ Red.prototype.isqr = function isqr (a) { ++ return this.imul(a, a.clone()); ++ }; ++ ++ Red.prototype.sqr = function sqr (a) { ++ return this.mul(a, a); ++ }; ++ ++ Red.prototype.sqrt = function sqrt (a) { ++ if (a.isZero()) return a.clone(); ++ ++ var mod3 = this.m.andln(3); ++ assert(mod3 % 2 === 1); ++ ++ // Fast case ++ if (mod3 === 3) { ++ var pow = this.m.add(new BN(1)).iushrn(2); ++ return this.pow(a, pow); ++ } ++ ++ // Tonelli-Shanks algorithm (Totally unoptimized and slow) ++ // ++ // Find Q and S, that Q * 2 ^ S = (P - 1) ++ var q = this.m.subn(1); ++ var s = 0; ++ while (!q.isZero() && q.andln(1) === 0) { ++ s++; ++ q.iushrn(1); ++ } ++ assert(!q.isZero()); ++ ++ var one = new BN(1).toRed(this); ++ var nOne = one.redNeg(); ++ ++ // Find quadratic non-residue ++ // NOTE: Max is such because of generalized Riemann hypothesis. ++ var lpow = this.m.subn(1).iushrn(1); ++ var z = this.m.bitLength(); ++ z = new BN(2 * z * z).toRed(this); ++ ++ while (this.pow(z, lpow).cmp(nOne) !== 0) { ++ z.redIAdd(nOne); ++ } ++ ++ var c = this.pow(z, q); ++ var r = this.pow(a, q.addn(1).iushrn(1)); ++ var t = this.pow(a, q); ++ var m = s; ++ while (t.cmp(one) !== 0) { ++ var tmp = t; ++ for (var i = 0; tmp.cmp(one) !== 0; i++) { ++ tmp = tmp.redSqr(); ++ } ++ assert(i < m); ++ var b = this.pow(c, new BN(1).iushln(m - i - 1)); ++ ++ r = r.redMul(b); ++ c = b.redSqr(); ++ t = t.redMul(c); ++ m = i; ++ } ++ ++ return r; ++ }; ++ ++ Red.prototype.invm = function invm (a) { ++ var inv = a._invmp(this.m); ++ if (inv.negative !== 0) { ++ inv.negative = 0; ++ return this.imod(inv).redNeg(); ++ } else { ++ return this.imod(inv); ++ } ++ }; ++ ++ Red.prototype.pow = function pow (a, num) { ++ if (num.isZero()) return new BN(1); ++ if (num.cmpn(1) === 0) return a.clone(); ++ ++ var windowSize = 4; ++ var wnd = new Array(1 << windowSize); ++ wnd[0] = new BN(1).toRed(this); ++ wnd[1] = a; ++ for (var i = 2; i < wnd.length; i++) { ++ wnd[i] = this.mul(wnd[i - 1], a); ++ } ++ ++ var res = wnd[0]; ++ var current = 0; ++ var currentLen = 0; ++ var start = num.bitLength() % 26; ++ if (start === 0) { ++ start = 26; ++ } ++ ++ for (i = num.length - 1; i >= 0; i--) { ++ var word = num.words[i]; ++ for (var j = start - 1; j >= 0; j--) { ++ var bit = (word >> j) & 1; ++ if (res !== wnd[0]) { ++ res = this.sqr(res); ++ } ++ ++ if (bit === 0 && current === 0) { ++ currentLen = 0; ++ continue; ++ } ++ ++ current <<= 1; ++ current |= bit; ++ currentLen++; ++ if (currentLen !== windowSize && (i !== 0 || j !== 0)) continue; ++ ++ res = this.mul(res, wnd[current]); ++ currentLen = 0; ++ current = 0; ++ } ++ start = 26; ++ } ++ ++ return res; ++ }; ++ ++ Red.prototype.convertTo = function convertTo (num) { ++ var r = num.umod(this.m); ++ ++ return r === num ? r.clone() : r; ++ }; ++ ++ Red.prototype.convertFrom = function convertFrom (num) { ++ var res = num.clone(); ++ res.red = null; ++ return res; ++ }; ++ ++ // ++ // Montgomery method engine ++ // ++ ++ BN.mont = function mont (num) { ++ return new Mont(num); ++ }; ++ ++ function Mont (m) { ++ Red.call(this, m); ++ ++ this.shift = this.m.bitLength(); ++ if (this.shift % 26 !== 0) { ++ this.shift += 26 - (this.shift % 26); ++ } ++ ++ this.r = new BN(1).iushln(this.shift); ++ this.r2 = this.imod(this.r.sqr()); ++ this.rinv = this.r._invmp(this.m); ++ ++ this.minv = this.rinv.mul(this.r).isubn(1).div(this.m); ++ this.minv = this.minv.umod(this.r); ++ this.minv = this.r.sub(this.minv); ++ } ++ inherits(Mont, Red); ++ ++ Mont.prototype.convertTo = function convertTo (num) { ++ return this.imod(num.ushln(this.shift)); ++ }; ++ ++ Mont.prototype.convertFrom = function convertFrom (num) { ++ var r = this.imod(num.mul(this.rinv)); ++ r.red = null; ++ return r; ++ }; ++ ++ Mont.prototype.imul = function imul (a, b) { ++ if (a.isZero() || b.isZero()) { ++ a.words[0] = 0; ++ a.length = 1; ++ return a; ++ } ++ ++ var t = a.imul(b); ++ var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m); ++ var u = t.isub(c).iushrn(this.shift); ++ var res = u; ++ ++ if (u.cmp(this.m) >= 0) { ++ res = u.isub(this.m); ++ } else if (u.cmpn(0) < 0) { ++ res = u.iadd(this.m); ++ } ++ ++ return res._forceRed(this); ++ }; ++ ++ Mont.prototype.mul = function mul (a, b) { ++ if (a.isZero() || b.isZero()) return new BN(0)._forceRed(this); ++ ++ var t = a.mul(b); ++ var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m); ++ var u = t.isub(c).iushrn(this.shift); ++ var res = u; ++ if (u.cmp(this.m) >= 0) { ++ res = u.isub(this.m); ++ } else if (u.cmpn(0) < 0) { ++ res = u.iadd(this.m); ++ } ++ ++ return res._forceRed(this); ++ }; ++ ++ Mont.prototype.invm = function invm (a) { ++ // (AR)^-1 * R^2 = (A^-1 * R^-1) * R^2 = A^-1 * R ++ var res = this.imod(a._invmp(this.m).mul(this.r2)); ++ return res._forceRed(this); ++ }; ++})(typeof module === 'undefined' || module, this); ++ ++},{}],2:[function(require,module,exports){ ++'use strict'; ++ ++var elliptic = exports; ++ ++elliptic.version = require('../package.json').version; ++elliptic.utils = require('./elliptic/utils'); ++elliptic.rand = require('brorand'); ++elliptic.hmacDRBG = require('./elliptic/hmac-drbg'); ++elliptic.curve = require('./elliptic/curve'); ++elliptic.curves = require('./elliptic/curves'); ++ ++// Protocols ++elliptic.ec = require('./elliptic/ec'); ++elliptic.eddsa = require('./elliptic/eddsa'); ++ ++},{"../package.json":26,"./elliptic/curve":5,"./elliptic/curves":8,"./elliptic/ec":9,"./elliptic/eddsa":12,"./elliptic/hmac-drbg":15,"./elliptic/utils":17,"brorand":18}],3:[function(require,module,exports){ ++'use strict'; ++ ++var BN = require('bn.js'); ++var elliptic = require('../../elliptic'); ++var utils = elliptic.utils; ++var getNAF = utils.getNAF; ++var getJSF = utils.getJSF; ++var assert = utils.assert; ++ ++function BaseCurve(type, conf) { ++ this.type = type; ++ this.p = new BN(conf.p, 16); ++ ++ // Use Montgomery, when there is no fast reduction for the prime ++ this.red = conf.prime ? BN.red(conf.prime) : BN.mont(this.p); ++ ++ // Useful for many curves ++ this.zero = new BN(0).toRed(this.red); ++ this.one = new BN(1).toRed(this.red); ++ this.two = new BN(2).toRed(this.red); ++ ++ // Curve configuration, optional ++ this.n = conf.n && new BN(conf.n, 16); ++ this.g = conf.g && this.pointFromJSON(conf.g, conf.gRed); ++ ++ // Temporary arrays ++ this._wnafT1 = new Array(4); ++ this._wnafT2 = new Array(4); ++ this._wnafT3 = new Array(4); ++ this._wnafT4 = new Array(4); ++ ++ // Generalized Greg Maxwell's trick ++ var adjustCount = this.n && this.p.div(this.n); ++ if (!adjustCount || adjustCount.cmpn(100) > 0) { ++ this.redN = null; ++ } else { ++ this._maxwellTrick = true; ++ this.redN = this.n.toRed(this.red); ++ } ++} ++module.exports = BaseCurve; ++ ++BaseCurve.prototype.point = function point() { ++ throw new Error('Not implemented'); ++}; ++ ++BaseCurve.prototype.validate = function validate() { ++ throw new Error('Not implemented'); ++}; ++ ++BaseCurve.prototype._fixedNafMul = function _fixedNafMul(p, k) { ++ assert(p.precomputed); ++ var doubles = p._getDoubles(); ++ ++ var naf = getNAF(k, 1); ++ var I = (1 << (doubles.step + 1)) - (doubles.step % 2 === 0 ? 2 : 1); ++ I /= 3; ++ ++ // Translate into more windowed form ++ var repr = []; ++ for (var j = 0; j < naf.length; j += doubles.step) { ++ var nafW = 0; ++ for (var k = j + doubles.step - 1; k >= j; k--) ++ nafW = (nafW << 1) + naf[k]; ++ repr.push(nafW); ++ } ++ ++ var a = this.jpoint(null, null, null); ++ var b = this.jpoint(null, null, null); ++ for (var i = I; i > 0; i--) { ++ for (var j = 0; j < repr.length; j++) { ++ var nafW = repr[j]; ++ if (nafW === i) ++ b = b.mixedAdd(doubles.points[j]); ++ else if (nafW === -i) ++ b = b.mixedAdd(doubles.points[j].neg()); ++ } ++ a = a.add(b); ++ } ++ return a.toP(); ++}; ++ ++BaseCurve.prototype._wnafMul = function _wnafMul(p, k) { ++ var w = 4; ++ ++ // Precompute window ++ var nafPoints = p._getNAFPoints(w); ++ w = nafPoints.wnd; ++ var wnd = nafPoints.points; ++ ++ // Get NAF form ++ var naf = getNAF(k, w); ++ ++ // Add `this`*(N+1) for every w-NAF index ++ var acc = this.jpoint(null, null, null); ++ for (var i = naf.length - 1; i >= 0; i--) { ++ // Count zeroes ++ for (var k = 0; i >= 0 && naf[i] === 0; i--) ++ k++; ++ if (i >= 0) ++ k++; ++ acc = acc.dblp(k); ++ ++ if (i < 0) ++ break; ++ var z = naf[i]; ++ assert(z !== 0); ++ if (p.type === 'affine') { ++ // J +- P ++ if (z > 0) ++ acc = acc.mixedAdd(wnd[(z - 1) >> 1]); ++ else ++ acc = acc.mixedAdd(wnd[(-z - 1) >> 1].neg()); ++ } else { ++ // J +- J ++ if (z > 0) ++ acc = acc.add(wnd[(z - 1) >> 1]); ++ else ++ acc = acc.add(wnd[(-z - 1) >> 1].neg()); ++ } ++ } ++ return p.type === 'affine' ? acc.toP() : acc; ++}; ++ ++BaseCurve.prototype._wnafMulAdd = function _wnafMulAdd(defW, ++ points, ++ coeffs, ++ len, ++ jacobianResult) { ++ var wndWidth = this._wnafT1; ++ var wnd = this._wnafT2; ++ var naf = this._wnafT3; ++ ++ // Fill all arrays ++ var max = 0; ++ for (var i = 0; i < len; i++) { ++ var p = points[i]; ++ var nafPoints = p._getNAFPoints(defW); ++ wndWidth[i] = nafPoints.wnd; ++ wnd[i] = nafPoints.points; ++ } ++ ++ // Comb small window NAFs ++ for (var i = len - 1; i >= 1; i -= 2) { ++ var a = i - 1; ++ var b = i; ++ if (wndWidth[a] !== 1 || wndWidth[b] !== 1) { ++ naf[a] = getNAF(coeffs[a], wndWidth[a]); ++ naf[b] = getNAF(coeffs[b], wndWidth[b]); ++ max = Math.max(naf[a].length, max); ++ max = Math.max(naf[b].length, max); ++ continue; ++ } ++ ++ var comb = [ ++ points[a], /* 1 */ ++ null, /* 3 */ ++ null, /* 5 */ ++ points[b] /* 7 */ ++ ]; ++ ++ // Try to avoid Projective points, if possible ++ if (points[a].y.cmp(points[b].y) === 0) { ++ comb[1] = points[a].add(points[b]); ++ comb[2] = points[a].toJ().mixedAdd(points[b].neg()); ++ } else if (points[a].y.cmp(points[b].y.redNeg()) === 0) { ++ comb[1] = points[a].toJ().mixedAdd(points[b]); ++ comb[2] = points[a].add(points[b].neg()); ++ } else { ++ comb[1] = points[a].toJ().mixedAdd(points[b]); ++ comb[2] = points[a].toJ().mixedAdd(points[b].neg()); ++ } ++ ++ var index = [ ++ -3, /* -1 -1 */ ++ -1, /* -1 0 */ ++ -5, /* -1 1 */ ++ -7, /* 0 -1 */ ++ 0, /* 0 0 */ ++ 7, /* 0 1 */ ++ 5, /* 1 -1 */ ++ 1, /* 1 0 */ ++ 3 /* 1 1 */ ++ ]; ++ ++ var jsf = getJSF(coeffs[a], coeffs[b]); ++ max = Math.max(jsf[0].length, max); ++ naf[a] = new Array(max); ++ naf[b] = new Array(max); ++ for (var j = 0; j < max; j++) { ++ var ja = jsf[0][j] | 0; ++ var jb = jsf[1][j] | 0; ++ ++ naf[a][j] = index[(ja + 1) * 3 + (jb + 1)]; ++ naf[b][j] = 0; ++ wnd[a] = comb; ++ } ++ } ++ ++ var acc = this.jpoint(null, null, null); ++ var tmp = this._wnafT4; ++ for (var i = max; i >= 0; i--) { ++ var k = 0; ++ ++ while (i >= 0) { ++ var zero = true; ++ for (var j = 0; j < len; j++) { ++ tmp[j] = naf[j][i] | 0; ++ if (tmp[j] !== 0) ++ zero = false; ++ } ++ if (!zero) ++ break; ++ k++; ++ i--; ++ } ++ if (i >= 0) ++ k++; ++ acc = acc.dblp(k); ++ if (i < 0) ++ break; ++ ++ for (var j = 0; j < len; j++) { ++ var z = tmp[j]; ++ var p; ++ if (z === 0) ++ continue; ++ else if (z > 0) ++ p = wnd[j][(z - 1) >> 1]; ++ else if (z < 0) ++ p = wnd[j][(-z - 1) >> 1].neg(); ++ ++ if (p.type === 'affine') ++ acc = acc.mixedAdd(p); ++ else ++ acc = acc.add(p); ++ } ++ } ++ // Zeroify references ++ for (var i = 0; i < len; i++) ++ wnd[i] = null; ++ ++ if (jacobianResult) ++ return acc; ++ else ++ return acc.toP(); ++}; ++ ++function BasePoint(curve, type) { ++ this.curve = curve; ++ this.type = type; ++ this.precomputed = null; ++} ++BaseCurve.BasePoint = BasePoint; ++ ++BasePoint.prototype.eq = function eq(/*other*/) { ++ throw new Error('Not implemented'); ++}; ++ ++BasePoint.prototype.validate = function validate() { ++ return this.curve.validate(this); ++}; ++ ++BaseCurve.prototype.decodePoint = function decodePoint(bytes, enc) { ++ bytes = utils.toArray(bytes, enc); ++ ++ var len = this.p.byteLength(); ++ ++ // uncompressed, hybrid-odd, hybrid-even ++ if ((bytes[0] === 0x04 || bytes[0] === 0x06 || bytes[0] === 0x07) && ++ bytes.length - 1 === 2 * len) { ++ if (bytes[0] === 0x06) ++ assert(bytes[bytes.length - 1] % 2 === 0); ++ else if (bytes[0] === 0x07) ++ assert(bytes[bytes.length - 1] % 2 === 1); ++ ++ var res = this.point(bytes.slice(1, 1 + len), ++ bytes.slice(1 + len, 1 + 2 * len)); ++ ++ return res; ++ } else if ((bytes[0] === 0x02 || bytes[0] === 0x03) && ++ bytes.length - 1 === len) { ++ return this.pointFromX(bytes.slice(1, 1 + len), bytes[0] === 0x03); ++ } ++ throw new Error('Unknown point format'); ++}; ++ ++BasePoint.prototype.encodeCompressed = function encodeCompressed(enc) { ++ return this.encode(enc, true); ++}; ++ ++BasePoint.prototype._encode = function _encode(compact) { ++ var len = this.curve.p.byteLength(); ++ var x = this.getX().toArray('be', len); ++ ++ if (compact) ++ return [ this.getY().isEven() ? 0x02 : 0x03 ].concat(x); ++ ++ return [ 0x04 ].concat(x, this.getY().toArray('be', len)) ; ++}; ++ ++BasePoint.prototype.encode = function encode(enc, compact) { ++ return utils.encode(this._encode(compact), enc); ++}; ++ ++BasePoint.prototype.precompute = function precompute(power) { ++ if (this.precomputed) ++ return this; ++ ++ var precomputed = { ++ doubles: null, ++ naf: null, ++ beta: null ++ }; ++ precomputed.naf = this._getNAFPoints(8); ++ precomputed.doubles = this._getDoubles(4, power); ++ precomputed.beta = this._getBeta(); ++ this.precomputed = precomputed; ++ ++ return this; ++}; ++ ++BasePoint.prototype._hasDoubles = function _hasDoubles(k) { ++ if (!this.precomputed) ++ return false; ++ ++ var doubles = this.precomputed.doubles; ++ if (!doubles) ++ return false; ++ ++ return doubles.points.length >= Math.ceil((k.bitLength() + 1) / doubles.step); ++}; ++ ++BasePoint.prototype._getDoubles = function _getDoubles(step, power) { ++ if (this.precomputed && this.precomputed.doubles) ++ return this.precomputed.doubles; ++ ++ var doubles = [ this ]; ++ var acc = this; ++ for (var i = 0; i < power; i += step) { ++ for (var j = 0; j < step; j++) ++ acc = acc.dbl(); ++ doubles.push(acc); ++ } ++ return { ++ step: step, ++ points: doubles ++ }; ++}; ++ ++BasePoint.prototype._getNAFPoints = function _getNAFPoints(wnd) { ++ if (this.precomputed && this.precomputed.naf) ++ return this.precomputed.naf; ++ ++ var res = [ this ]; ++ var max = (1 << wnd) - 1; ++ var dbl = max === 1 ? null : this.dbl(); ++ for (var i = 1; i < max; i++) ++ res[i] = res[i - 1].add(dbl); ++ return { ++ wnd: wnd, ++ points: res ++ }; ++}; ++ ++BasePoint.prototype._getBeta = function _getBeta() { ++ return null; ++}; ++ ++BasePoint.prototype.dblp = function dblp(k) { ++ var r = this; ++ for (var i = 0; i < k; i++) ++ r = r.dbl(); ++ return r; ++}; ++ ++},{"../../elliptic":2,"bn.js":1}],4:[function(require,module,exports){ ++'use strict'; ++ ++var curve = require('../curve'); ++var elliptic = require('../../elliptic'); ++var BN = require('bn.js'); ++var inherits = require('inherits'); ++var Base = curve.base; ++ ++var assert = elliptic.utils.assert; ++ ++function EdwardsCurve(conf) { ++ // NOTE: Important as we are creating point in Base.call() ++ this.twisted = (conf.a | 0) !== 1; ++ this.mOneA = this.twisted && (conf.a | 0) === -1; ++ this.extended = this.mOneA; ++ ++ Base.call(this, 'edwards', conf); ++ ++ this.a = new BN(conf.a, 16).umod(this.red.m); ++ this.a = this.a.toRed(this.red); ++ this.c = new BN(conf.c, 16).toRed(this.red); ++ this.c2 = this.c.redSqr(); ++ this.d = new BN(conf.d, 16).toRed(this.red); ++ this.dd = this.d.redAdd(this.d); ++ ++ assert(!this.twisted || this.c.fromRed().cmpn(1) === 0); ++ this.oneC = (conf.c | 0) === 1; ++} ++inherits(EdwardsCurve, Base); ++module.exports = EdwardsCurve; ++ ++EdwardsCurve.prototype._mulA = function _mulA(num) { ++ if (this.mOneA) ++ return num.redNeg(); ++ else ++ return this.a.redMul(num); ++}; ++ ++EdwardsCurve.prototype._mulC = function _mulC(num) { ++ if (this.oneC) ++ return num; ++ else ++ return this.c.redMul(num); ++}; ++ ++// Just for compatibility with Short curve ++EdwardsCurve.prototype.jpoint = function jpoint(x, y, z, t) { ++ return this.point(x, y, z, t); ++}; ++ ++EdwardsCurve.prototype.pointFromX = function pointFromX(x, odd) { ++ x = new BN(x, 16); ++ if (!x.red) ++ x = x.toRed(this.red); ++ ++ var x2 = x.redSqr(); ++ var rhs = this.c2.redSub(this.a.redMul(x2)); ++ var lhs = this.one.redSub(this.c2.redMul(this.d).redMul(x2)); ++ ++ var y2 = rhs.redMul(lhs.redInvm()); ++ var y = y2.redSqrt(); ++ if (y.redSqr().redSub(y2).cmp(this.zero) !== 0) ++ throw new Error('invalid point'); ++ ++ var isOdd = y.fromRed().isOdd(); ++ if (odd && !isOdd || !odd && isOdd) ++ y = y.redNeg(); ++ ++ return this.point(x, y); ++}; ++ ++EdwardsCurve.prototype.pointFromY = function pointFromY(y, odd) { ++ y = new BN(y, 16); ++ if (!y.red) ++ y = y.toRed(this.red); ++ ++ // x^2 = (y^2 - 1) / (d y^2 + 1) ++ var y2 = y.redSqr(); ++ var lhs = y2.redSub(this.one); ++ var rhs = y2.redMul(this.d).redAdd(this.one); ++ var x2 = lhs.redMul(rhs.redInvm()); ++ ++ if (x2.cmp(this.zero) === 0) { ++ if (odd) ++ throw new Error('invalid point'); ++ else ++ return this.point(this.zero, y); ++ } ++ ++ var x = x2.redSqrt(); ++ if (x.redSqr().redSub(x2).cmp(this.zero) !== 0) ++ throw new Error('invalid point'); ++ ++ if (x.isOdd() !== odd) ++ x = x.redNeg(); ++ ++ return this.point(x, y); ++}; ++ ++EdwardsCurve.prototype.validate = function validate(point) { ++ if (point.isInfinity()) ++ return true; ++ ++ // Curve: A * X^2 + Y^2 = C^2 * (1 + D * X^2 * Y^2) ++ point.normalize(); ++ ++ var x2 = point.x.redSqr(); ++ var y2 = point.y.redSqr(); ++ var lhs = x2.redMul(this.a).redAdd(y2); ++ var rhs = this.c2.redMul(this.one.redAdd(this.d.redMul(x2).redMul(y2))); ++ ++ return lhs.cmp(rhs) === 0; ++}; ++ ++function Point(curve, x, y, z, t) { ++ Base.BasePoint.call(this, curve, 'projective'); ++ if (x === null && y === null && z === null) { ++ this.x = this.curve.zero; ++ this.y = this.curve.one; ++ this.z = this.curve.one; ++ this.t = this.curve.zero; ++ this.zOne = true; ++ } else { ++ this.x = new BN(x, 16); ++ this.y = new BN(y, 16); ++ this.z = z ? new BN(z, 16) : this.curve.one; ++ this.t = t && new BN(t, 16); ++ if (!this.x.red) ++ this.x = this.x.toRed(this.curve.red); ++ if (!this.y.red) ++ this.y = this.y.toRed(this.curve.red); ++ if (!this.z.red) ++ this.z = this.z.toRed(this.curve.red); ++ if (this.t && !this.t.red) ++ this.t = this.t.toRed(this.curve.red); ++ this.zOne = this.z === this.curve.one; ++ ++ // Use extended coordinates ++ if (this.curve.extended && !this.t) { ++ this.t = this.x.redMul(this.y); ++ if (!this.zOne) ++ this.t = this.t.redMul(this.z.redInvm()); ++ } ++ } ++} ++inherits(Point, Base.BasePoint); ++ ++EdwardsCurve.prototype.pointFromJSON = function pointFromJSON(obj) { ++ return Point.fromJSON(this, obj); ++}; ++ ++EdwardsCurve.prototype.point = function point(x, y, z, t) { ++ return new Point(this, x, y, z, t); ++}; ++ ++Point.fromJSON = function fromJSON(curve, obj) { ++ return new Point(curve, obj[0], obj[1], obj[2]); ++}; ++ ++Point.prototype.inspect = function inspect() { ++ if (this.isInfinity()) ++ return '<EC Point Infinity>'; ++ return '<EC Point x: ' + this.x.fromRed().toString(16, 2) + ++ ' y: ' + this.y.fromRed().toString(16, 2) + ++ ' z: ' + this.z.fromRed().toString(16, 2) + '>'; ++}; ++ ++Point.prototype.isInfinity = function isInfinity() { ++ // XXX This code assumes that zero is always zero in red ++ return this.x.cmpn(0) === 0 && ++ this.y.cmp(this.z) === 0; ++}; ++ ++Point.prototype._extDbl = function _extDbl() { ++ // hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html ++ // #doubling-dbl-2008-hwcd ++ // 4M + 4S ++ ++ // A = X1^2 ++ var a = this.x.redSqr(); ++ // B = Y1^2 ++ var b = this.y.redSqr(); ++ // C = 2 * Z1^2 ++ var c = this.z.redSqr(); ++ c = c.redIAdd(c); ++ // D = a * A ++ var d = this.curve._mulA(a); ++ // E = (X1 + Y1)^2 - A - B ++ var e = this.x.redAdd(this.y).redSqr().redISub(a).redISub(b); ++ // G = D + B ++ var g = d.redAdd(b); ++ // F = G - C ++ var f = g.redSub(c); ++ // H = D - B ++ var h = d.redSub(b); ++ // X3 = E * F ++ var nx = e.redMul(f); ++ // Y3 = G * H ++ var ny = g.redMul(h); ++ // T3 = E * H ++ var nt = e.redMul(h); ++ // Z3 = F * G ++ var nz = f.redMul(g); ++ return this.curve.point(nx, ny, nz, nt); ++}; ++ ++Point.prototype._projDbl = function _projDbl() { ++ // hyperelliptic.org/EFD/g1p/auto-twisted-projective.html ++ // #doubling-dbl-2008-bbjlp ++ // #doubling-dbl-2007-bl ++ // and others ++ // Generally 3M + 4S or 2M + 4S ++ ++ // B = (X1 + Y1)^2 ++ var b = this.x.redAdd(this.y).redSqr(); ++ // C = X1^2 ++ var c = this.x.redSqr(); ++ // D = Y1^2 ++ var d = this.y.redSqr(); ++ ++ var nx; ++ var ny; ++ var nz; ++ if (this.curve.twisted) { ++ // E = a * C ++ var e = this.curve._mulA(c); ++ // F = E + D ++ var f = e.redAdd(d); ++ if (this.zOne) { ++ // X3 = (B - C - D) * (F - 2) ++ nx = b.redSub(c).redSub(d).redMul(f.redSub(this.curve.two)); ++ // Y3 = F * (E - D) ++ ny = f.redMul(e.redSub(d)); ++ // Z3 = F^2 - 2 * F ++ nz = f.redSqr().redSub(f).redSub(f); ++ } else { ++ // H = Z1^2 ++ var h = this.z.redSqr(); ++ // J = F - 2 * H ++ var j = f.redSub(h).redISub(h); ++ // X3 = (B-C-D)*J ++ nx = b.redSub(c).redISub(d).redMul(j); ++ // Y3 = F * (E - D) ++ ny = f.redMul(e.redSub(d)); ++ // Z3 = F * J ++ nz = f.redMul(j); ++ } ++ } else { ++ // E = C + D ++ var e = c.redAdd(d); ++ // H = (c * Z1)^2 ++ var h = this.curve._mulC(this.c.redMul(this.z)).redSqr(); ++ // J = E - 2 * H ++ var j = e.redSub(h).redSub(h); ++ // X3 = c * (B - E) * J ++ nx = this.curve._mulC(b.redISub(e)).redMul(j); ++ // Y3 = c * E * (C - D) ++ ny = this.curve._mulC(e).redMul(c.redISub(d)); ++ // Z3 = E * J ++ nz = e.redMul(j); ++ } ++ return this.curve.point(nx, ny, nz); ++}; ++ ++Point.prototype.dbl = function dbl() { ++ if (this.isInfinity()) ++ return this; ++ ++ // Double in extended coordinates ++ if (this.curve.extended) ++ return this._extDbl(); ++ else ++ return this._projDbl(); ++}; ++ ++Point.prototype._extAdd = function _extAdd(p) { ++ // hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html ++ // #addition-add-2008-hwcd-3 ++ // 8M ++ ++ // A = (Y1 - X1) * (Y2 - X2) ++ var a = this.y.redSub(this.x).redMul(p.y.redSub(p.x)); ++ // B = (Y1 + X1) * (Y2 + X2) ++ var b = this.y.redAdd(this.x).redMul(p.y.redAdd(p.x)); ++ // C = T1 * k * T2 ++ var c = this.t.redMul(this.curve.dd).redMul(p.t); ++ // D = Z1 * 2 * Z2 ++ var d = this.z.redMul(p.z.redAdd(p.z)); ++ // E = B - A ++ var e = b.redSub(a); ++ // F = D - C ++ var f = d.redSub(c); ++ // G = D + C ++ var g = d.redAdd(c); ++ // H = B + A ++ var h = b.redAdd(a); ++ // X3 = E * F ++ var nx = e.redMul(f); ++ // Y3 = G * H ++ var ny = g.redMul(h); ++ // T3 = E * H ++ var nt = e.redMul(h); ++ // Z3 = F * G ++ var nz = f.redMul(g); ++ return this.curve.point(nx, ny, nz, nt); ++}; ++ ++Point.prototype._projAdd = function _projAdd(p) { ++ // hyperelliptic.org/EFD/g1p/auto-twisted-projective.html ++ // #addition-add-2008-bbjlp ++ // #addition-add-2007-bl ++ // 10M + 1S ++ ++ // A = Z1 * Z2 ++ var a = this.z.redMul(p.z); ++ // B = A^2 ++ var b = a.redSqr(); ++ // C = X1 * X2 ++ var c = this.x.redMul(p.x); ++ // D = Y1 * Y2 ++ var d = this.y.redMul(p.y); ++ // E = d * C * D ++ var e = this.curve.d.redMul(c).redMul(d); ++ // F = B - E ++ var f = b.redSub(e); ++ // G = B + E ++ var g = b.redAdd(e); ++ // X3 = A * F * ((X1 + Y1) * (X2 + Y2) - C - D) ++ var tmp = this.x.redAdd(this.y).redMul(p.x.redAdd(p.y)).redISub(c).redISub(d); ++ var nx = a.redMul(f).redMul(tmp); ++ var ny; ++ var nz; ++ if (this.curve.twisted) { ++ // Y3 = A * G * (D - a * C) ++ ny = a.redMul(g).redMul(d.redSub(this.curve._mulA(c))); ++ // Z3 = F * G ++ nz = f.redMul(g); ++ } else { ++ // Y3 = A * G * (D - C) ++ ny = a.redMul(g).redMul(d.redSub(c)); ++ // Z3 = c * F * G ++ nz = this.curve._mulC(f).redMul(g); ++ } ++ return this.curve.point(nx, ny, nz); ++}; ++ ++Point.prototype.add = function add(p) { ++ if (this.isInfinity()) ++ return p; ++ if (p.isInfinity()) ++ return this; ++ ++ if (this.curve.extended) ++ return this._extAdd(p); ++ else ++ return this._projAdd(p); ++}; ++ ++Point.prototype.mul = function mul(k) { ++ if (this._hasDoubles(k)) ++ return this.curve._fixedNafMul(this, k); ++ else ++ return this.curve._wnafMul(this, k); ++}; ++ ++Point.prototype.mulAdd = function mulAdd(k1, p, k2) { ++ return this.curve._wnafMulAdd(1, [ this, p ], [ k1, k2 ], 2, false); ++}; ++ ++Point.prototype.jmulAdd = function jmulAdd(k1, p, k2) { ++ return this.curve._wnafMulAdd(1, [ this, p ], [ k1, k2 ], 2, true); ++}; ++ ++Point.prototype.normalize = function normalize() { ++ if (this.zOne) ++ return this; ++ ++ // Normalize coordinates ++ var zi = this.z.redInvm(); ++ this.x = this.x.redMul(zi); ++ this.y = this.y.redMul(zi); ++ if (this.t) ++ this.t = this.t.redMul(zi); ++ this.z = this.curve.one; ++ this.zOne = true; ++ return this; ++}; ++ ++Point.prototype.neg = function neg() { ++ return this.curve.point(this.x.redNeg(), ++ this.y, ++ this.z, ++ this.t && this.t.redNeg()); ++}; ++ ++Point.prototype.getX = function getX() { ++ this.normalize(); ++ return this.x.fromRed(); ++}; ++ ++Point.prototype.getY = function getY() { ++ this.normalize(); ++ return this.y.fromRed(); ++}; ++ ++Point.prototype.eq = function eq(other) { ++ return this === other || ++ this.getX().cmp(other.getX()) === 0 && ++ this.getY().cmp(other.getY()) === 0; ++}; ++ ++Point.prototype.eqXToP = function eqXToP(x) { ++ var rx = x.toRed(this.curve.red).redMul(this.z); ++ if (this.x.cmp(rx) === 0) ++ return true; ++ ++ var xc = x.clone(); ++ var t = this.curve.redN.redMul(this.z); ++ for (;;) { ++ xc.iadd(this.curve.n); ++ if (xc.cmp(this.curve.p) >= 0) ++ return false; ++ ++ rx.redIAdd(t); ++ if (this.x.cmp(rx) === 0) ++ return true; ++ } ++ return false; ++}; ++ ++// Compatibility with BaseCurve ++Point.prototype.toP = Point.prototype.normalize; ++Point.prototype.mixedAdd = Point.prototype.add; ++ ++},{"../../elliptic":2,"../curve":5,"bn.js":1,"inherits":25}],5:[function(require,module,exports){ ++'use strict'; ++ ++var curve = exports; ++ ++curve.base = require('./base'); ++curve.short = require('./short'); ++curve.mont = require('./mont'); ++curve.edwards = require('./edwards'); ++ ++},{"./base":3,"./edwards":4,"./mont":6,"./short":7}],6:[function(require,module,exports){ ++'use strict'; ++ ++var curve = require('../curve'); ++var BN = require('bn.js'); ++var inherits = require('inherits'); ++var Base = curve.base; ++ ++var elliptic = require('../../elliptic'); ++var utils = elliptic.utils; ++ ++function MontCurve(conf) { ++ Base.call(this, 'mont', conf); ++ ++ this.a = new BN(conf.a, 16).toRed(this.red); ++ this.b = new BN(conf.b, 16).toRed(this.red); ++ this.i4 = new BN(4).toRed(this.red).redInvm(); ++ this.two = new BN(2).toRed(this.red); ++ this.a24 = this.i4.redMul(this.a.redAdd(this.two)); ++} ++inherits(MontCurve, Base); ++module.exports = MontCurve; ++ ++MontCurve.prototype.validate = function validate(point) { ++ var x = point.normalize().x; ++ var x2 = x.redSqr(); ++ var rhs = x2.redMul(x).redAdd(x2.redMul(this.a)).redAdd(x); ++ var y = rhs.redSqrt(); ++ ++ return y.redSqr().cmp(rhs) === 0; ++}; ++ ++function Point(curve, x, z) { ++ Base.BasePoint.call(this, curve, 'projective'); ++ if (x === null && z === null) { ++ this.x = this.curve.one; ++ this.z = this.curve.zero; ++ } else { ++ this.x = new BN(x, 16); ++ this.z = new BN(z, 16); ++ if (!this.x.red) ++ this.x = this.x.toRed(this.curve.red); ++ if (!this.z.red) ++ this.z = this.z.toRed(this.curve.red); ++ } ++} ++inherits(Point, Base.BasePoint); ++ ++MontCurve.prototype.decodePoint = function decodePoint(bytes, enc) { ++ return this.point(utils.toArray(bytes, enc), 1); ++}; ++ ++MontCurve.prototype.point = function point(x, z) { ++ return new Point(this, x, z); ++}; ++ ++MontCurve.prototype.pointFromJSON = function pointFromJSON(obj) { ++ return Point.fromJSON(this, obj); ++}; ++ ++Point.prototype.precompute = function precompute() { ++ // No-op ++}; ++ ++Point.prototype._encode = function _encode() { ++ return this.getX().toArray('be', this.curve.p.byteLength()); ++}; ++ ++Point.fromJSON = function fromJSON(curve, obj) { ++ return new Point(curve, obj[0], obj[1] || curve.one); ++}; ++ ++Point.prototype.inspect = function inspect() { ++ if (this.isInfinity()) ++ return '<EC Point Infinity>'; ++ return '<EC Point x: ' + this.x.fromRed().toString(16, 2) + ++ ' z: ' + this.z.fromRed().toString(16, 2) + '>'; ++}; ++ ++Point.prototype.isInfinity = function isInfinity() { ++ // XXX This code assumes that zero is always zero in red ++ return this.z.cmpn(0) === 0; ++}; ++ ++Point.prototype.dbl = function dbl() { ++ // http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#doubling-dbl-1987-m-3 ++ // 2M + 2S + 4A ++ ++ // A = X1 + Z1 ++ var a = this.x.redAdd(this.z); ++ // AA = A^2 ++ var aa = a.redSqr(); ++ // B = X1 - Z1 ++ var b = this.x.redSub(this.z); ++ // BB = B^2 ++ var bb = b.redSqr(); ++ // C = AA - BB ++ var c = aa.redSub(bb); ++ // X3 = AA * BB ++ var nx = aa.redMul(bb); ++ // Z3 = C * (BB + A24 * C) ++ var nz = c.redMul(bb.redAdd(this.curve.a24.redMul(c))); ++ return this.curve.point(nx, nz); ++}; ++ ++Point.prototype.add = function add() { ++ throw new Error('Not supported on Montgomery curve'); ++}; ++ ++Point.prototype.diffAdd = function diffAdd(p, diff) { ++ // http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#diffadd-dadd-1987-m-3 ++ // 4M + 2S + 6A ++ ++ // A = X2 + Z2 ++ var a = this.x.redAdd(this.z); ++ // B = X2 - Z2 ++ var b = this.x.redSub(this.z); ++ // C = X3 + Z3 ++ var c = p.x.redAdd(p.z); ++ // D = X3 - Z3 ++ var d = p.x.redSub(p.z); ++ // DA = D * A ++ var da = d.redMul(a); ++ // CB = C * B ++ var cb = c.redMul(b); ++ // X5 = Z1 * (DA + CB)^2 ++ var nx = diff.z.redMul(da.redAdd(cb).redSqr()); ++ // Z5 = X1 * (DA - CB)^2 ++ var nz = diff.x.redMul(da.redISub(cb).redSqr()); ++ return this.curve.point(nx, nz); ++}; ++ ++Point.prototype.mul = function mul(k) { ++ var t = k.clone(); ++ var a = this; // (N / 2) * Q + Q ++ var b = this.curve.point(null, null); // (N / 2) * Q ++ var c = this; // Q ++ ++ for (var bits = []; t.cmpn(0) !== 0; t.iushrn(1)) ++ bits.push(t.andln(1)); ++ ++ for (var i = bits.length - 1; i >= 0; i--) { ++ if (bits[i] === 0) { ++ // N * Q + Q = ((N / 2) * Q + Q)) + (N / 2) * Q ++ a = a.diffAdd(b, c); ++ // N * Q = 2 * ((N / 2) * Q + Q)) ++ b = b.dbl(); ++ } else { ++ // N * Q = ((N / 2) * Q + Q) + ((N / 2) * Q) ++ b = a.diffAdd(b, c); ++ // N * Q + Q = 2 * ((N / 2) * Q + Q) ++ a = a.dbl(); ++ } ++ } ++ return b; ++}; ++ ++Point.prototype.mulAdd = function mulAdd() { ++ throw new Error('Not supported on Montgomery curve'); ++}; ++ ++Point.prototype.jumlAdd = function jumlAdd() { ++ throw new Error('Not supported on Montgomery curve'); ++}; ++ ++Point.prototype.eq = function eq(other) { ++ return this.getX().cmp(other.getX()) === 0; ++}; ++ ++Point.prototype.normalize = function normalize() { ++ this.x = this.x.redMul(this.z.redInvm()); ++ this.z = this.curve.one; ++ return this; ++}; ++ ++Point.prototype.getX = function getX() { ++ // Normalize coordinates ++ this.normalize(); ++ ++ return this.x.fromRed(); ++}; ++ ++},{"../../elliptic":2,"../curve":5,"bn.js":1,"inherits":25}],7:[function(require,module,exports){ ++'use strict'; ++ ++var curve = require('../curve'); ++var elliptic = require('../../elliptic'); ++var BN = require('bn.js'); ++var inherits = require('inherits'); ++var Base = curve.base; ++ ++var assert = elliptic.utils.assert; ++ ++function ShortCurve(conf) { ++ Base.call(this, 'short', conf); ++ ++ this.a = new BN(conf.a, 16).toRed(this.red); ++ this.b = new BN(conf.b, 16).toRed(this.red); ++ this.tinv = this.two.redInvm(); ++ ++ this.zeroA = this.a.fromRed().cmpn(0) === 0; ++ this.threeA = this.a.fromRed().sub(this.p).cmpn(-3) === 0; ++ ++ // If the curve is endomorphic, precalculate beta and lambda ++ this.endo = this._getEndomorphism(conf); ++ this._endoWnafT1 = new Array(4); ++ this._endoWnafT2 = new Array(4); ++} ++inherits(ShortCurve, Base); ++module.exports = ShortCurve; ++ ++ShortCurve.prototype._getEndomorphism = function _getEndomorphism(conf) { ++ // No efficient endomorphism ++ if (!this.zeroA || !this.g || !this.n || this.p.modn(3) !== 1) ++ return; ++ ++ // Compute beta and lambda, that lambda * P = (beta * Px; Py) ++ var beta; ++ var lambda; ++ if (conf.beta) { ++ beta = new BN(conf.beta, 16).toRed(this.red); ++ } else { ++ var betas = this._getEndoRoots(this.p); ++ // Choose the smallest beta ++ beta = betas[0].cmp(betas[1]) < 0 ? betas[0] : betas[1]; ++ beta = beta.toRed(this.red); ++ } ++ if (conf.lambda) { ++ lambda = new BN(conf.lambda, 16); ++ } else { ++ // Choose the lambda that is matching selected beta ++ var lambdas = this._getEndoRoots(this.n); ++ if (this.g.mul(lambdas[0]).x.cmp(this.g.x.redMul(beta)) === 0) { ++ lambda = lambdas[0]; ++ } else { ++ lambda = lambdas[1]; ++ assert(this.g.mul(lambda).x.cmp(this.g.x.redMul(beta)) === 0); ++ } ++ } ++ ++ // Get basis vectors, used for balanced length-two representation ++ var basis; ++ if (conf.basis) { ++ basis = conf.basis.map(function(vec) { ++ return { ++ a: new BN(vec.a, 16), ++ b: new BN(vec.b, 16) ++ }; ++ }); ++ } else { ++ basis = this._getEndoBasis(lambda); ++ } ++ ++ return { ++ beta: beta, ++ lambda: lambda, ++ basis: basis ++ }; ++}; ++ ++ShortCurve.prototype._getEndoRoots = function _getEndoRoots(num) { ++ // Find roots of for x^2 + x + 1 in F ++ // Root = (-1 +- Sqrt(-3)) / 2 ++ // ++ var red = num === this.p ? this.red : BN.mont(num); ++ var tinv = new BN(2).toRed(red).redInvm(); ++ var ntinv = tinv.redNeg(); ++ ++ var s = new BN(3).toRed(red).redNeg().redSqrt().redMul(tinv); ++ ++ var l1 = ntinv.redAdd(s).fromRed(); ++ var l2 = ntinv.redSub(s).fromRed(); ++ return [ l1, l2 ]; ++}; ++ ++ShortCurve.prototype._getEndoBasis = function _getEndoBasis(lambda) { ++ // aprxSqrt >= sqrt(this.n) ++ var aprxSqrt = this.n.ushrn(Math.floor(this.n.bitLength() / 2)); ++ ++ // 3.74 ++ // Run EGCD, until r(L + 1) < aprxSqrt ++ var u = lambda; ++ var v = this.n.clone(); ++ var x1 = new BN(1); ++ var y1 = new BN(0); ++ var x2 = new BN(0); ++ var y2 = new BN(1); ++ ++ // NOTE: all vectors are roots of: a + b * lambda = 0 (mod n) ++ var a0; ++ var b0; ++ // First vector ++ var a1; ++ var b1; ++ // Second vector ++ var a2; ++ var b2; ++ ++ var prevR; ++ var i = 0; ++ var r; ++ var x; ++ while (u.cmpn(0) !== 0) { ++ var q = v.div(u); ++ r = v.sub(q.mul(u)); ++ x = x2.sub(q.mul(x1)); ++ var y = y2.sub(q.mul(y1)); ++ ++ if (!a1 && r.cmp(aprxSqrt) < 0) { ++ a0 = prevR.neg(); ++ b0 = x1; ++ a1 = r.neg(); ++ b1 = x; ++ } else if (a1 && ++i === 2) { ++ break; ++ } ++ prevR = r; ++ ++ v = u; ++ u = r; ++ x2 = x1; ++ x1 = x; ++ y2 = y1; ++ y1 = y; ++ } ++ a2 = r.neg(); ++ b2 = x; ++ ++ var len1 = a1.sqr().add(b1.sqr()); ++ var len2 = a2.sqr().add(b2.sqr()); ++ if (len2.cmp(len1) >= 0) { ++ a2 = a0; ++ b2 = b0; ++ } ++ ++ // Normalize signs ++ if (a1.negative) { ++ a1 = a1.neg(); ++ b1 = b1.neg(); ++ } ++ if (a2.negative) { ++ a2 = a2.neg(); ++ b2 = b2.neg(); ++ } ++ ++ return [ ++ { a: a1, b: b1 }, ++ { a: a2, b: b2 } ++ ]; ++}; ++ ++ShortCurve.prototype._endoSplit = function _endoSplit(k) { ++ var basis = this.endo.basis; ++ var v1 = basis[0]; ++ var v2 = basis[1]; ++ ++ var c1 = v2.b.mul(k).divRound(this.n); ++ var c2 = v1.b.neg().mul(k).divRound(this.n); ++ ++ var p1 = c1.mul(v1.a); ++ var p2 = c2.mul(v2.a); ++ var q1 = c1.mul(v1.b); ++ var q2 = c2.mul(v2.b); ++ ++ // Calculate answer ++ var k1 = k.sub(p1).sub(p2); ++ var k2 = q1.add(q2).neg(); ++ return { k1: k1, k2: k2 }; ++}; ++ ++ShortCurve.prototype.pointFromX = function pointFromX(x, odd) { ++ x = new BN(x, 16); ++ if (!x.red) ++ x = x.toRed(this.red); ++ ++ var y2 = x.redSqr().redMul(x).redIAdd(x.redMul(this.a)).redIAdd(this.b); ++ var y = y2.redSqrt(); ++ if (y.redSqr().redSub(y2).cmp(this.zero) !== 0) ++ throw new Error('invalid point'); ++ ++ // XXX Is there any way to tell if the number is odd without converting it ++ // to non-red form? ++ var isOdd = y.fromRed().isOdd(); ++ if (odd && !isOdd || !odd && isOdd) ++ y = y.redNeg(); ++ ++ return this.point(x, y); ++}; ++ ++ShortCurve.prototype.validate = function validate(point) { ++ if (point.inf) ++ return true; ++ ++ var x = point.x; ++ var y = point.y; ++ ++ var ax = this.a.redMul(x); ++ var rhs = x.redSqr().redMul(x).redIAdd(ax).redIAdd(this.b); ++ return y.redSqr().redISub(rhs).cmpn(0) === 0; ++}; ++ ++ShortCurve.prototype._endoWnafMulAdd = ++ function _endoWnafMulAdd(points, coeffs, jacobianResult) { ++ var npoints = this._endoWnafT1; ++ var ncoeffs = this._endoWnafT2; ++ for (var i = 0; i < points.length; i++) { ++ var split = this._endoSplit(coeffs[i]); ++ var p = points[i]; ++ var beta = p._getBeta(); ++ ++ if (split.k1.negative) { ++ split.k1.ineg(); ++ p = p.neg(true); ++ } ++ if (split.k2.negative) { ++ split.k2.ineg(); ++ beta = beta.neg(true); ++ } ++ ++ npoints[i * 2] = p; ++ npoints[i * 2 + 1] = beta; ++ ncoeffs[i * 2] = split.k1; ++ ncoeffs[i * 2 + 1] = split.k2; ++ } ++ var res = this._wnafMulAdd(1, npoints, ncoeffs, i * 2, jacobianResult); ++ ++ // Clean-up references to points and coefficients ++ for (var j = 0; j < i * 2; j++) { ++ npoints[j] = null; ++ ncoeffs[j] = null; ++ } ++ return res; ++}; ++ ++function Point(curve, x, y, isRed) { ++ Base.BasePoint.call(this, curve, 'affine'); ++ if (x === null && y === null) { ++ this.x = null; ++ this.y = null; ++ this.inf = true; ++ } else { ++ this.x = new BN(x, 16); ++ this.y = new BN(y, 16); ++ // Force redgomery representation when loading from JSON ++ if (isRed) { ++ this.x.forceRed(this.curve.red); ++ this.y.forceRed(this.curve.red); ++ } ++ if (!this.x.red) ++ this.x = this.x.toRed(this.curve.red); ++ if (!this.y.red) ++ this.y = this.y.toRed(this.curve.red); ++ this.inf = false; ++ } ++} ++inherits(Point, Base.BasePoint); ++ ++ShortCurve.prototype.point = function point(x, y, isRed) { ++ return new Point(this, x, y, isRed); ++}; ++ ++ShortCurve.prototype.pointFromJSON = function pointFromJSON(obj, red) { ++ return Point.fromJSON(this, obj, red); ++}; ++ ++Point.prototype._getBeta = function _getBeta() { ++ if (!this.curve.endo) ++ return; ++ ++ var pre = this.precomputed; ++ if (pre && pre.beta) ++ return pre.beta; ++ ++ var beta = this.curve.point(this.x.redMul(this.curve.endo.beta), this.y); ++ if (pre) { ++ var curve = this.curve; ++ var endoMul = function(p) { ++ return curve.point(p.x.redMul(curve.endo.beta), p.y); ++ }; ++ pre.beta = beta; ++ beta.precomputed = { ++ beta: null, ++ naf: pre.naf && { ++ wnd: pre.naf.wnd, ++ points: pre.naf.points.map(endoMul) ++ }, ++ doubles: pre.doubles && { ++ step: pre.doubles.step, ++ points: pre.doubles.points.map(endoMul) ++ } ++ }; ++ } ++ return beta; ++}; ++ ++Point.prototype.toJSON = function toJSON() { ++ if (!this.precomputed) ++ return [ this.x, this.y ]; ++ ++ return [ this.x, this.y, this.precomputed && { ++ doubles: this.precomputed.doubles && { ++ step: this.precomputed.doubles.step, ++ points: this.precomputed.doubles.points.slice(1) ++ }, ++ naf: this.precomputed.naf && { ++ wnd: this.precomputed.naf.wnd, ++ points: this.precomputed.naf.points.slice(1) ++ } ++ } ]; ++}; ++ ++Point.fromJSON = function fromJSON(curve, obj, red) { ++ if (typeof obj === 'string') ++ obj = JSON.parse(obj); ++ var res = curve.point(obj[0], obj[1], red); ++ if (!obj[2]) ++ return res; ++ ++ function obj2point(obj) { ++ return curve.point(obj[0], obj[1], red); ++ } ++ ++ var pre = obj[2]; ++ res.precomputed = { ++ beta: null, ++ doubles: pre.doubles && { ++ step: pre.doubles.step, ++ points: [ res ].concat(pre.doubles.points.map(obj2point)) ++ }, ++ naf: pre.naf && { ++ wnd: pre.naf.wnd, ++ points: [ res ].concat(pre.naf.points.map(obj2point)) ++ } ++ }; ++ return res; ++}; ++ ++Point.prototype.inspect = function inspect() { ++ if (this.isInfinity()) ++ return '<EC Point Infinity>'; ++ return '<EC Point x: ' + this.x.fromRed().toString(16, 2) + ++ ' y: ' + this.y.fromRed().toString(16, 2) + '>'; ++}; ++ ++Point.prototype.isInfinity = function isInfinity() { ++ return this.inf; ++}; ++ ++Point.prototype.add = function add(p) { ++ // O + P = P ++ if (this.inf) ++ return p; ++ ++ // P + O = P ++ if (p.inf) ++ return this; ++ ++ // P + P = 2P ++ if (this.eq(p)) ++ return this.dbl(); ++ ++ // P + (-P) = O ++ if (this.neg().eq(p)) ++ return this.curve.point(null, null); ++ ++ // P + Q = O ++ if (this.x.cmp(p.x) === 0) ++ return this.curve.point(null, null); ++ ++ var c = this.y.redSub(p.y); ++ if (c.cmpn(0) !== 0) ++ c = c.redMul(this.x.redSub(p.x).redInvm()); ++ var nx = c.redSqr().redISub(this.x).redISub(p.x); ++ var ny = c.redMul(this.x.redSub(nx)).redISub(this.y); ++ return this.curve.point(nx, ny); ++}; ++ ++Point.prototype.dbl = function dbl() { ++ if (this.inf) ++ return this; ++ ++ // 2P = O ++ var ys1 = this.y.redAdd(this.y); ++ if (ys1.cmpn(0) === 0) ++ return this.curve.point(null, null); ++ ++ var a = this.curve.a; ++ ++ var x2 = this.x.redSqr(); ++ var dyinv = ys1.redInvm(); ++ var c = x2.redAdd(x2).redIAdd(x2).redIAdd(a).redMul(dyinv); ++ ++ var nx = c.redSqr().redISub(this.x.redAdd(this.x)); ++ var ny = c.redMul(this.x.redSub(nx)).redISub(this.y); ++ return this.curve.point(nx, ny); ++}; ++ ++Point.prototype.getX = function getX() { ++ return this.x.fromRed(); ++}; ++ ++Point.prototype.getY = function getY() { ++ return this.y.fromRed(); ++}; ++ ++Point.prototype.mul = function mul(k) { ++ k = new BN(k, 16); ++ ++ if (this._hasDoubles(k)) ++ return this.curve._fixedNafMul(this, k); ++ else if (this.curve.endo) ++ return this.curve._endoWnafMulAdd([ this ], [ k ]); ++ else ++ return this.curve._wnafMul(this, k); ++}; ++ ++Point.prototype.mulAdd = function mulAdd(k1, p2, k2) { ++ var points = [ this, p2 ]; ++ var coeffs = [ k1, k2 ]; ++ if (this.curve.endo) ++ return this.curve._endoWnafMulAdd(points, coeffs); ++ else ++ return this.curve._wnafMulAdd(1, points, coeffs, 2); ++}; ++ ++Point.prototype.jmulAdd = function jmulAdd(k1, p2, k2) { ++ var points = [ this, p2 ]; ++ var coeffs = [ k1, k2 ]; ++ if (this.curve.endo) ++ return this.curve._endoWnafMulAdd(points, coeffs, true); ++ else ++ return this.curve._wnafMulAdd(1, points, coeffs, 2, true); ++}; ++ ++Point.prototype.eq = function eq(p) { ++ return this === p || ++ this.inf === p.inf && ++ (this.inf || this.x.cmp(p.x) === 0 && this.y.cmp(p.y) === 0); ++}; ++ ++Point.prototype.neg = function neg(_precompute) { ++ if (this.inf) ++ return this; ++ ++ var res = this.curve.point(this.x, this.y.redNeg()); ++ if (_precompute && this.precomputed) { ++ var pre = this.precomputed; ++ var negate = function(p) { ++ return p.neg(); ++ }; ++ res.precomputed = { ++ naf: pre.naf && { ++ wnd: pre.naf.wnd, ++ points: pre.naf.points.map(negate) ++ }, ++ doubles: pre.doubles && { ++ step: pre.doubles.step, ++ points: pre.doubles.points.map(negate) ++ } ++ }; ++ } ++ return res; ++}; ++ ++Point.prototype.toJ = function toJ() { ++ if (this.inf) ++ return this.curve.jpoint(null, null, null); ++ ++ var res = this.curve.jpoint(this.x, this.y, this.curve.one); ++ return res; ++}; ++ ++function JPoint(curve, x, y, z) { ++ Base.BasePoint.call(this, curve, 'jacobian'); ++ if (x === null && y === null && z === null) { ++ this.x = this.curve.one; ++ this.y = this.curve.one; ++ this.z = new BN(0); ++ } else { ++ this.x = new BN(x, 16); ++ this.y = new BN(y, 16); ++ this.z = new BN(z, 16); ++ } ++ if (!this.x.red) ++ this.x = this.x.toRed(this.curve.red); ++ if (!this.y.red) ++ this.y = this.y.toRed(this.curve.red); ++ if (!this.z.red) ++ this.z = this.z.toRed(this.curve.red); ++ ++ this.zOne = this.z === this.curve.one; ++} ++inherits(JPoint, Base.BasePoint); ++ ++ShortCurve.prototype.jpoint = function jpoint(x, y, z) { ++ return new JPoint(this, x, y, z); ++}; ++ ++JPoint.prototype.toP = function toP() { ++ if (this.isInfinity()) ++ return this.curve.point(null, null); ++ ++ var zinv = this.z.redInvm(); ++ var zinv2 = zinv.redSqr(); ++ var ax = this.x.redMul(zinv2); ++ var ay = this.y.redMul(zinv2).redMul(zinv); ++ ++ return this.curve.point(ax, ay); ++}; ++ ++JPoint.prototype.neg = function neg() { ++ return this.curve.jpoint(this.x, this.y.redNeg(), this.z); ++}; ++ ++JPoint.prototype.add = function add(p) { ++ // O + P = P ++ if (this.isInfinity()) ++ return p; ++ ++ // P + O = P ++ if (p.isInfinity()) ++ return this; ++ ++ // 12M + 4S + 7A ++ var pz2 = p.z.redSqr(); ++ var z2 = this.z.redSqr(); ++ var u1 = this.x.redMul(pz2); ++ var u2 = p.x.redMul(z2); ++ var s1 = this.y.redMul(pz2.redMul(p.z)); ++ var s2 = p.y.redMul(z2.redMul(this.z)); ++ ++ var h = u1.redSub(u2); ++ var r = s1.redSub(s2); ++ if (h.cmpn(0) === 0) { ++ if (r.cmpn(0) !== 0) ++ return this.curve.jpoint(null, null, null); ++ else ++ return this.dbl(); ++ } ++ ++ var h2 = h.redSqr(); ++ var h3 = h2.redMul(h); ++ var v = u1.redMul(h2); ++ ++ var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v); ++ var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3)); ++ var nz = this.z.redMul(p.z).redMul(h); ++ ++ return this.curve.jpoint(nx, ny, nz); ++}; ++ ++JPoint.prototype.mixedAdd = function mixedAdd(p) { ++ // O + P = P ++ if (this.isInfinity()) ++ return p.toJ(); ++ ++ // P + O = P ++ if (p.isInfinity()) ++ return this; ++ ++ // 8M + 3S + 7A ++ var z2 = this.z.redSqr(); ++ var u1 = this.x; ++ var u2 = p.x.redMul(z2); ++ var s1 = this.y; ++ var s2 = p.y.redMul(z2).redMul(this.z); ++ ++ var h = u1.redSub(u2); ++ var r = s1.redSub(s2); ++ if (h.cmpn(0) === 0) { ++ if (r.cmpn(0) !== 0) ++ return this.curve.jpoint(null, null, null); ++ else ++ return this.dbl(); ++ } ++ ++ var h2 = h.redSqr(); ++ var h3 = h2.redMul(h); ++ var v = u1.redMul(h2); ++ ++ var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v); ++ var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3)); ++ var nz = this.z.redMul(h); ++ ++ return this.curve.jpoint(nx, ny, nz); ++}; ++ ++JPoint.prototype.dblp = function dblp(pow) { ++ if (pow === 0) ++ return this; ++ if (this.isInfinity()) ++ return this; ++ if (!pow) ++ return this.dbl(); ++ ++ if (this.curve.zeroA || this.curve.threeA) { ++ var r = this; ++ for (var i = 0; i < pow; i++) ++ r = r.dbl(); ++ return r; ++ } ++ ++ // 1M + 2S + 1A + N * (4S + 5M + 8A) ++ // N = 1 => 6M + 6S + 9A ++ var a = this.curve.a; ++ var tinv = this.curve.tinv; ++ ++ var jx = this.x; ++ var jy = this.y; ++ var jz = this.z; ++ var jz4 = jz.redSqr().redSqr(); ++ ++ // Reuse results ++ var jyd = jy.redAdd(jy); ++ for (var i = 0; i < pow; i++) { ++ var jx2 = jx.redSqr(); ++ var jyd2 = jyd.redSqr(); ++ var jyd4 = jyd2.redSqr(); ++ var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4)); ++ ++ var t1 = jx.redMul(jyd2); ++ var nx = c.redSqr().redISub(t1.redAdd(t1)); ++ var t2 = t1.redISub(nx); ++ var dny = c.redMul(t2); ++ dny = dny.redIAdd(dny).redISub(jyd4); ++ var nz = jyd.redMul(jz); ++ if (i + 1 < pow) ++ jz4 = jz4.redMul(jyd4); ++ ++ jx = nx; ++ jz = nz; ++ jyd = dny; ++ } ++ ++ return this.curve.jpoint(jx, jyd.redMul(tinv), jz); ++}; ++ ++JPoint.prototype.dbl = function dbl() { ++ if (this.isInfinity()) ++ return this; ++ ++ if (this.curve.zeroA) ++ return this._zeroDbl(); ++ else if (this.curve.threeA) ++ return this._threeDbl(); ++ else ++ return this._dbl(); ++}; ++ ++JPoint.prototype._zeroDbl = function _zeroDbl() { ++ var nx; ++ var ny; ++ var nz; ++ // Z = 1 ++ if (this.zOne) { ++ // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html ++ // #doubling-mdbl-2007-bl ++ // 1M + 5S + 14A ++ ++ // XX = X1^2 ++ var xx = this.x.redSqr(); ++ // YY = Y1^2 ++ var yy = this.y.redSqr(); ++ // YYYY = YY^2 ++ var yyyy = yy.redSqr(); ++ // S = 2 * ((X1 + YY)^2 - XX - YYYY) ++ var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy); ++ s = s.redIAdd(s); ++ // M = 3 * XX + a; a = 0 ++ var m = xx.redAdd(xx).redIAdd(xx); ++ // T = M ^ 2 - 2*S ++ var t = m.redSqr().redISub(s).redISub(s); ++ ++ // 8 * YYYY ++ var yyyy8 = yyyy.redIAdd(yyyy); ++ yyyy8 = yyyy8.redIAdd(yyyy8); ++ yyyy8 = yyyy8.redIAdd(yyyy8); ++ ++ // X3 = T ++ nx = t; ++ // Y3 = M * (S - T) - 8 * YYYY ++ ny = m.redMul(s.redISub(t)).redISub(yyyy8); ++ // Z3 = 2*Y1 ++ nz = this.y.redAdd(this.y); ++ } else { ++ // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html ++ // #doubling-dbl-2009-l ++ // 2M + 5S + 13A ++ ++ // A = X1^2 ++ var a = this.x.redSqr(); ++ // B = Y1^2 ++ var b = this.y.redSqr(); ++ // C = B^2 ++ var c = b.redSqr(); ++ // D = 2 * ((X1 + B)^2 - A - C) ++ var d = this.x.redAdd(b).redSqr().redISub(a).redISub(c); ++ d = d.redIAdd(d); ++ // E = 3 * A ++ var e = a.redAdd(a).redIAdd(a); ++ // F = E^2 ++ var f = e.redSqr(); ++ ++ // 8 * C ++ var c8 = c.redIAdd(c); ++ c8 = c8.redIAdd(c8); ++ c8 = c8.redIAdd(c8); ++ ++ // X3 = F - 2 * D ++ nx = f.redISub(d).redISub(d); ++ // Y3 = E * (D - X3) - 8 * C ++ ny = e.redMul(d.redISub(nx)).redISub(c8); ++ // Z3 = 2 * Y1 * Z1 ++ nz = this.y.redMul(this.z); ++ nz = nz.redIAdd(nz); ++ } ++ ++ return this.curve.jpoint(nx, ny, nz); ++}; ++ ++JPoint.prototype._threeDbl = function _threeDbl() { ++ var nx; ++ var ny; ++ var nz; ++ // Z = 1 ++ if (this.zOne) { ++ // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html ++ // #doubling-mdbl-2007-bl ++ // 1M + 5S + 15A ++ ++ // XX = X1^2 ++ var xx = this.x.redSqr(); ++ // YY = Y1^2 ++ var yy = this.y.redSqr(); ++ // YYYY = YY^2 ++ var yyyy = yy.redSqr(); ++ // S = 2 * ((X1 + YY)^2 - XX - YYYY) ++ var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy); ++ s = s.redIAdd(s); ++ // M = 3 * XX + a ++ var m = xx.redAdd(xx).redIAdd(xx).redIAdd(this.curve.a); ++ // T = M^2 - 2 * S ++ var t = m.redSqr().redISub(s).redISub(s); ++ // X3 = T ++ nx = t; ++ // Y3 = M * (S - T) - 8 * YYYY ++ var yyyy8 = yyyy.redIAdd(yyyy); ++ yyyy8 = yyyy8.redIAdd(yyyy8); ++ yyyy8 = yyyy8.redIAdd(yyyy8); ++ ny = m.redMul(s.redISub(t)).redISub(yyyy8); ++ // Z3 = 2 * Y1 ++ nz = this.y.redAdd(this.y); ++ } else { ++ // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b ++ // 3M + 5S ++ ++ // delta = Z1^2 ++ var delta = this.z.redSqr(); ++ // gamma = Y1^2 ++ var gamma = this.y.redSqr(); ++ // beta = X1 * gamma ++ var beta = this.x.redMul(gamma); ++ // alpha = 3 * (X1 - delta) * (X1 + delta) ++ var alpha = this.x.redSub(delta).redMul(this.x.redAdd(delta)); ++ alpha = alpha.redAdd(alpha).redIAdd(alpha); ++ // X3 = alpha^2 - 8 * beta ++ var beta4 = beta.redIAdd(beta); ++ beta4 = beta4.redIAdd(beta4); ++ var beta8 = beta4.redAdd(beta4); ++ nx = alpha.redSqr().redISub(beta8); ++ // Z3 = (Y1 + Z1)^2 - gamma - delta ++ nz = this.y.redAdd(this.z).redSqr().redISub(gamma).redISub(delta); ++ // Y3 = alpha * (4 * beta - X3) - 8 * gamma^2 ++ var ggamma8 = gamma.redSqr(); ++ ggamma8 = ggamma8.redIAdd(ggamma8); ++ ggamma8 = ggamma8.redIAdd(ggamma8); ++ ggamma8 = ggamma8.redIAdd(ggamma8); ++ ny = alpha.redMul(beta4.redISub(nx)).redISub(ggamma8); ++ } ++ ++ return this.curve.jpoint(nx, ny, nz); ++}; ++ ++JPoint.prototype._dbl = function _dbl() { ++ var a = this.curve.a; ++ ++ // 4M + 6S + 10A ++ var jx = this.x; ++ var jy = this.y; ++ var jz = this.z; ++ var jz4 = jz.redSqr().redSqr(); ++ ++ var jx2 = jx.redSqr(); ++ var jy2 = jy.redSqr(); ++ ++ var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4)); ++ ++ var jxd4 = jx.redAdd(jx); ++ jxd4 = jxd4.redIAdd(jxd4); ++ var t1 = jxd4.redMul(jy2); ++ var nx = c.redSqr().redISub(t1.redAdd(t1)); ++ var t2 = t1.redISub(nx); ++ ++ var jyd8 = jy2.redSqr(); ++ jyd8 = jyd8.redIAdd(jyd8); ++ jyd8 = jyd8.redIAdd(jyd8); ++ jyd8 = jyd8.redIAdd(jyd8); ++ var ny = c.redMul(t2).redISub(jyd8); ++ var nz = jy.redAdd(jy).redMul(jz); ++ ++ return this.curve.jpoint(nx, ny, nz); ++}; ++ ++JPoint.prototype.trpl = function trpl() { ++ if (!this.curve.zeroA) ++ return this.dbl().add(this); ++ ++ // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#tripling-tpl-2007-bl ++ // 5M + 10S + ... ++ ++ // XX = X1^2 ++ var xx = this.x.redSqr(); ++ // YY = Y1^2 ++ var yy = this.y.redSqr(); ++ // ZZ = Z1^2 ++ var zz = this.z.redSqr(); ++ // YYYY = YY^2 ++ var yyyy = yy.redSqr(); ++ // M = 3 * XX + a * ZZ2; a = 0 ++ var m = xx.redAdd(xx).redIAdd(xx); ++ // MM = M^2 ++ var mm = m.redSqr(); ++ // E = 6 * ((X1 + YY)^2 - XX - YYYY) - MM ++ var e = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy); ++ e = e.redIAdd(e); ++ e = e.redAdd(e).redIAdd(e); ++ e = e.redISub(mm); ++ // EE = E^2 ++ var ee = e.redSqr(); ++ // T = 16*YYYY ++ var t = yyyy.redIAdd(yyyy); ++ t = t.redIAdd(t); ++ t = t.redIAdd(t); ++ t = t.redIAdd(t); ++ // U = (M + E)^2 - MM - EE - T ++ var u = m.redIAdd(e).redSqr().redISub(mm).redISub(ee).redISub(t); ++ // X3 = 4 * (X1 * EE - 4 * YY * U) ++ var yyu4 = yy.redMul(u); ++ yyu4 = yyu4.redIAdd(yyu4); ++ yyu4 = yyu4.redIAdd(yyu4); ++ var nx = this.x.redMul(ee).redISub(yyu4); ++ nx = nx.redIAdd(nx); ++ nx = nx.redIAdd(nx); ++ // Y3 = 8 * Y1 * (U * (T - U) - E * EE) ++ var ny = this.y.redMul(u.redMul(t.redISub(u)).redISub(e.redMul(ee))); ++ ny = ny.redIAdd(ny); ++ ny = ny.redIAdd(ny); ++ ny = ny.redIAdd(ny); ++ // Z3 = (Z1 + E)^2 - ZZ - EE ++ var nz = this.z.redAdd(e).redSqr().redISub(zz).redISub(ee); ++ ++ return this.curve.jpoint(nx, ny, nz); ++}; ++ ++JPoint.prototype.mul = function mul(k, kbase) { ++ k = new BN(k, kbase); ++ ++ return this.curve._wnafMul(this, k); ++}; ++ ++JPoint.prototype.eq = function eq(p) { ++ if (p.type === 'affine') ++ return this.eq(p.toJ()); ++ ++ if (this === p) ++ return true; ++ ++ // x1 * z2^2 == x2 * z1^2 ++ var z2 = this.z.redSqr(); ++ var pz2 = p.z.redSqr(); ++ if (this.x.redMul(pz2).redISub(p.x.redMul(z2)).cmpn(0) !== 0) ++ return false; ++ ++ // y1 * z2^3 == y2 * z1^3 ++ var z3 = z2.redMul(this.z); ++ var pz3 = pz2.redMul(p.z); ++ return this.y.redMul(pz3).redISub(p.y.redMul(z3)).cmpn(0) === 0; ++}; ++ ++JPoint.prototype.eqXToP = function eqXToP(x) { ++ var zs = this.z.redSqr(); ++ var rx = x.toRed(this.curve.red).redMul(zs); ++ if (this.x.cmp(rx) === 0) ++ return true; ++ ++ var xc = x.clone(); ++ var t = this.curve.redN.redMul(zs); ++ for (;;) { ++ xc.iadd(this.curve.n); ++ if (xc.cmp(this.curve.p) >= 0) ++ return false; ++ ++ rx.redIAdd(t); ++ if (this.x.cmp(rx) === 0) ++ return true; ++ } ++ return false; ++}; ++ ++JPoint.prototype.inspect = function inspect() { ++ if (this.isInfinity()) ++ return '<EC JPoint Infinity>'; ++ return '<EC JPoint x: ' + this.x.toString(16, 2) + ++ ' y: ' + this.y.toString(16, 2) + ++ ' z: ' + this.z.toString(16, 2) + '>'; ++}; ++ ++JPoint.prototype.isInfinity = function isInfinity() { ++ // XXX This code assumes that zero is always zero in red ++ return this.z.cmpn(0) === 0; ++}; ++ ++},{"../../elliptic":2,"../curve":5,"bn.js":1,"inherits":25}],8:[function(require,module,exports){ ++'use strict'; ++ ++var curves = exports; ++ ++var hash = require('hash.js'); ++var elliptic = require('../elliptic'); ++ ++var assert = elliptic.utils.assert; ++ ++function PresetCurve(options) { ++ if (options.type === 'short') ++ this.curve = new elliptic.curve.short(options); ++ else if (options.type === 'edwards') ++ this.curve = new elliptic.curve.edwards(options); ++ else ++ this.curve = new elliptic.curve.mont(options); ++ this.g = this.curve.g; ++ this.n = this.curve.n; ++ this.hash = options.hash; ++ ++ assert(this.g.validate(), 'Invalid curve'); ++ assert(this.g.mul(this.n).isInfinity(), 'Invalid curve, G*N != O'); ++} ++curves.PresetCurve = PresetCurve; ++ ++function defineCurve(name, options) { ++ Object.defineProperty(curves, name, { ++ configurable: true, ++ enumerable: true, ++ get: function() { ++ var curve = new PresetCurve(options); ++ Object.defineProperty(curves, name, { ++ configurable: true, ++ enumerable: true, ++ value: curve ++ }); ++ return curve; ++ } ++ }); ++} ++ ++defineCurve('p192', { ++ type: 'short', ++ prime: 'p192', ++ p: 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff', ++ a: 'ffffffff ffffffff ffffffff fffffffe ffffffff fffffffc', ++ b: '64210519 e59c80e7 0fa7e9ab 72243049 feb8deec c146b9b1', ++ n: 'ffffffff ffffffff ffffffff 99def836 146bc9b1 b4d22831', ++ hash: hash.sha256, ++ gRed: false, ++ g: [ ++ '188da80e b03090f6 7cbf20eb 43a18800 f4ff0afd 82ff1012', ++ '07192b95 ffc8da78 631011ed 6b24cdd5 73f977a1 1e794811' ++ ] ++}); ++ ++defineCurve('p224', { ++ type: 'short', ++ prime: 'p224', ++ p: 'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001', ++ a: 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff fffffffe', ++ b: 'b4050a85 0c04b3ab f5413256 5044b0b7 d7bfd8ba 270b3943 2355ffb4', ++ n: 'ffffffff ffffffff ffffffff ffff16a2 e0b8f03e 13dd2945 5c5c2a3d', ++ hash: hash.sha256, ++ gRed: false, ++ g: [ ++ 'b70e0cbd 6bb4bf7f 321390b9 4a03c1d3 56c21122 343280d6 115c1d21', ++ 'bd376388 b5f723fb 4c22dfe6 cd4375a0 5a074764 44d58199 85007e34' ++ ] ++}); ++ ++defineCurve('p256', { ++ type: 'short', ++ prime: null, ++ p: 'ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff ffffffff', ++ a: 'ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff fffffffc', ++ b: '5ac635d8 aa3a93e7 b3ebbd55 769886bc 651d06b0 cc53b0f6 3bce3c3e 27d2604b', ++ n: 'ffffffff 00000000 ffffffff ffffffff bce6faad a7179e84 f3b9cac2 fc632551', ++ hash: hash.sha256, ++ gRed: false, ++ g: [ ++ '6b17d1f2 e12c4247 f8bce6e5 63a440f2 77037d81 2deb33a0 f4a13945 d898c296', ++ '4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16 2bce3357 6b315ece cbb64068 37bf51f5' ++ ] ++}); ++ ++defineCurve('p384', { ++ type: 'short', ++ prime: null, ++ p: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' + ++ 'fffffffe ffffffff 00000000 00000000 ffffffff', ++ a: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' + ++ 'fffffffe ffffffff 00000000 00000000 fffffffc', ++ b: 'b3312fa7 e23ee7e4 988e056b e3f82d19 181d9c6e fe814112 0314088f ' + ++ '5013875a c656398d 8a2ed19d 2a85c8ed d3ec2aef', ++ n: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff c7634d81 ' + ++ 'f4372ddf 581a0db2 48b0a77a ecec196a ccc52973', ++ hash: hash.sha384, ++ gRed: false, ++ g: [ ++ 'aa87ca22 be8b0537 8eb1c71e f320ad74 6e1d3b62 8ba79b98 59f741e0 82542a38 ' + ++ '5502f25d bf55296c 3a545e38 72760ab7', ++ '3617de4a 96262c6f 5d9e98bf 9292dc29 f8f41dbd 289a147c e9da3113 b5f0b8c0 ' + ++ '0a60b1ce 1d7e819d 7a431d7c 90ea0e5f' ++ ] ++}); ++ ++defineCurve('p521', { ++ type: 'short', ++ prime: null, ++ p: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' + ++ 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' + ++ 'ffffffff ffffffff ffffffff ffffffff ffffffff', ++ a: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' + ++ 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' + ++ 'ffffffff ffffffff ffffffff ffffffff fffffffc', ++ b: '00000051 953eb961 8e1c9a1f 929a21a0 b68540ee a2da725b ' + ++ '99b315f3 b8b48991 8ef109e1 56193951 ec7e937b 1652c0bd ' + ++ '3bb1bf07 3573df88 3d2c34f1 ef451fd4 6b503f00', ++ n: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' + ++ 'ffffffff ffffffff fffffffa 51868783 bf2f966b 7fcc0148 ' + ++ 'f709a5d0 3bb5c9b8 899c47ae bb6fb71e 91386409', ++ hash: hash.sha512, ++ gRed: false, ++ g: [ ++ '000000c6 858e06b7 0404e9cd 9e3ecb66 2395b442 9c648139 ' + ++ '053fb521 f828af60 6b4d3dba a14b5e77 efe75928 fe1dc127 ' + ++ 'a2ffa8de 3348b3c1 856a429b f97e7e31 c2e5bd66', ++ '00000118 39296a78 9a3bc004 5c8a5fb4 2c7d1bd9 98f54449 ' + ++ '579b4468 17afbd17 273e662c 97ee7299 5ef42640 c550b901 ' + ++ '3fad0761 353c7086 a272c240 88be9476 9fd16650' ++ ] ++}); ++ ++defineCurve('curve25519', { ++ type: 'mont', ++ prime: 'p25519', ++ p: '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed', ++ a: '76d06', ++ b: '0', ++ n: '1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed', ++ hash: hash.sha256, ++ gRed: false, ++ g: [ ++ '9' ++ ] ++}); ++ ++defineCurve('ed25519', { ++ type: 'edwards', ++ prime: 'p25519', ++ p: '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed', ++ a: '-1', ++ c: '1', ++ // -121665 * (121666^(-1)) (mod P) ++ d: '52036cee2b6ffe73 8cc740797779e898 00700a4d4141d8ab 75eb4dca135978a3', ++ n: '1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed', ++ hash: hash.sha256, ++ gRed: false, ++ g: [ ++ '216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a', ++ ++ // 4/5 ++ '6666666666666666666666666666666666666666666666666666666666666658' ++ ] ++}); ++ ++var pre; ++try { ++ pre = require('./precomputed/secp256k1'); ++} catch (e) { ++ pre = undefined; ++} ++ ++defineCurve('secp256k1', { ++ type: 'short', ++ prime: 'k256', ++ p: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f', ++ a: '0', ++ b: '7', ++ n: 'ffffffff ffffffff ffffffff fffffffe baaedce6 af48a03b bfd25e8c d0364141', ++ h: '1', ++ hash: hash.sha256, ++ ++ // Precomputed endomorphism ++ beta: '7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee', ++ lambda: '5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72', ++ basis: [ ++ { ++ a: '3086d221a7d46bcde86c90e49284eb15', ++ b: '-e4437ed6010e88286f547fa90abfe4c3' ++ }, ++ { ++ a: '114ca50f7a8e2f3f657c1108d9d44cfd8', ++ b: '3086d221a7d46bcde86c90e49284eb15' ++ } ++ ], ++ ++ gRed: false, ++ g: [ ++ '79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798', ++ '483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8', ++ pre ++ ] ++}); ++ ++},{"../elliptic":2,"./precomputed/secp256k1":16,"hash.js":19}],9:[function(require,module,exports){ ++'use strict'; ++ ++var BN = require('bn.js'); ++var elliptic = require('../../elliptic'); ++var utils = elliptic.utils; ++var assert = utils.assert; ++ ++var KeyPair = require('./key'); ++var Signature = require('./signature'); ++ ++function EC(options) { ++ if (!(this instanceof EC)) ++ return new EC(options); ++ ++ // Shortcut `elliptic.ec(curve-name)` ++ if (typeof options === 'string') { ++ assert(elliptic.curves.hasOwnProperty(options), 'Unknown curve ' + options); ++ ++ options = elliptic.curves[options]; ++ } ++ ++ // Shortcut for `elliptic.ec(elliptic.curves.curveName)` ++ if (options instanceof elliptic.curves.PresetCurve) ++ options = { curve: options }; ++ ++ this.curve = options.curve.curve; ++ this.n = this.curve.n; ++ this.nh = this.n.ushrn(1); ++ this.g = this.curve.g; ++ ++ // Point on curve ++ this.g = options.curve.g; ++ this.g.precompute(options.curve.n.bitLength() + 1); ++ ++ // Hash for function for DRBG ++ this.hash = options.hash || options.curve.hash; ++} ++module.exports = EC; ++ ++EC.prototype.keyPair = function keyPair(options) { ++ return new KeyPair(this, options); ++}; ++ ++EC.prototype.keyFromPrivate = function keyFromPrivate(priv, enc) { ++ return KeyPair.fromPrivate(this, priv, enc); ++}; ++ ++EC.prototype.keyFromPublic = function keyFromPublic(pub, enc) { ++ return KeyPair.fromPublic(this, pub, enc); ++}; ++ ++EC.prototype.genKeyPair = function genKeyPair(options) { ++ if (!options) ++ options = {}; ++ ++ // Instantiate Hmac_DRBG ++ var drbg = new elliptic.hmacDRBG({ ++ hash: this.hash, ++ pers: options.pers, ++ entropy: options.entropy || elliptic.rand(this.hash.hmacStrength), ++ nonce: this.n.toArray() ++ }); ++ ++ var bytes = this.n.byteLength(); ++ var ns2 = this.n.sub(new BN(2)); ++ do { ++ var priv = new BN(drbg.generate(bytes)); ++ if (priv.cmp(ns2) > 0) ++ continue; ++ ++ priv.iaddn(1); ++ return this.keyFromPrivate(priv); ++ } while (true); ++}; ++ ++EC.prototype._truncateToN = function truncateToN(msg, truncOnly) { ++ var delta = msg.byteLength() * 8 - this.n.bitLength(); ++ if (delta > 0) ++ msg = msg.ushrn(delta); ++ if (!truncOnly && msg.cmp(this.n) >= 0) ++ return msg.sub(this.n); ++ else ++ return msg; ++}; ++ ++EC.prototype.sign = function sign(msg, key, enc, options) { ++ if (typeof enc === 'object') { ++ options = enc; ++ enc = null; ++ } ++ if (!options) ++ options = {}; ++ ++ key = this.keyFromPrivate(key, enc); ++ msg = this._truncateToN(new BN(msg, 16)); ++ ++ // Zero-extend key to provide enough entropy ++ var bytes = this.n.byteLength(); ++ var bkey = key.getPrivate().toArray('be', bytes); ++ ++ // Zero-extend nonce to have the same byte size as N ++ var nonce = msg.toArray('be', bytes); ++ ++ // Instantiate Hmac_DRBG ++ var drbg = new elliptic.hmacDRBG({ ++ hash: this.hash, ++ entropy: bkey, ++ nonce: nonce, ++ pers: options.pers, ++ persEnc: options.persEnc ++ }); ++ ++ // Number of bytes to generate ++ var ns1 = this.n.sub(new BN(1)); ++ ++ for (var iter = 0; true; iter++) { ++ var k = options.k ? ++ options.k(iter) : ++ new BN(drbg.generate(this.n.byteLength())); ++ k = this._truncateToN(k, true); ++ if (k.cmpn(1) <= 0 || k.cmp(ns1) >= 0) ++ continue; ++ ++ var kp = this.g.mul(k); ++ if (kp.isInfinity()) ++ continue; ++ ++ var kpX = kp.getX(); ++ var r = kpX.umod(this.n); ++ if (r.cmpn(0) === 0) ++ continue; ++ ++ var s = k.invm(this.n).mul(r.mul(key.getPrivate()).iadd(msg)); ++ s = s.umod(this.n); ++ if (s.cmpn(0) === 0) ++ continue; ++ ++ var recoveryParam = (kp.getY().isOdd() ? 1 : 0) | ++ (kpX.cmp(r) !== 0 ? 2 : 0); ++ ++ // Use complement of `s`, if it is > `n / 2` ++ if (options.canonical && s.cmp(this.nh) > 0) { ++ s = this.n.sub(s); ++ recoveryParam ^= 1; ++ } ++ ++ return new Signature({ r: r, s: s, recoveryParam: recoveryParam }); ++ } ++}; ++ ++EC.prototype.verify = function verify(msg, signature, key, enc) { ++ msg = this._truncateToN(new BN(msg, 16)); ++ key = this.keyFromPublic(key, enc); ++ signature = new Signature(signature, 'hex'); ++ ++ // Perform primitive values validation ++ var r = signature.r; ++ var s = signature.s; ++ if (r.cmpn(1) < 0 || r.cmp(this.n) >= 0) ++ return false; ++ if (s.cmpn(1) < 0 || s.cmp(this.n) >= 0) ++ return false; ++ ++ // Validate signature ++ var sinv = s.invm(this.n); ++ var u1 = sinv.mul(msg).umod(this.n); ++ var u2 = sinv.mul(r).umod(this.n); ++ ++ if (!this.curve._maxwellTrick) { ++ var p = this.g.mulAdd(u1, key.getPublic(), u2); ++ if (p.isInfinity()) ++ return false; ++ ++ return p.getX().umod(this.n).cmp(r) === 0; ++ } ++ ++ // NOTE: Greg Maxwell's trick, inspired by: ++ // https://git.io/vad3K ++ ++ var p = this.g.jmulAdd(u1, key.getPublic(), u2); ++ if (p.isInfinity()) ++ return false; ++ ++ // Compare `p.x` of Jacobian point with `r`, ++ // this will do `p.x == r * p.z^2` instead of multiplying `p.x` by the ++ // inverse of `p.z^2` ++ return p.eqXToP(r); ++}; ++ ++EC.prototype.recoverPubKey = function(msg, signature, j, enc) { ++ assert((3 & j) === j, 'The recovery param is more than two bits'); ++ signature = new Signature(signature, enc); ++ ++ var n = this.n; ++ var e = new BN(msg); ++ var r = signature.r; ++ var s = signature.s; ++ ++ // A set LSB signifies that the y-coordinate is odd ++ var isYOdd = j & 1; ++ var isSecondKey = j >> 1; ++ if (r.cmp(this.curve.p.umod(this.curve.n)) >= 0 && isSecondKey) ++ throw new Error('Unable to find sencond key candinate'); ++ ++ // 1.1. Let x = r + jn. ++ if (isSecondKey) ++ r = this.curve.pointFromX(r.add(this.curve.n), isYOdd); ++ else ++ r = this.curve.pointFromX(r, isYOdd); ++ ++ var rInv = signature.r.invm(n); ++ var s1 = n.sub(e).mul(rInv).umod(n); ++ var s2 = s.mul(rInv).umod(n); ++ ++ // 1.6.1 Compute Q = r^-1 (sR - eG) ++ // Q = r^-1 (sR + -eG) ++ return this.g.mulAdd(s1, r, s2); ++}; ++ ++EC.prototype.getKeyRecoveryParam = function(e, signature, Q, enc) { ++ signature = new Signature(signature, enc); ++ if (signature.recoveryParam !== null) ++ return signature.recoveryParam; ++ ++ for (var i = 0; i < 4; i++) { ++ var Qprime; ++ try { ++ Qprime = this.recoverPubKey(e, signature, i); ++ } catch (e) { ++ continue; ++ } ++ ++ if (Qprime.eq(Q)) ++ return i; ++ } ++ throw new Error('Unable to find valid recovery factor'); ++}; ++ ++},{"../../elliptic":2,"./key":10,"./signature":11,"bn.js":1}],10:[function(require,module,exports){ ++'use strict'; ++ ++var BN = require('bn.js'); ++ ++function KeyPair(ec, options) { ++ this.ec = ec; ++ this.priv = null; ++ this.pub = null; ++ ++ // KeyPair(ec, { priv: ..., pub: ... }) ++ if (options.priv) ++ this._importPrivate(options.priv, options.privEnc); ++ if (options.pub) ++ this._importPublic(options.pub, options.pubEnc); ++} ++module.exports = KeyPair; ++ ++KeyPair.fromPublic = function fromPublic(ec, pub, enc) { ++ if (pub instanceof KeyPair) ++ return pub; ++ ++ return new KeyPair(ec, { ++ pub: pub, ++ pubEnc: enc ++ }); ++}; ++ ++KeyPair.fromPrivate = function fromPrivate(ec, priv, enc) { ++ if (priv instanceof KeyPair) ++ return priv; ++ ++ return new KeyPair(ec, { ++ priv: priv, ++ privEnc: enc ++ }); ++}; ++ ++KeyPair.prototype.validate = function validate() { ++ var pub = this.getPublic(); ++ ++ if (pub.isInfinity()) ++ return { result: false, reason: 'Invalid public key' }; ++ if (!pub.validate()) ++ return { result: false, reason: 'Public key is not a point' }; ++ if (!pub.mul(this.ec.curve.n).isInfinity()) ++ return { result: false, reason: 'Public key * N != O' }; ++ ++ return { result: true, reason: null }; ++}; ++ ++KeyPair.prototype.getPublic = function getPublic(compact, enc) { ++ // compact is optional argument ++ if (typeof compact === 'string') { ++ enc = compact; ++ compact = null; ++ } ++ ++ if (!this.pub) ++ this.pub = this.ec.g.mul(this.priv); ++ ++ if (!enc) ++ return this.pub; ++ ++ return this.pub.encode(enc, compact); ++}; ++ ++KeyPair.prototype.getPrivate = function getPrivate(enc) { ++ if (enc === 'hex') ++ return this.priv.toString(16, 2); ++ else ++ return this.priv; ++}; ++ ++KeyPair.prototype._importPrivate = function _importPrivate(key, enc) { ++ this.priv = new BN(key, enc || 16); ++ ++ // Ensure that the priv won't be bigger than n, otherwise we may fail ++ // in fixed multiplication method ++ this.priv = this.priv.umod(this.ec.curve.n); ++}; ++ ++KeyPair.prototype._importPublic = function _importPublic(key, enc) { ++ if (key.x || key.y) { ++ this.pub = this.ec.curve.point(key.x, key.y); ++ return; ++ } ++ this.pub = this.ec.curve.decodePoint(key, enc); ++}; ++ ++// ECDH ++KeyPair.prototype.derive = function derive(pub) { ++ return pub.mul(this.priv).getX(); ++}; ++ ++// ECDSA ++KeyPair.prototype.sign = function sign(msg, enc, options) { ++ return this.ec.sign(msg, this, enc, options); ++}; ++ ++KeyPair.prototype.verify = function verify(msg, signature) { ++ return this.ec.verify(msg, signature, this); ++}; ++ ++KeyPair.prototype.inspect = function inspect() { ++ return '<Key priv: ' + (this.priv && this.priv.toString(16, 2)) + ++ ' pub: ' + (this.pub && this.pub.inspect()) + ' >'; ++}; ++ ++},{"bn.js":1}],11:[function(require,module,exports){ ++'use strict'; ++ ++var BN = require('bn.js'); ++ ++var elliptic = require('../../elliptic'); ++var utils = elliptic.utils; ++var assert = utils.assert; ++ ++function Signature(options, enc) { ++ if (options instanceof Signature) ++ return options; ++ ++ if (this._importDER(options, enc)) ++ return; ++ ++ assert(options.r && options.s, 'Signature without r or s'); ++ this.r = new BN(options.r, 16); ++ this.s = new BN(options.s, 16); ++ if (options.recoveryParam === undefined) ++ this.recoveryParam = null; ++ else ++ this.recoveryParam = options.recoveryParam; ++} ++module.exports = Signature; ++ ++function Position() { ++ this.place = 0; ++} ++ ++function getLength(buf, p) { ++ var initial = buf[p.place++]; ++ if (!(initial & 0x80)) { ++ return initial; ++ } ++ var octetLen = initial & 0xf; ++ var val = 0; ++ for (var i = 0, off = p.place; i < octetLen; i++, off++) { ++ val <<= 8; ++ val |= buf[off]; ++ } ++ p.place = off; ++ return val; ++} ++ ++function rmPadding(buf) { ++ var i = 0; ++ var len = buf.length - 1; ++ while (!buf[i] && !(buf[i + 1] & 0x80) && i < len) { ++ i++; ++ } ++ if (i === 0) { ++ return buf; ++ } ++ return buf.slice(i); ++} ++ ++Signature.prototype._importDER = function _importDER(data, enc) { ++ data = utils.toArray(data, enc); ++ var p = new Position(); ++ if (data[p.place++] !== 0x30) { ++ return false; ++ } ++ var len = getLength(data, p); ++ if ((len + p.place) !== data.length) { ++ return false; ++ } ++ if (data[p.place++] !== 0x02) { ++ return false; ++ } ++ var rlen = getLength(data, p); ++ var r = data.slice(p.place, rlen + p.place); ++ p.place += rlen; ++ if (data[p.place++] !== 0x02) { ++ return false; ++ } ++ var slen = getLength(data, p); ++ if (data.length !== slen + p.place) { ++ return false; ++ } ++ var s = data.slice(p.place, slen + p.place); ++ if (r[0] === 0 && (r[1] & 0x80)) { ++ r = r.slice(1); ++ } ++ if (s[0] === 0 && (s[1] & 0x80)) { ++ s = s.slice(1); ++ } ++ ++ this.r = new BN(r); ++ this.s = new BN(s); ++ this.recoveryParam = null; ++ ++ return true; ++}; ++ ++function constructLength(arr, len) { ++ if (len < 0x80) { ++ arr.push(len); ++ return; ++ } ++ var octets = 1 + (Math.log(len) / Math.LN2 >>> 3); ++ arr.push(octets | 0x80); ++ while (--octets) { ++ arr.push((len >>> (octets << 3)) & 0xff); ++ } ++ arr.push(len); ++} ++ ++Signature.prototype.toDER = function toDER(enc) { ++ var r = this.r.toArray(); ++ var s = this.s.toArray(); ++ ++ // Pad values ++ if (r[0] & 0x80) ++ r = [ 0 ].concat(r); ++ // Pad values ++ if (s[0] & 0x80) ++ s = [ 0 ].concat(s); ++ ++ r = rmPadding(r); ++ s = rmPadding(s); ++ ++ while (!s[0] && !(s[1] & 0x80)) { ++ s = s.slice(1); ++ } ++ var arr = [ 0x02 ]; ++ constructLength(arr, r.length); ++ arr = arr.concat(r); ++ arr.push(0x02); ++ constructLength(arr, s.length); ++ var backHalf = arr.concat(s); ++ var res = [ 0x30 ]; ++ constructLength(res, backHalf.length); ++ res = res.concat(backHalf); ++ return utils.encode(res, enc); ++}; ++ ++},{"../../elliptic":2,"bn.js":1}],12:[function(require,module,exports){ ++'use strict'; ++ ++var hash = require('hash.js'); ++var elliptic = require('../../elliptic'); ++var utils = elliptic.utils; ++var assert = utils.assert; ++var parseBytes = utils.parseBytes; ++var KeyPair = require('./key'); ++var Signature = require('./signature'); ++ ++function EDDSA(curve) { ++ assert(curve === 'ed25519', 'only tested with ed25519 so far'); ++ ++ if (!(this instanceof EDDSA)) ++ return new EDDSA(curve); ++ ++ var curve = elliptic.curves[curve].curve; ++ this.curve = curve; ++ this.g = curve.g; ++ this.g.precompute(curve.n.bitLength() + 1); ++ ++ this.pointClass = curve.point().constructor; ++ this.encodingLength = Math.ceil(curve.n.bitLength() / 8); ++ this.hash = hash.sha512; ++} ++ ++module.exports = EDDSA; ++ ++/** ++* @param {Array|String} message - message bytes ++* @param {Array|String|KeyPair} secret - secret bytes or a keypair ++* @returns {Signature} - signature ++*/ ++EDDSA.prototype.sign = function sign(message, secret) { ++ message = parseBytes(message); ++ var key = this.keyFromSecret(secret); ++ var r = this.hashInt(key.messagePrefix(), message); ++ var R = this.g.mul(r); ++ var Rencoded = this.encodePoint(R); ++ var s_ = this.hashInt(Rencoded, key.pubBytes(), message) ++ .mul(key.priv()); ++ var S = r.add(s_).umod(this.curve.n); ++ return this.makeSignature({ R: R, S: S, Rencoded: Rencoded }); ++}; ++ ++/** ++* @param {Array} message - message bytes ++* @param {Array|String|Signature} sig - sig bytes ++* @param {Array|String|Point|KeyPair} pub - public key ++* @returns {Boolean} - true if public key matches sig of message ++*/ ++EDDSA.prototype.verify = function verify(message, sig, pub) { ++ message = parseBytes(message); ++ sig = this.makeSignature(sig); ++ var key = this.keyFromPublic(pub); ++ var h = this.hashInt(sig.Rencoded(), key.pubBytes(), message); ++ var SG = this.g.mul(sig.S()); ++ var RplusAh = sig.R().add(key.pub().mul(h)); ++ return RplusAh.eq(SG); ++}; ++ ++EDDSA.prototype.hashInt = function hashInt() { ++ var hash = this.hash(); ++ for (var i = 0; i < arguments.length; i++) ++ hash.update(arguments[i]); ++ return utils.intFromLE(hash.digest()).umod(this.curve.n); ++}; ++ ++EDDSA.prototype.keyFromPublic = function keyFromPublic(pub) { ++ return KeyPair.fromPublic(this, pub); ++}; ++ ++EDDSA.prototype.keyFromSecret = function keyFromSecret(secret) { ++ return KeyPair.fromSecret(this, secret); ++}; ++ ++EDDSA.prototype.makeSignature = function makeSignature(sig) { ++ if (sig instanceof Signature) ++ return sig; ++ return new Signature(this, sig); ++}; ++ ++/** ++* * https://tools.ietf.org/html/draft-josefsson-eddsa-ed25519-03#section-5.2 ++* ++* EDDSA defines methods for encoding and decoding points and integers. These are ++* helper convenience methods, that pass along to utility functions implied ++* parameters. ++* ++*/ ++EDDSA.prototype.encodePoint = function encodePoint(point) { ++ var enc = point.getY().toArray('le', this.encodingLength); ++ enc[this.encodingLength - 1] |= point.getX().isOdd() ? 0x80 : 0; ++ return enc; ++}; ++ ++EDDSA.prototype.decodePoint = function decodePoint(bytes) { ++ bytes = utils.parseBytes(bytes); ++ ++ var lastIx = bytes.length - 1; ++ var normed = bytes.slice(0, lastIx).concat(bytes[lastIx] & ~0x80); ++ var xIsOdd = (bytes[lastIx] & 0x80) !== 0; ++ ++ var y = utils.intFromLE(normed); ++ return this.curve.pointFromY(y, xIsOdd); ++}; ++ ++EDDSA.prototype.encodeInt = function encodeInt(num) { ++ return num.toArray('le', this.encodingLength); ++}; ++ ++EDDSA.prototype.decodeInt = function decodeInt(bytes) { ++ return utils.intFromLE(bytes); ++}; ++ ++EDDSA.prototype.isPoint = function isPoint(val) { ++ return val instanceof this.pointClass; ++}; ++ ++},{"../../elliptic":2,"./key":13,"./signature":14,"hash.js":19}],13:[function(require,module,exports){ ++'use strict'; ++ ++var elliptic = require('../../elliptic'); ++var utils = elliptic.utils; ++var assert = utils.assert; ++var parseBytes = utils.parseBytes; ++var cachedProperty = utils.cachedProperty; ++ ++/** ++* @param {EDDSA} eddsa - instance ++* @param {Object} params - public/private key parameters ++* ++* @param {Array<Byte>} [params.secret] - secret seed bytes ++* @param {Point} [params.pub] - public key point (aka `A` in eddsa terms) ++* @param {Array<Byte>} [params.pub] - public key point encoded as bytes ++* ++*/ ++function KeyPair(eddsa, params) { ++ this.eddsa = eddsa; ++ this._secret = parseBytes(params.secret); ++ if (eddsa.isPoint(params.pub)) ++ this._pub = params.pub; ++ else ++ this._pubBytes = parseBytes(params.pub); ++} ++ ++KeyPair.fromPublic = function fromPublic(eddsa, pub) { ++ if (pub instanceof KeyPair) ++ return pub; ++ return new KeyPair(eddsa, { pub: pub }); ++}; ++ ++KeyPair.fromSecret = function fromSecret(eddsa, secret) { ++ if (secret instanceof KeyPair) ++ return secret; ++ return new KeyPair(eddsa, { secret: secret }); ++}; ++ ++KeyPair.prototype.secret = function secret() { ++ return this._secret; ++}; ++ ++cachedProperty(KeyPair, 'pubBytes', function pubBytes() { ++ return this.eddsa.encodePoint(this.pub()); ++}); ++ ++cachedProperty(KeyPair, 'pub', function pub() { ++ if (this._pubBytes) ++ return this.eddsa.decodePoint(this._pubBytes); ++ return this.eddsa.g.mul(this.priv()); ++}); ++ ++cachedProperty(KeyPair, 'privBytes', function privBytes() { ++ var eddsa = this.eddsa; ++ var hash = this.hash(); ++ var lastIx = eddsa.encodingLength - 1; ++ ++ var a = hash.slice(0, eddsa.encodingLength); ++ a[0] &= 248; ++ a[lastIx] &= 127; ++ a[lastIx] |= 64; ++ ++ return a; ++}); ++ ++cachedProperty(KeyPair, 'priv', function priv() { ++ return this.eddsa.decodeInt(this.privBytes()); ++}); ++ ++cachedProperty(KeyPair, 'hash', function hash() { ++ return this.eddsa.hash().update(this.secret()).digest(); ++}); ++ ++cachedProperty(KeyPair, 'messagePrefix', function messagePrefix() { ++ return this.hash().slice(this.eddsa.encodingLength); ++}); ++ ++KeyPair.prototype.sign = function sign(message) { ++ assert(this._secret, 'KeyPair can only verify'); ++ return this.eddsa.sign(message, this); ++}; ++ ++KeyPair.prototype.verify = function verify(message, sig) { ++ return this.eddsa.verify(message, sig, this); ++}; ++ ++KeyPair.prototype.getSecret = function getSecret(enc) { ++ assert(this._secret, 'KeyPair is public only'); ++ return utils.encode(this.secret(), enc); ++}; ++ ++KeyPair.prototype.getPublic = function getPublic(enc) { ++ return utils.encode(this.pubBytes(), enc); ++}; ++ ++module.exports = KeyPair; ++ ++},{"../../elliptic":2}],14:[function(require,module,exports){ ++'use strict'; ++ ++var BN = require('bn.js'); ++var elliptic = require('../../elliptic'); ++var utils = elliptic.utils; ++var assert = utils.assert; ++var cachedProperty = utils.cachedProperty; ++var parseBytes = utils.parseBytes; ++ ++/** ++* @param {EDDSA} eddsa - eddsa instance ++* @param {Array<Bytes>|Object} sig - ++* @param {Array<Bytes>|Point} [sig.R] - R point as Point or bytes ++* @param {Array<Bytes>|bn} [sig.S] - S scalar as bn or bytes ++* @param {Array<Bytes>} [sig.Rencoded] - R point encoded ++* @param {Array<Bytes>} [sig.Sencoded] - S scalar encoded ++*/ ++function Signature(eddsa, sig) { ++ this.eddsa = eddsa; ++ ++ if (typeof sig !== 'object') ++ sig = parseBytes(sig); ++ ++ if (Array.isArray(sig)) { ++ sig = { ++ R: sig.slice(0, eddsa.encodingLength), ++ S: sig.slice(eddsa.encodingLength) ++ }; ++ } ++ ++ assert(sig.R && sig.S, 'Signature without R or S'); ++ ++ if (eddsa.isPoint(sig.R)) ++ this._R = sig.R; ++ if (sig.S instanceof BN) ++ this._S = sig.S; ++ ++ this._Rencoded = Array.isArray(sig.R) ? sig.R : sig.Rencoded; ++ this._Sencoded = Array.isArray(sig.S) ? sig.S : sig.Sencoded; ++} ++ ++cachedProperty(Signature, 'S', function S() { ++ return this.eddsa.decodeInt(this.Sencoded()); ++}); ++ ++cachedProperty(Signature, 'R', function R() { ++ return this.eddsa.decodePoint(this.Rencoded()); ++}); ++ ++cachedProperty(Signature, 'Rencoded', function Rencoded() { ++ return this.eddsa.encodePoint(this.R()); ++}); ++ ++cachedProperty(Signature, 'Sencoded', function Sencoded() { ++ return this.eddsa.encodeInt(this.S()); ++}); ++ ++Signature.prototype.toBytes = function toBytes() { ++ return this.Rencoded().concat(this.Sencoded()); ++}; ++ ++Signature.prototype.toHex = function toHex() { ++ return utils.encode(this.toBytes(), 'hex').toUpperCase(); ++}; ++ ++module.exports = Signature; ++ ++},{"../../elliptic":2,"bn.js":1}],15:[function(require,module,exports){ ++'use strict'; ++ ++var hash = require('hash.js'); ++var elliptic = require('../elliptic'); ++var utils = elliptic.utils; ++var assert = utils.assert; ++ ++function HmacDRBG(options) { ++ if (!(this instanceof HmacDRBG)) ++ return new HmacDRBG(options); ++ this.hash = options.hash; ++ this.predResist = !!options.predResist; ++ ++ this.outLen = this.hash.outSize; ++ this.minEntropy = options.minEntropy || this.hash.hmacStrength; ++ ++ this.reseed = null; ++ this.reseedInterval = null; ++ this.K = null; ++ this.V = null; ++ ++ var entropy = utils.toArray(options.entropy, options.entropyEnc); ++ var nonce = utils.toArray(options.nonce, options.nonceEnc); ++ var pers = utils.toArray(options.pers, options.persEnc); ++ assert(entropy.length >= (this.minEntropy / 8), ++ 'Not enough entropy. Minimum is: ' + this.minEntropy + ' bits'); ++ this._init(entropy, nonce, pers); ++} ++module.exports = HmacDRBG; ++ ++HmacDRBG.prototype._init = function init(entropy, nonce, pers) { ++ var seed = entropy.concat(nonce).concat(pers); ++ ++ this.K = new Array(this.outLen / 8); ++ this.V = new Array(this.outLen / 8); ++ for (var i = 0; i < this.V.length; i++) { ++ this.K[i] = 0x00; ++ this.V[i] = 0x01; ++ } ++ ++ this._update(seed); ++ this.reseed = 1; ++ this.reseedInterval = 0x1000000000000; // 2^48 ++}; ++ ++HmacDRBG.prototype._hmac = function hmac() { ++ return new hash.hmac(this.hash, this.K); ++}; ++ ++HmacDRBG.prototype._update = function update(seed) { ++ var kmac = this._hmac() ++ .update(this.V) ++ .update([ 0x00 ]); ++ if (seed) ++ kmac = kmac.update(seed); ++ this.K = kmac.digest(); ++ this.V = this._hmac().update(this.V).digest(); ++ if (!seed) ++ return; ++ ++ this.K = this._hmac() ++ .update(this.V) ++ .update([ 0x01 ]) ++ .update(seed) ++ .digest(); ++ this.V = this._hmac().update(this.V).digest(); ++}; ++ ++HmacDRBG.prototype.reseed = function reseed(entropy, entropyEnc, add, addEnc) { ++ // Optional entropy enc ++ if (typeof entropyEnc !== 'string') { ++ addEnc = add; ++ add = entropyEnc; ++ entropyEnc = null; ++ } ++ ++ entropy = utils.toBuffer(entropy, entropyEnc); ++ add = utils.toBuffer(add, addEnc); ++ ++ assert(entropy.length >= (this.minEntropy / 8), ++ 'Not enough entropy. Minimum is: ' + this.minEntropy + ' bits'); ++ ++ this._update(entropy.concat(add || [])); ++ this.reseed = 1; ++}; ++ ++HmacDRBG.prototype.generate = function generate(len, enc, add, addEnc) { ++ if (this.reseed > this.reseedInterval) ++ throw new Error('Reseed is required'); ++ ++ // Optional encoding ++ if (typeof enc !== 'string') { ++ addEnc = add; ++ add = enc; ++ enc = null; ++ } ++ ++ // Optional additional data ++ if (add) { ++ add = utils.toArray(add, addEnc); ++ this._update(add); ++ } ++ ++ var temp = []; ++ while (temp.length < len) { ++ this.V = this._hmac().update(this.V).digest(); ++ temp = temp.concat(this.V); ++ } ++ ++ var res = temp.slice(0, len); ++ this._update(add); ++ this.reseed++; ++ return utils.encode(res, enc); ++}; ++ ++},{"../elliptic":2,"hash.js":19}],16:[function(require,module,exports){ ++module.exports = { ++ doubles: { ++ step: 4, ++ points: [ ++ [ ++ 'e60fce93b59e9ec53011aabc21c23e97b2a31369b87a5ae9c44ee89e2a6dec0a', ++ 'f7e3507399e595929db99f34f57937101296891e44d23f0be1f32cce69616821' ++ ], ++ [ ++ '8282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508', ++ '11f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf' ++ ], ++ [ ++ '175e159f728b865a72f99cc6c6fc846de0b93833fd2222ed73fce5b551e5b739', ++ 'd3506e0d9e3c79eba4ef97a51ff71f5eacb5955add24345c6efa6ffee9fed695' ++ ], ++ [ ++ '363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640', ++ '4e273adfc732221953b445397f3363145b9a89008199ecb62003c7f3bee9de9' ++ ], ++ [ ++ '8b4b5f165df3c2be8c6244b5b745638843e4a781a15bcd1b69f79a55dffdf80c', ++ '4aad0a6f68d308b4b3fbd7813ab0da04f9e336546162ee56b3eff0c65fd4fd36' ++ ], ++ [ ++ '723cbaa6e5db996d6bf771c00bd548c7b700dbffa6c0e77bcb6115925232fcda', ++ '96e867b5595cc498a921137488824d6e2660a0653779494801dc069d9eb39f5f' ++ ], ++ [ ++ 'eebfa4d493bebf98ba5feec812c2d3b50947961237a919839a533eca0e7dd7fa', ++ '5d9a8ca3970ef0f269ee7edaf178089d9ae4cdc3a711f712ddfd4fdae1de8999' ++ ], ++ [ ++ '100f44da696e71672791d0a09b7bde459f1215a29b3c03bfefd7835b39a48db0', ++ 'cdd9e13192a00b772ec8f3300c090666b7ff4a18ff5195ac0fbd5cd62bc65a09' ++ ], ++ [ ++ 'e1031be262c7ed1b1dc9227a4a04c017a77f8d4464f3b3852c8acde6e534fd2d', ++ '9d7061928940405e6bb6a4176597535af292dd419e1ced79a44f18f29456a00d' ++ ], ++ [ ++ 'feea6cae46d55b530ac2839f143bd7ec5cf8b266a41d6af52d5e688d9094696d', ++ 'e57c6b6c97dce1bab06e4e12bf3ecd5c981c8957cc41442d3155debf18090088' ++ ], ++ [ ++ 'da67a91d91049cdcb367be4be6ffca3cfeed657d808583de33fa978bc1ec6cb1', ++ '9bacaa35481642bc41f463f7ec9780e5dec7adc508f740a17e9ea8e27a68be1d' ++ ], ++ [ ++ '53904faa0b334cdda6e000935ef22151ec08d0f7bb11069f57545ccc1a37b7c0', ++ '5bc087d0bc80106d88c9eccac20d3c1c13999981e14434699dcb096b022771c8' ++ ], ++ [ ++ '8e7bcd0bd35983a7719cca7764ca906779b53a043a9b8bcaeff959f43ad86047', ++ '10b7770b2a3da4b3940310420ca9514579e88e2e47fd68b3ea10047e8460372a' ++ ], ++ [ ++ '385eed34c1cdff21e6d0818689b81bde71a7f4f18397e6690a841e1599c43862', ++ '283bebc3e8ea23f56701de19e9ebf4576b304eec2086dc8cc0458fe5542e5453' ++ ], ++ [ ++ '6f9d9b803ecf191637c73a4413dfa180fddf84a5947fbc9c606ed86c3fac3a7', ++ '7c80c68e603059ba69b8e2a30e45c4d47ea4dd2f5c281002d86890603a842160' ++ ], ++ [ ++ '3322d401243c4e2582a2147c104d6ecbf774d163db0f5e5313b7e0e742d0e6bd', ++ '56e70797e9664ef5bfb019bc4ddaf9b72805f63ea2873af624f3a2e96c28b2a0' ++ ], ++ [ ++ '85672c7d2de0b7da2bd1770d89665868741b3f9af7643397721d74d28134ab83', ++ '7c481b9b5b43b2eb6374049bfa62c2e5e77f17fcc5298f44c8e3094f790313a6' ++ ], ++ [ ++ '948bf809b1988a46b06c9f1919413b10f9226c60f668832ffd959af60c82a0a', ++ '53a562856dcb6646dc6b74c5d1c3418c6d4dff08c97cd2bed4cb7f88d8c8e589' ++ ], ++ [ ++ '6260ce7f461801c34f067ce0f02873a8f1b0e44dfc69752accecd819f38fd8e8', ++ 'bc2da82b6fa5b571a7f09049776a1ef7ecd292238051c198c1a84e95b2b4ae17' ++ ], ++ [ ++ 'e5037de0afc1d8d43d8348414bbf4103043ec8f575bfdc432953cc8d2037fa2d', ++ '4571534baa94d3b5f9f98d09fb990bddbd5f5b03ec481f10e0e5dc841d755bda' ++ ], ++ [ ++ 'e06372b0f4a207adf5ea905e8f1771b4e7e8dbd1c6a6c5b725866a0ae4fce725', ++ '7a908974bce18cfe12a27bb2ad5a488cd7484a7787104870b27034f94eee31dd' ++ ], ++ [ ++ '213c7a715cd5d45358d0bbf9dc0ce02204b10bdde2a3f58540ad6908d0559754', ++ '4b6dad0b5ae462507013ad06245ba190bb4850f5f36a7eeddff2c27534b458f2' ++ ], ++ [ ++ '4e7c272a7af4b34e8dbb9352a5419a87e2838c70adc62cddf0cc3a3b08fbd53c', ++ '17749c766c9d0b18e16fd09f6def681b530b9614bff7dd33e0b3941817dcaae6' ++ ], ++ [ ++ 'fea74e3dbe778b1b10f238ad61686aa5c76e3db2be43057632427e2840fb27b6', ++ '6e0568db9b0b13297cf674deccb6af93126b596b973f7b77701d3db7f23cb96f' ++ ], ++ [ ++ '76e64113f677cf0e10a2570d599968d31544e179b760432952c02a4417bdde39', ++ 'c90ddf8dee4e95cf577066d70681f0d35e2a33d2b56d2032b4b1752d1901ac01' ++ ], ++ [ ++ 'c738c56b03b2abe1e8281baa743f8f9a8f7cc643df26cbee3ab150242bcbb891', ++ '893fb578951ad2537f718f2eacbfbbbb82314eef7880cfe917e735d9699a84c3' ++ ], ++ [ ++ 'd895626548b65b81e264c7637c972877d1d72e5f3a925014372e9f6588f6c14b', ++ 'febfaa38f2bc7eae728ec60818c340eb03428d632bb067e179363ed75d7d991f' ++ ], ++ [ ++ 'b8da94032a957518eb0f6433571e8761ceffc73693e84edd49150a564f676e03', ++ '2804dfa44805a1e4d7c99cc9762808b092cc584d95ff3b511488e4e74efdf6e7' ++ ], ++ [ ++ 'e80fea14441fb33a7d8adab9475d7fab2019effb5156a792f1a11778e3c0df5d', ++ 'eed1de7f638e00771e89768ca3ca94472d155e80af322ea9fcb4291b6ac9ec78' ++ ], ++ [ ++ 'a301697bdfcd704313ba48e51d567543f2a182031efd6915ddc07bbcc4e16070', ++ '7370f91cfb67e4f5081809fa25d40f9b1735dbf7c0a11a130c0d1a041e177ea1' ++ ], ++ [ ++ '90ad85b389d6b936463f9d0512678de208cc330b11307fffab7ac63e3fb04ed4', ++ 'e507a3620a38261affdcbd9427222b839aefabe1582894d991d4d48cb6ef150' ++ ], ++ [ ++ '8f68b9d2f63b5f339239c1ad981f162ee88c5678723ea3351b7b444c9ec4c0da', ++ '662a9f2dba063986de1d90c2b6be215dbbea2cfe95510bfdf23cbf79501fff82' ++ ], ++ [ ++ 'e4f3fb0176af85d65ff99ff9198c36091f48e86503681e3e6686fd5053231e11', ++ '1e63633ad0ef4f1c1661a6d0ea02b7286cc7e74ec951d1c9822c38576feb73bc' ++ ], ++ [ ++ '8c00fa9b18ebf331eb961537a45a4266c7034f2f0d4e1d0716fb6eae20eae29e', ++ 'efa47267fea521a1a9dc343a3736c974c2fadafa81e36c54e7d2a4c66702414b' ++ ], ++ [ ++ 'e7a26ce69dd4829f3e10cec0a9e98ed3143d084f308b92c0997fddfc60cb3e41', ++ '2a758e300fa7984b471b006a1aafbb18d0a6b2c0420e83e20e8a9421cf2cfd51' ++ ], ++ [ ++ 'b6459e0ee3662ec8d23540c223bcbdc571cbcb967d79424f3cf29eb3de6b80ef', ++ '67c876d06f3e06de1dadf16e5661db3c4b3ae6d48e35b2ff30bf0b61a71ba45' ++ ], ++ [ ++ 'd68a80c8280bb840793234aa118f06231d6f1fc67e73c5a5deda0f5b496943e8', ++ 'db8ba9fff4b586d00c4b1f9177b0e28b5b0e7b8f7845295a294c84266b133120' ++ ], ++ [ ++ '324aed7df65c804252dc0270907a30b09612aeb973449cea4095980fc28d3d5d', ++ '648a365774b61f2ff130c0c35aec1f4f19213b0c7e332843967224af96ab7c84' ++ ], ++ [ ++ '4df9c14919cde61f6d51dfdbe5fee5dceec4143ba8d1ca888e8bd373fd054c96', ++ '35ec51092d8728050974c23a1d85d4b5d506cdc288490192ebac06cad10d5d' ++ ], ++ [ ++ '9c3919a84a474870faed8a9c1cc66021523489054d7f0308cbfc99c8ac1f98cd', ++ 'ddb84f0f4a4ddd57584f044bf260e641905326f76c64c8e6be7e5e03d4fc599d' ++ ], ++ [ ++ '6057170b1dd12fdf8de05f281d8e06bb91e1493a8b91d4cc5a21382120a959e5', ++ '9a1af0b26a6a4807add9a2daf71df262465152bc3ee24c65e899be932385a2a8' ++ ], ++ [ ++ 'a576df8e23a08411421439a4518da31880cef0fba7d4df12b1a6973eecb94266', ++ '40a6bf20e76640b2c92b97afe58cd82c432e10a7f514d9f3ee8be11ae1b28ec8' ++ ], ++ [ ++ '7778a78c28dec3e30a05fe9629de8c38bb30d1f5cf9a3a208f763889be58ad71', ++ '34626d9ab5a5b22ff7098e12f2ff580087b38411ff24ac563b513fc1fd9f43ac' ++ ], ++ [ ++ '928955ee637a84463729fd30e7afd2ed5f96274e5ad7e5cb09eda9c06d903ac', ++ 'c25621003d3f42a827b78a13093a95eeac3d26efa8a8d83fc5180e935bcd091f' ++ ], ++ [ ++ '85d0fef3ec6db109399064f3a0e3b2855645b4a907ad354527aae75163d82751', ++ '1f03648413a38c0be29d496e582cf5663e8751e96877331582c237a24eb1f962' ++ ], ++ [ ++ 'ff2b0dce97eece97c1c9b6041798b85dfdfb6d8882da20308f5404824526087e', ++ '493d13fef524ba188af4c4dc54d07936c7b7ed6fb90e2ceb2c951e01f0c29907' ++ ], ++ [ ++ '827fbbe4b1e880ea9ed2b2e6301b212b57f1ee148cd6dd28780e5e2cf856e241', ++ 'c60f9c923c727b0b71bef2c67d1d12687ff7a63186903166d605b68baec293ec' ++ ], ++ [ ++ 'eaa649f21f51bdbae7be4ae34ce6e5217a58fdce7f47f9aa7f3b58fa2120e2b3', ++ 'be3279ed5bbbb03ac69a80f89879aa5a01a6b965f13f7e59d47a5305ba5ad93d' ++ ], ++ [ ++ 'e4a42d43c5cf169d9391df6decf42ee541b6d8f0c9a137401e23632dda34d24f', ++ '4d9f92e716d1c73526fc99ccfb8ad34ce886eedfa8d8e4f13a7f7131deba9414' ++ ], ++ [ ++ '1ec80fef360cbdd954160fadab352b6b92b53576a88fea4947173b9d4300bf19', ++ 'aeefe93756b5340d2f3a4958a7abbf5e0146e77f6295a07b671cdc1cc107cefd' ++ ], ++ [ ++ '146a778c04670c2f91b00af4680dfa8bce3490717d58ba889ddb5928366642be', ++ 'b318e0ec3354028add669827f9d4b2870aaa971d2f7e5ed1d0b297483d83efd0' ++ ], ++ [ ++ 'fa50c0f61d22e5f07e3acebb1aa07b128d0012209a28b9776d76a8793180eef9', ++ '6b84c6922397eba9b72cd2872281a68a5e683293a57a213b38cd8d7d3f4f2811' ++ ], ++ [ ++ 'da1d61d0ca721a11b1a5bf6b7d88e8421a288ab5d5bba5220e53d32b5f067ec2', ++ '8157f55a7c99306c79c0766161c91e2966a73899d279b48a655fba0f1ad836f1' ++ ], ++ [ ++ 'a8e282ff0c9706907215ff98e8fd416615311de0446f1e062a73b0610d064e13', ++ '7f97355b8db81c09abfb7f3c5b2515888b679a3e50dd6bd6cef7c73111f4cc0c' ++ ], ++ [ ++ '174a53b9c9a285872d39e56e6913cab15d59b1fa512508c022f382de8319497c', ++ 'ccc9dc37abfc9c1657b4155f2c47f9e6646b3a1d8cb9854383da13ac079afa73' ++ ], ++ [ ++ '959396981943785c3d3e57edf5018cdbe039e730e4918b3d884fdff09475b7ba', ++ '2e7e552888c331dd8ba0386a4b9cd6849c653f64c8709385e9b8abf87524f2fd' ++ ], ++ [ ++ 'd2a63a50ae401e56d645a1153b109a8fcca0a43d561fba2dbb51340c9d82b151', ++ 'e82d86fb6443fcb7565aee58b2948220a70f750af484ca52d4142174dcf89405' ++ ], ++ [ ++ '64587e2335471eb890ee7896d7cfdc866bacbdbd3839317b3436f9b45617e073', ++ 'd99fcdd5bf6902e2ae96dd6447c299a185b90a39133aeab358299e5e9faf6589' ++ ], ++ [ ++ '8481bde0e4e4d885b3a546d3e549de042f0aa6cea250e7fd358d6c86dd45e458', ++ '38ee7b8cba5404dd84a25bf39cecb2ca900a79c42b262e556d64b1b59779057e' ++ ], ++ [ ++ '13464a57a78102aa62b6979ae817f4637ffcfed3c4b1ce30bcd6303f6caf666b', ++ '69be159004614580ef7e433453ccb0ca48f300a81d0942e13f495a907f6ecc27' ++ ], ++ [ ++ 'bc4a9df5b713fe2e9aef430bcc1dc97a0cd9ccede2f28588cada3a0d2d83f366', ++ 'd3a81ca6e785c06383937adf4b798caa6e8a9fbfa547b16d758d666581f33c1' ++ ], ++ [ ++ '8c28a97bf8298bc0d23d8c749452a32e694b65e30a9472a3954ab30fe5324caa', ++ '40a30463a3305193378fedf31f7cc0eb7ae784f0451cb9459e71dc73cbef9482' ++ ], ++ [ ++ '8ea9666139527a8c1dd94ce4f071fd23c8b350c5a4bb33748c4ba111faccae0', ++ '620efabbc8ee2782e24e7c0cfb95c5d735b783be9cf0f8e955af34a30e62b945' ++ ], ++ [ ++ 'dd3625faef5ba06074669716bbd3788d89bdde815959968092f76cc4eb9a9787', ++ '7a188fa3520e30d461da2501045731ca941461982883395937f68d00c644a573' ++ ], ++ [ ++ 'f710d79d9eb962297e4f6232b40e8f7feb2bc63814614d692c12de752408221e', ++ 'ea98e67232d3b3295d3b535532115ccac8612c721851617526ae47a9c77bfc82' ++ ] ++ ] ++ }, ++ naf: { ++ wnd: 7, ++ points: [ ++ [ ++ 'f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9', ++ '388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672' ++ ], ++ [ ++ '2f8bde4d1a07209355b4a7250a5c5128e88b84bddc619ab7cba8d569b240efe4', ++ 'd8ac222636e5e3d6d4dba9dda6c9c426f788271bab0d6840dca87d3aa6ac62d6' ++ ], ++ [ ++ '5cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc', ++ '6aebca40ba255960a3178d6d861a54dba813d0b813fde7b5a5082628087264da' ++ ], ++ [ ++ 'acd484e2f0c7f65309ad178a9f559abde09796974c57e714c35f110dfc27ccbe', ++ 'cc338921b0a7d9fd64380971763b61e9add888a4375f8e0f05cc262ac64f9c37' ++ ], ++ [ ++ '774ae7f858a9411e5ef4246b70c65aac5649980be5c17891bbec17895da008cb', ++ 'd984a032eb6b5e190243dd56d7b7b365372db1e2dff9d6a8301d74c9c953c61b' ++ ], ++ [ ++ 'f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8', ++ 'ab0902e8d880a89758212eb65cdaf473a1a06da521fa91f29b5cb52db03ed81' ++ ], ++ [ ++ 'd7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e', ++ '581e2872a86c72a683842ec228cc6defea40af2bd896d3a5c504dc9ff6a26b58' ++ ], ++ [ ++ 'defdea4cdb677750a420fee807eacf21eb9898ae79b9768766e4faa04a2d4a34', ++ '4211ab0694635168e997b0ead2a93daeced1f4a04a95c0f6cfb199f69e56eb77' ++ ], ++ [ ++ '2b4ea0a797a443d293ef5cff444f4979f06acfebd7e86d277475656138385b6c', ++ '85e89bc037945d93b343083b5a1c86131a01f60c50269763b570c854e5c09b7a' ++ ], ++ [ ++ '352bbf4a4cdd12564f93fa332ce333301d9ad40271f8107181340aef25be59d5', ++ '321eb4075348f534d59c18259dda3e1f4a1b3b2e71b1039c67bd3d8bcf81998c' ++ ], ++ [ ++ '2fa2104d6b38d11b0230010559879124e42ab8dfeff5ff29dc9cdadd4ecacc3f', ++ '2de1068295dd865b64569335bd5dd80181d70ecfc882648423ba76b532b7d67' ++ ], ++ [ ++ '9248279b09b4d68dab21a9b066edda83263c3d84e09572e269ca0cd7f5453714', ++ '73016f7bf234aade5d1aa71bdea2b1ff3fc0de2a887912ffe54a32ce97cb3402' ++ ], ++ [ ++ 'daed4f2be3a8bf278e70132fb0beb7522f570e144bf615c07e996d443dee8729', ++ 'a69dce4a7d6c98e8d4a1aca87ef8d7003f83c230f3afa726ab40e52290be1c55' ++ ], ++ [ ++ 'c44d12c7065d812e8acf28d7cbb19f9011ecd9e9fdf281b0e6a3b5e87d22e7db', ++ '2119a460ce326cdc76c45926c982fdac0e106e861edf61c5a039063f0e0e6482' ++ ], ++ [ ++ '6a245bf6dc698504c89a20cfded60853152b695336c28063b61c65cbd269e6b4', ++ 'e022cf42c2bd4a708b3f5126f16a24ad8b33ba48d0423b6efd5e6348100d8a82' ++ ], ++ [ ++ '1697ffa6fd9de627c077e3d2fe541084ce13300b0bec1146f95ae57f0d0bd6a5', ++ 'b9c398f186806f5d27561506e4557433a2cf15009e498ae7adee9d63d01b2396' ++ ], ++ [ ++ '605bdb019981718b986d0f07e834cb0d9deb8360ffb7f61df982345ef27a7479', ++ '2972d2de4f8d20681a78d93ec96fe23c26bfae84fb14db43b01e1e9056b8c49' ++ ], ++ [ ++ '62d14dab4150bf497402fdc45a215e10dcb01c354959b10cfe31c7e9d87ff33d', ++ '80fc06bd8cc5b01098088a1950eed0db01aa132967ab472235f5642483b25eaf' ++ ], ++ [ ++ '80c60ad0040f27dade5b4b06c408e56b2c50e9f56b9b8b425e555c2f86308b6f', ++ '1c38303f1cc5c30f26e66bad7fe72f70a65eed4cbe7024eb1aa01f56430bd57a' ++ ], ++ [ ++ '7a9375ad6167ad54aa74c6348cc54d344cc5dc9487d847049d5eabb0fa03c8fb', ++ 'd0e3fa9eca8726909559e0d79269046bdc59ea10c70ce2b02d499ec224dc7f7' ++ ], ++ [ ++ 'd528ecd9b696b54c907a9ed045447a79bb408ec39b68df504bb51f459bc3ffc9', ++ 'eecf41253136e5f99966f21881fd656ebc4345405c520dbc063465b521409933' ++ ], ++ [ ++ '49370a4b5f43412ea25f514e8ecdad05266115e4a7ecb1387231808f8b45963', ++ '758f3f41afd6ed428b3081b0512fd62a54c3f3afbb5b6764b653052a12949c9a' ++ ], ++ [ ++ '77f230936ee88cbbd73df930d64702ef881d811e0e1498e2f1c13eb1fc345d74', ++ '958ef42a7886b6400a08266e9ba1b37896c95330d97077cbbe8eb3c7671c60d6' ++ ], ++ [ ++ 'f2dac991cc4ce4b9ea44887e5c7c0bce58c80074ab9d4dbaeb28531b7739f530', ++ 'e0dedc9b3b2f8dad4da1f32dec2531df9eb5fbeb0598e4fd1a117dba703a3c37' ++ ], ++ [ ++ '463b3d9f662621fb1b4be8fbbe2520125a216cdfc9dae3debcba4850c690d45b', ++ '5ed430d78c296c3543114306dd8622d7c622e27c970a1de31cb377b01af7307e' ++ ], ++ [ ++ 'f16f804244e46e2a09232d4aff3b59976b98fac14328a2d1a32496b49998f247', ++ 'cedabd9b82203f7e13d206fcdf4e33d92a6c53c26e5cce26d6579962c4e31df6' ++ ], ++ [ ++ 'caf754272dc84563b0352b7a14311af55d245315ace27c65369e15f7151d41d1', ++ 'cb474660ef35f5f2a41b643fa5e460575f4fa9b7962232a5c32f908318a04476' ++ ], ++ [ ++ '2600ca4b282cb986f85d0f1709979d8b44a09c07cb86d7c124497bc86f082120', ++ '4119b88753c15bd6a693b03fcddbb45d5ac6be74ab5f0ef44b0be9475a7e4b40' ++ ], ++ [ ++ '7635ca72d7e8432c338ec53cd12220bc01c48685e24f7dc8c602a7746998e435', ++ '91b649609489d613d1d5e590f78e6d74ecfc061d57048bad9e76f302c5b9c61' ++ ], ++ [ ++ '754e3239f325570cdbbf4a87deee8a66b7f2b33479d468fbc1a50743bf56cc18', ++ '673fb86e5bda30fb3cd0ed304ea49a023ee33d0197a695d0c5d98093c536683' ++ ], ++ [ ++ 'e3e6bd1071a1e96aff57859c82d570f0330800661d1c952f9fe2694691d9b9e8', ++ '59c9e0bba394e76f40c0aa58379a3cb6a5a2283993e90c4167002af4920e37f5' ++ ], ++ [ ++ '186b483d056a033826ae73d88f732985c4ccb1f32ba35f4b4cc47fdcf04aa6eb', ++ '3b952d32c67cf77e2e17446e204180ab21fb8090895138b4a4a797f86e80888b' ++ ], ++ [ ++ 'df9d70a6b9876ce544c98561f4be4f725442e6d2b737d9c91a8321724ce0963f', ++ '55eb2dafd84d6ccd5f862b785dc39d4ab157222720ef9da217b8c45cf2ba2417' ++ ], ++ [ ++ '5edd5cc23c51e87a497ca815d5dce0f8ab52554f849ed8995de64c5f34ce7143', ++ 'efae9c8dbc14130661e8cec030c89ad0c13c66c0d17a2905cdc706ab7399a868' ++ ], ++ [ ++ '290798c2b6476830da12fe02287e9e777aa3fba1c355b17a722d362f84614fba', ++ 'e38da76dcd440621988d00bcf79af25d5b29c094db2a23146d003afd41943e7a' ++ ], ++ [ ++ 'af3c423a95d9f5b3054754efa150ac39cd29552fe360257362dfdecef4053b45', ++ 'f98a3fd831eb2b749a93b0e6f35cfb40c8cd5aa667a15581bc2feded498fd9c6' ++ ], ++ [ ++ '766dbb24d134e745cccaa28c99bf274906bb66b26dcf98df8d2fed50d884249a', ++ '744b1152eacbe5e38dcc887980da38b897584a65fa06cedd2c924f97cbac5996' ++ ], ++ [ ++ '59dbf46f8c94759ba21277c33784f41645f7b44f6c596a58ce92e666191abe3e', ++ 'c534ad44175fbc300f4ea6ce648309a042ce739a7919798cd85e216c4a307f6e' ++ ], ++ [ ++ 'f13ada95103c4537305e691e74e9a4a8dd647e711a95e73cb62dc6018cfd87b8', ++ 'e13817b44ee14de663bf4bc808341f326949e21a6a75c2570778419bdaf5733d' ++ ], ++ [ ++ '7754b4fa0e8aced06d4167a2c59cca4cda1869c06ebadfb6488550015a88522c', ++ '30e93e864e669d82224b967c3020b8fa8d1e4e350b6cbcc537a48b57841163a2' ++ ], ++ [ ++ '948dcadf5990e048aa3874d46abef9d701858f95de8041d2a6828c99e2262519', ++ 'e491a42537f6e597d5d28a3224b1bc25df9154efbd2ef1d2cbba2cae5347d57e' ++ ], ++ [ ++ '7962414450c76c1689c7b48f8202ec37fb224cf5ac0bfa1570328a8a3d7c77ab', ++ '100b610ec4ffb4760d5c1fc133ef6f6b12507a051f04ac5760afa5b29db83437' ++ ], ++ [ ++ '3514087834964b54b15b160644d915485a16977225b8847bb0dd085137ec47ca', ++ 'ef0afbb2056205448e1652c48e8127fc6039e77c15c2378b7e7d15a0de293311' ++ ], ++ [ ++ 'd3cc30ad6b483e4bc79ce2c9dd8bc54993e947eb8df787b442943d3f7b527eaf', ++ '8b378a22d827278d89c5e9be8f9508ae3c2ad46290358630afb34db04eede0a4' ++ ], ++ [ ++ '1624d84780732860ce1c78fcbfefe08b2b29823db913f6493975ba0ff4847610', ++ '68651cf9b6da903e0914448c6cd9d4ca896878f5282be4c8cc06e2a404078575' ++ ], ++ [ ++ '733ce80da955a8a26902c95633e62a985192474b5af207da6df7b4fd5fc61cd4', ++ 'f5435a2bd2badf7d485a4d8b8db9fcce3e1ef8e0201e4578c54673bc1dc5ea1d' ++ ], ++ [ ++ '15d9441254945064cf1a1c33bbd3b49f8966c5092171e699ef258dfab81c045c', ++ 'd56eb30b69463e7234f5137b73b84177434800bacebfc685fc37bbe9efe4070d' ++ ], ++ [ ++ 'a1d0fcf2ec9de675b612136e5ce70d271c21417c9d2b8aaaac138599d0717940', ++ 'edd77f50bcb5a3cab2e90737309667f2641462a54070f3d519212d39c197a629' ++ ], ++ [ ++ 'e22fbe15c0af8ccc5780c0735f84dbe9a790badee8245c06c7ca37331cb36980', ++ 'a855babad5cd60c88b430a69f53a1a7a38289154964799be43d06d77d31da06' ++ ], ++ [ ++ '311091dd9860e8e20ee13473c1155f5f69635e394704eaa74009452246cfa9b3', ++ '66db656f87d1f04fffd1f04788c06830871ec5a64feee685bd80f0b1286d8374' ++ ], ++ [ ++ '34c1fd04d301be89b31c0442d3e6ac24883928b45a9340781867d4232ec2dbdf', ++ '9414685e97b1b5954bd46f730174136d57f1ceeb487443dc5321857ba73abee' ++ ], ++ [ ++ 'f219ea5d6b54701c1c14de5b557eb42a8d13f3abbcd08affcc2a5e6b049b8d63', ++ '4cb95957e83d40b0f73af4544cccf6b1f4b08d3c07b27fb8d8c2962a400766d1' ++ ], ++ [ ++ 'd7b8740f74a8fbaab1f683db8f45de26543a5490bca627087236912469a0b448', ++ 'fa77968128d9c92ee1010f337ad4717eff15db5ed3c049b3411e0315eaa4593b' ++ ], ++ [ ++ '32d31c222f8f6f0ef86f7c98d3a3335ead5bcd32abdd94289fe4d3091aa824bf', ++ '5f3032f5892156e39ccd3d7915b9e1da2e6dac9e6f26e961118d14b8462e1661' ++ ], ++ [ ++ '7461f371914ab32671045a155d9831ea8793d77cd59592c4340f86cbc18347b5', ++ '8ec0ba238b96bec0cbdddcae0aa442542eee1ff50c986ea6b39847b3cc092ff6' ++ ], ++ [ ++ 'ee079adb1df1860074356a25aa38206a6d716b2c3e67453d287698bad7b2b2d6', ++ '8dc2412aafe3be5c4c5f37e0ecc5f9f6a446989af04c4e25ebaac479ec1c8c1e' ++ ], ++ [ ++ '16ec93e447ec83f0467b18302ee620f7e65de331874c9dc72bfd8616ba9da6b5', ++ '5e4631150e62fb40d0e8c2a7ca5804a39d58186a50e497139626778e25b0674d' ++ ], ++ [ ++ 'eaa5f980c245f6f038978290afa70b6bd8855897f98b6aa485b96065d537bd99', ++ 'f65f5d3e292c2e0819a528391c994624d784869d7e6ea67fb18041024edc07dc' ++ ], ++ [ ++ '78c9407544ac132692ee1910a02439958ae04877151342ea96c4b6b35a49f51', ++ 'f3e0319169eb9b85d5404795539a5e68fa1fbd583c064d2462b675f194a3ddb4' ++ ], ++ [ ++ '494f4be219a1a77016dcd838431aea0001cdc8ae7a6fc688726578d9702857a5', ++ '42242a969283a5f339ba7f075e36ba2af925ce30d767ed6e55f4b031880d562c' ++ ], ++ [ ++ 'a598a8030da6d86c6bc7f2f5144ea549d28211ea58faa70ebf4c1e665c1fe9b5', ++ '204b5d6f84822c307e4b4a7140737aec23fc63b65b35f86a10026dbd2d864e6b' ++ ], ++ [ ++ 'c41916365abb2b5d09192f5f2dbeafec208f020f12570a184dbadc3e58595997', ++ '4f14351d0087efa49d245b328984989d5caf9450f34bfc0ed16e96b58fa9913' ++ ], ++ [ ++ '841d6063a586fa475a724604da03bc5b92a2e0d2e0a36acfe4c73a5514742881', ++ '73867f59c0659e81904f9a1c7543698e62562d6744c169ce7a36de01a8d6154' ++ ], ++ [ ++ '5e95bb399a6971d376026947f89bde2f282b33810928be4ded112ac4d70e20d5', ++ '39f23f366809085beebfc71181313775a99c9aed7d8ba38b161384c746012865' ++ ], ++ [ ++ '36e4641a53948fd476c39f8a99fd974e5ec07564b5315d8bf99471bca0ef2f66', ++ 'd2424b1b1abe4eb8164227b085c9aa9456ea13493fd563e06fd51cf5694c78fc' ++ ], ++ [ ++ '336581ea7bfbbb290c191a2f507a41cf5643842170e914faeab27c2c579f726', ++ 'ead12168595fe1be99252129b6e56b3391f7ab1410cd1e0ef3dcdcabd2fda224' ++ ], ++ [ ++ '8ab89816dadfd6b6a1f2634fcf00ec8403781025ed6890c4849742706bd43ede', ++ '6fdcef09f2f6d0a044e654aef624136f503d459c3e89845858a47a9129cdd24e' ++ ], ++ [ ++ '1e33f1a746c9c5778133344d9299fcaa20b0938e8acff2544bb40284b8c5fb94', ++ '60660257dd11b3aa9c8ed618d24edff2306d320f1d03010e33a7d2057f3b3b6' ++ ], ++ [ ++ '85b7c1dcb3cec1b7ee7f30ded79dd20a0ed1f4cc18cbcfcfa410361fd8f08f31', ++ '3d98a9cdd026dd43f39048f25a8847f4fcafad1895d7a633c6fed3c35e999511' ++ ], ++ [ ++ '29df9fbd8d9e46509275f4b125d6d45d7fbe9a3b878a7af872a2800661ac5f51', ++ 'b4c4fe99c775a606e2d8862179139ffda61dc861c019e55cd2876eb2a27d84b' ++ ], ++ [ ++ 'a0b1cae06b0a847a3fea6e671aaf8adfdfe58ca2f768105c8082b2e449fce252', ++ 'ae434102edde0958ec4b19d917a6a28e6b72da1834aff0e650f049503a296cf2' ++ ], ++ [ ++ '4e8ceafb9b3e9a136dc7ff67e840295b499dfb3b2133e4ba113f2e4c0e121e5', ++ 'cf2174118c8b6d7a4b48f6d534ce5c79422c086a63460502b827ce62a326683c' ++ ], ++ [ ++ 'd24a44e047e19b6f5afb81c7ca2f69080a5076689a010919f42725c2b789a33b', ++ '6fb8d5591b466f8fc63db50f1c0f1c69013f996887b8244d2cdec417afea8fa3' ++ ], ++ [ ++ 'ea01606a7a6c9cdd249fdfcfacb99584001edd28abbab77b5104e98e8e3b35d4', ++ '322af4908c7312b0cfbfe369f7a7b3cdb7d4494bc2823700cfd652188a3ea98d' ++ ], ++ [ ++ 'af8addbf2b661c8a6c6328655eb96651252007d8c5ea31be4ad196de8ce2131f', ++ '6749e67c029b85f52a034eafd096836b2520818680e26ac8f3dfbcdb71749700' ++ ], ++ [ ++ 'e3ae1974566ca06cc516d47e0fb165a674a3dabcfca15e722f0e3450f45889', ++ '2aeabe7e4531510116217f07bf4d07300de97e4874f81f533420a72eeb0bd6a4' ++ ], ++ [ ++ '591ee355313d99721cf6993ffed1e3e301993ff3ed258802075ea8ced397e246', ++ 'b0ea558a113c30bea60fc4775460c7901ff0b053d25ca2bdeee98f1a4be5d196' ++ ], ++ [ ++ '11396d55fda54c49f19aa97318d8da61fa8584e47b084945077cf03255b52984', ++ '998c74a8cd45ac01289d5833a7beb4744ff536b01b257be4c5767bea93ea57a4' ++ ], ++ [ ++ '3c5d2a1ba39c5a1790000738c9e0c40b8dcdfd5468754b6405540157e017aa7a', ++ 'b2284279995a34e2f9d4de7396fc18b80f9b8b9fdd270f6661f79ca4c81bd257' ++ ], ++ [ ++ 'cc8704b8a60a0defa3a99a7299f2e9c3fbc395afb04ac078425ef8a1793cc030', ++ 'bdd46039feed17881d1e0862db347f8cf395b74fc4bcdc4e940b74e3ac1f1b13' ++ ], ++ [ ++ 'c533e4f7ea8555aacd9777ac5cad29b97dd4defccc53ee7ea204119b2889b197', ++ '6f0a256bc5efdf429a2fb6242f1a43a2d9b925bb4a4b3a26bb8e0f45eb596096' ++ ], ++ [ ++ 'c14f8f2ccb27d6f109f6d08d03cc96a69ba8c34eec07bbcf566d48e33da6593', ++ 'c359d6923bb398f7fd4473e16fe1c28475b740dd098075e6c0e8649113dc3a38' ++ ], ++ [ ++ 'a6cbc3046bc6a450bac24789fa17115a4c9739ed75f8f21ce441f72e0b90e6ef', ++ '21ae7f4680e889bb130619e2c0f95a360ceb573c70603139862afd617fa9b9f' ++ ], ++ [ ++ '347d6d9a02c48927ebfb86c1359b1caf130a3c0267d11ce6344b39f99d43cc38', ++ '60ea7f61a353524d1c987f6ecec92f086d565ab687870cb12689ff1e31c74448' ++ ], ++ [ ++ 'da6545d2181db8d983f7dcb375ef5866d47c67b1bf31c8cf855ef7437b72656a', ++ '49b96715ab6878a79e78f07ce5680c5d6673051b4935bd897fea824b77dc208a' ++ ], ++ [ ++ 'c40747cc9d012cb1a13b8148309c6de7ec25d6945d657146b9d5994b8feb1111', ++ '5ca560753be2a12fc6de6caf2cb489565db936156b9514e1bb5e83037e0fa2d4' ++ ], ++ [ ++ '4e42c8ec82c99798ccf3a610be870e78338c7f713348bd34c8203ef4037f3502', ++ '7571d74ee5e0fb92a7a8b33a07783341a5492144cc54bcc40a94473693606437' ++ ], ++ [ ++ '3775ab7089bc6af823aba2e1af70b236d251cadb0c86743287522a1b3b0dedea', ++ 'be52d107bcfa09d8bcb9736a828cfa7fac8db17bf7a76a2c42ad961409018cf7' ++ ], ++ [ ++ 'cee31cbf7e34ec379d94fb814d3d775ad954595d1314ba8846959e3e82f74e26', ++ '8fd64a14c06b589c26b947ae2bcf6bfa0149ef0be14ed4d80f448a01c43b1c6d' ++ ], ++ [ ++ 'b4f9eaea09b6917619f6ea6a4eb5464efddb58fd45b1ebefcdc1a01d08b47986', ++ '39e5c9925b5a54b07433a4f18c61726f8bb131c012ca542eb24a8ac07200682a' ++ ], ++ [ ++ 'd4263dfc3d2df923a0179a48966d30ce84e2515afc3dccc1b77907792ebcc60e', ++ '62dfaf07a0f78feb30e30d6295853ce189e127760ad6cf7fae164e122a208d54' ++ ], ++ [ ++ '48457524820fa65a4f8d35eb6930857c0032acc0a4a2de422233eeda897612c4', ++ '25a748ab367979d98733c38a1fa1c2e7dc6cc07db2d60a9ae7a76aaa49bd0f77' ++ ], ++ [ ++ 'dfeeef1881101f2cb11644f3a2afdfc2045e19919152923f367a1767c11cceda', ++ 'ecfb7056cf1de042f9420bab396793c0c390bde74b4bbdff16a83ae09a9a7517' ++ ], ++ [ ++ '6d7ef6b17543f8373c573f44e1f389835d89bcbc6062ced36c82df83b8fae859', ++ 'cd450ec335438986dfefa10c57fea9bcc521a0959b2d80bbf74b190dca712d10' ++ ], ++ [ ++ 'e75605d59102a5a2684500d3b991f2e3f3c88b93225547035af25af66e04541f', ++ 'f5c54754a8f71ee540b9b48728473e314f729ac5308b06938360990e2bfad125' ++ ], ++ [ ++ 'eb98660f4c4dfaa06a2be453d5020bc99a0c2e60abe388457dd43fefb1ed620c', ++ '6cb9a8876d9cb8520609af3add26cd20a0a7cd8a9411131ce85f44100099223e' ++ ], ++ [ ++ '13e87b027d8514d35939f2e6892b19922154596941888336dc3563e3b8dba942', ++ 'fef5a3c68059a6dec5d624114bf1e91aac2b9da568d6abeb2570d55646b8adf1' ++ ], ++ [ ++ 'ee163026e9fd6fe017c38f06a5be6fc125424b371ce2708e7bf4491691e5764a', ++ '1acb250f255dd61c43d94ccc670d0f58f49ae3fa15b96623e5430da0ad6c62b2' ++ ], ++ [ ++ 'b268f5ef9ad51e4d78de3a750c2dc89b1e626d43505867999932e5db33af3d80', ++ '5f310d4b3c99b9ebb19f77d41c1dee018cf0d34fd4191614003e945a1216e423' ++ ], ++ [ ++ 'ff07f3118a9df035e9fad85eb6c7bfe42b02f01ca99ceea3bf7ffdba93c4750d', ++ '438136d603e858a3a5c440c38eccbaddc1d2942114e2eddd4740d098ced1f0d8' ++ ], ++ [ ++ '8d8b9855c7c052a34146fd20ffb658bea4b9f69e0d825ebec16e8c3ce2b526a1', ++ 'cdb559eedc2d79f926baf44fb84ea4d44bcf50fee51d7ceb30e2e7f463036758' ++ ], ++ [ ++ '52db0b5384dfbf05bfa9d472d7ae26dfe4b851ceca91b1eba54263180da32b63', ++ 'c3b997d050ee5d423ebaf66a6db9f57b3180c902875679de924b69d84a7b375' ++ ], ++ [ ++ 'e62f9490d3d51da6395efd24e80919cc7d0f29c3f3fa48c6fff543becbd43352', ++ '6d89ad7ba4876b0b22c2ca280c682862f342c8591f1daf5170e07bfd9ccafa7d' ++ ], ++ [ ++ '7f30ea2476b399b4957509c88f77d0191afa2ff5cb7b14fd6d8e7d65aaab1193', ++ 'ca5ef7d4b231c94c3b15389a5f6311e9daff7bb67b103e9880ef4bff637acaec' ++ ], ++ [ ++ '5098ff1e1d9f14fb46a210fada6c903fef0fb7b4a1dd1d9ac60a0361800b7a00', ++ '9731141d81fc8f8084d37c6e7542006b3ee1b40d60dfe5362a5b132fd17ddc0' ++ ], ++ [ ++ '32b78c7de9ee512a72895be6b9cbefa6e2f3c4ccce445c96b9f2c81e2778ad58', ++ 'ee1849f513df71e32efc3896ee28260c73bb80547ae2275ba497237794c8753c' ++ ], ++ [ ++ 'e2cb74fddc8e9fbcd076eef2a7c72b0ce37d50f08269dfc074b581550547a4f7', ++ 'd3aa2ed71c9dd2247a62df062736eb0baddea9e36122d2be8641abcb005cc4a4' ++ ], ++ [ ++ '8438447566d4d7bedadc299496ab357426009a35f235cb141be0d99cd10ae3a8', ++ 'c4e1020916980a4da5d01ac5e6ad330734ef0d7906631c4f2390426b2edd791f' ++ ], ++ [ ++ '4162d488b89402039b584c6fc6c308870587d9c46f660b878ab65c82c711d67e', ++ '67163e903236289f776f22c25fb8a3afc1732f2b84b4e95dbda47ae5a0852649' ++ ], ++ [ ++ '3fad3fa84caf0f34f0f89bfd2dcf54fc175d767aec3e50684f3ba4a4bf5f683d', ++ 'cd1bc7cb6cc407bb2f0ca647c718a730cf71872e7d0d2a53fa20efcdfe61826' ++ ], ++ [ ++ '674f2600a3007a00568c1a7ce05d0816c1fb84bf1370798f1c69532faeb1a86b', ++ '299d21f9413f33b3edf43b257004580b70db57da0b182259e09eecc69e0d38a5' ++ ], ++ [ ++ 'd32f4da54ade74abb81b815ad1fb3b263d82d6c692714bcff87d29bd5ee9f08f', ++ 'f9429e738b8e53b968e99016c059707782e14f4535359d582fc416910b3eea87' ++ ], ++ [ ++ '30e4e670435385556e593657135845d36fbb6931f72b08cb1ed954f1e3ce3ff6', ++ '462f9bce619898638499350113bbc9b10a878d35da70740dc695a559eb88db7b' ++ ], ++ [ ++ 'be2062003c51cc3004682904330e4dee7f3dcd10b01e580bf1971b04d4cad297', ++ '62188bc49d61e5428573d48a74e1c655b1c61090905682a0d5558ed72dccb9bc' ++ ], ++ [ ++ '93144423ace3451ed29e0fb9ac2af211cb6e84a601df5993c419859fff5df04a', ++ '7c10dfb164c3425f5c71a3f9d7992038f1065224f72bb9d1d902a6d13037b47c' ++ ], ++ [ ++ 'b015f8044f5fcbdcf21ca26d6c34fb8197829205c7b7d2a7cb66418c157b112c', ++ 'ab8c1e086d04e813744a655b2df8d5f83b3cdc6faa3088c1d3aea1454e3a1d5f' ++ ], ++ [ ++ 'd5e9e1da649d97d89e4868117a465a3a4f8a18de57a140d36b3f2af341a21b52', ++ '4cb04437f391ed73111a13cc1d4dd0db1693465c2240480d8955e8592f27447a' ++ ], ++ [ ++ 'd3ae41047dd7ca065dbf8ed77b992439983005cd72e16d6f996a5316d36966bb', ++ 'bd1aeb21ad22ebb22a10f0303417c6d964f8cdd7df0aca614b10dc14d125ac46' ++ ], ++ [ ++ '463e2763d885f958fc66cdd22800f0a487197d0a82e377b49f80af87c897b065', ++ 'bfefacdb0e5d0fd7df3a311a94de062b26b80c61fbc97508b79992671ef7ca7f' ++ ], ++ [ ++ '7985fdfd127c0567c6f53ec1bb63ec3158e597c40bfe747c83cddfc910641917', ++ '603c12daf3d9862ef2b25fe1de289aed24ed291e0ec6708703a5bd567f32ed03' ++ ], ++ [ ++ '74a1ad6b5f76e39db2dd249410eac7f99e74c59cb83d2d0ed5ff1543da7703e9', ++ 'cc6157ef18c9c63cd6193d83631bbea0093e0968942e8c33d5737fd790e0db08' ++ ], ++ [ ++ '30682a50703375f602d416664ba19b7fc9bab42c72747463a71d0896b22f6da3', ++ '553e04f6b018b4fa6c8f39e7f311d3176290d0e0f19ca73f17714d9977a22ff8' ++ ], ++ [ ++ '9e2158f0d7c0d5f26c3791efefa79597654e7a2b2464f52b1ee6c1347769ef57', ++ '712fcdd1b9053f09003a3481fa7762e9ffd7c8ef35a38509e2fbf2629008373' ++ ], ++ [ ++ '176e26989a43c9cfeba4029c202538c28172e566e3c4fce7322857f3be327d66', ++ 'ed8cc9d04b29eb877d270b4878dc43c19aefd31f4eee09ee7b47834c1fa4b1c3' ++ ], ++ [ ++ '75d46efea3771e6e68abb89a13ad747ecf1892393dfc4f1b7004788c50374da8', ++ '9852390a99507679fd0b86fd2b39a868d7efc22151346e1a3ca4726586a6bed8' ++ ], ++ [ ++ '809a20c67d64900ffb698c4c825f6d5f2310fb0451c869345b7319f645605721', ++ '9e994980d9917e22b76b061927fa04143d096ccc54963e6a5ebfa5f3f8e286c1' ++ ], ++ [ ++ '1b38903a43f7f114ed4500b4eac7083fdefece1cf29c63528d563446f972c180', ++ '4036edc931a60ae889353f77fd53de4a2708b26b6f5da72ad3394119daf408f9' ++ ] ++ ] ++ } ++}; ++ ++},{}],17:[function(require,module,exports){ ++'use strict'; ++ ++var utils = exports; ++var BN = require('bn.js'); ++ ++utils.assert = function assert(val, msg) { ++ if (!val) ++ throw new Error(msg || 'Assertion failed'); ++}; ++ ++function toArray(msg, enc) { ++ if (Array.isArray(msg)) ++ return msg.slice(); ++ if (!msg) ++ return []; ++ var res = []; ++ if (typeof msg !== 'string') { ++ for (var i = 0; i < msg.length; i++) ++ res[i] = msg[i] | 0; ++ return res; ++ } ++ if (!enc) { ++ for (var i = 0; i < msg.length; i++) { ++ var c = msg.charCodeAt(i); ++ var hi = c >> 8; ++ var lo = c & 0xff; ++ if (hi) ++ res.push(hi, lo); ++ else ++ res.push(lo); ++ } ++ } else if (enc === 'hex') { ++ msg = msg.replace(/[^a-z0-9]+/ig, ''); ++ if (msg.length % 2 !== 0) ++ msg = '0' + msg; ++ for (var i = 0; i < msg.length; i += 2) ++ res.push(parseInt(msg[i] + msg[i + 1], 16)); ++ } ++ return res; ++} ++utils.toArray = toArray; ++ ++function zero2(word) { ++ if (word.length === 1) ++ return '0' + word; ++ else ++ return word; ++} ++utils.zero2 = zero2; ++ ++function toHex(msg) { ++ var res = ''; ++ for (var i = 0; i < msg.length; i++) ++ res += zero2(msg[i].toString(16)); ++ return res; ++} ++utils.toHex = toHex; ++ ++utils.encode = function encode(arr, enc) { ++ if (enc === 'hex') ++ return toHex(arr); ++ else ++ return arr; ++}; ++ ++// Represent num in a w-NAF form ++function getNAF(num, w) { ++ var naf = []; ++ var ws = 1 << (w + 1); ++ var k = num.clone(); ++ while (k.cmpn(1) >= 0) { ++ var z; ++ if (k.isOdd()) { ++ var mod = k.andln(ws - 1); ++ if (mod > (ws >> 1) - 1) ++ z = (ws >> 1) - mod; ++ else ++ z = mod; ++ k.isubn(z); ++ } else { ++ z = 0; ++ } ++ naf.push(z); ++ ++ // Optimization, shift by word if possible ++ var shift = (k.cmpn(0) !== 0 && k.andln(ws - 1) === 0) ? (w + 1) : 1; ++ for (var i = 1; i < shift; i++) ++ naf.push(0); ++ k.iushrn(shift); ++ } ++ ++ return naf; ++} ++utils.getNAF = getNAF; ++ ++// Represent k1, k2 in a Joint Sparse Form ++function getJSF(k1, k2) { ++ var jsf = [ ++ [], ++ [] ++ ]; ++ ++ k1 = k1.clone(); ++ k2 = k2.clone(); ++ var d1 = 0; ++ var d2 = 0; ++ while (k1.cmpn(-d1) > 0 || k2.cmpn(-d2) > 0) { ++ ++ // First phase ++ var m14 = (k1.andln(3) + d1) & 3; ++ var m24 = (k2.andln(3) + d2) & 3; ++ if (m14 === 3) ++ m14 = -1; ++ if (m24 === 3) ++ m24 = -1; ++ var u1; ++ if ((m14 & 1) === 0) { ++ u1 = 0; ++ } else { ++ var m8 = (k1.andln(7) + d1) & 7; ++ if ((m8 === 3 || m8 === 5) && m24 === 2) ++ u1 = -m14; ++ else ++ u1 = m14; ++ } ++ jsf[0].push(u1); ++ ++ var u2; ++ if ((m24 & 1) === 0) { ++ u2 = 0; ++ } else { ++ var m8 = (k2.andln(7) + d2) & 7; ++ if ((m8 === 3 || m8 === 5) && m14 === 2) ++ u2 = -m24; ++ else ++ u2 = m24; ++ } ++ jsf[1].push(u2); ++ ++ // Second phase ++ if (2 * d1 === u1 + 1) ++ d1 = 1 - d1; ++ if (2 * d2 === u2 + 1) ++ d2 = 1 - d2; ++ k1.iushrn(1); ++ k2.iushrn(1); ++ } ++ ++ return jsf; ++} ++utils.getJSF = getJSF; ++ ++function cachedProperty(obj, name, computer) { ++ var key = '_' + name; ++ obj.prototype[name] = function cachedProperty() { ++ return this[key] !== undefined ? this[key] : ++ this[key] = computer.call(this); ++ }; ++} ++utils.cachedProperty = cachedProperty; ++ ++function parseBytes(bytes) { ++ return typeof bytes === 'string' ? utils.toArray(bytes, 'hex') : ++ bytes; ++} ++utils.parseBytes = parseBytes; ++ ++function intFromLE(bytes) { ++ return new BN(bytes, 'hex', 'le'); ++} ++utils.intFromLE = intFromLE; ++ ++ ++},{"bn.js":1}],18:[function(require,module,exports){ ++var r; ++ ++module.exports = function rand(len) { ++ if (!r) ++ r = new Rand(null); ++ ++ return r.generate(len); ++}; ++ ++function Rand(rand) { ++ this.rand = rand; ++} ++module.exports.Rand = Rand; ++ ++Rand.prototype.generate = function generate(len) { ++ return this._rand(len); ++}; ++ ++if (typeof window === 'object') { ++ if (window.crypto && window.crypto.getRandomValues) { ++ // Modern browsers ++ Rand.prototype._rand = function _rand(n) { ++ var arr = new Uint8Array(n); ++ window.crypto.getRandomValues(arr); ++ return arr; ++ }; ++ } else if (window.msCrypto && window.msCrypto.getRandomValues) { ++ // IE ++ Rand.prototype._rand = function _rand(n) { ++ var arr = new Uint8Array(n); ++ window.msCrypto.getRandomValues(arr); ++ return arr; ++ }; ++ } else { ++ // Old junk ++ Rand.prototype._rand = function() { ++ throw new Error('Not implemented yet'); ++ }; ++ } ++} else { ++ // Node.js or Web worker ++ try { ++ var crypto = require('cry' + 'pto'); ++ ++ Rand.prototype._rand = function _rand(n) { ++ return crypto.randomBytes(n); ++ }; ++ } catch (e) { ++ // Emulate crypto API using randy ++ Rand.prototype._rand = function _rand(n) { ++ var res = new Uint8Array(n); ++ for (var i = 0; i < res.length; i++) ++ res[i] = this.rand.getByte(); ++ return res; ++ }; ++ } ++} ++ ++},{}],19:[function(require,module,exports){ ++var hash = exports; ++ ++hash.utils = require('./hash/utils'); ++hash.common = require('./hash/common'); ++hash.sha = require('./hash/sha'); ++hash.ripemd = require('./hash/ripemd'); ++hash.hmac = require('./hash/hmac'); ++ ++// Proxy hash functions to the main object ++hash.sha1 = hash.sha.sha1; ++hash.sha256 = hash.sha.sha256; ++hash.sha224 = hash.sha.sha224; ++hash.sha384 = hash.sha.sha384; ++hash.sha512 = hash.sha.sha512; ++hash.ripemd160 = hash.ripemd.ripemd160; ++ ++},{"./hash/common":20,"./hash/hmac":21,"./hash/ripemd":22,"./hash/sha":23,"./hash/utils":24}],20:[function(require,module,exports){ ++var hash = require('../hash'); ++var utils = hash.utils; ++var assert = utils.assert; ++ ++function BlockHash() { ++ this.pending = null; ++ this.pendingTotal = 0; ++ this.blockSize = this.constructor.blockSize; ++ this.outSize = this.constructor.outSize; ++ this.hmacStrength = this.constructor.hmacStrength; ++ this.padLength = this.constructor.padLength / 8; ++ this.endian = 'big'; ++ ++ this._delta8 = this.blockSize / 8; ++ this._delta32 = this.blockSize / 32; ++} ++exports.BlockHash = BlockHash; ++ ++BlockHash.prototype.update = function update(msg, enc) { ++ // Convert message to array, pad it, and join into 32bit blocks ++ msg = utils.toArray(msg, enc); ++ if (!this.pending) ++ this.pending = msg; ++ else ++ this.pending = this.pending.concat(msg); ++ this.pendingTotal += msg.length; ++ ++ // Enough data, try updating ++ if (this.pending.length >= this._delta8) { ++ msg = this.pending; ++ ++ // Process pending data in blocks ++ var r = msg.length % this._delta8; ++ this.pending = msg.slice(msg.length - r, msg.length); ++ if (this.pending.length === 0) ++ this.pending = null; ++ ++ msg = utils.join32(msg, 0, msg.length - r, this.endian); ++ for (var i = 0; i < msg.length; i += this._delta32) ++ this._update(msg, i, i + this._delta32); ++ } ++ ++ return this; ++}; ++ ++BlockHash.prototype.digest = function digest(enc) { ++ this.update(this._pad()); ++ assert(this.pending === null); ++ ++ return this._digest(enc); ++}; ++ ++BlockHash.prototype._pad = function pad() { ++ var len = this.pendingTotal; ++ var bytes = this._delta8; ++ var k = bytes - ((len + this.padLength) % bytes); ++ var res = new Array(k + this.padLength); ++ res[0] = 0x80; ++ for (var i = 1; i < k; i++) ++ res[i] = 0; ++ ++ // Append length ++ len <<= 3; ++ if (this.endian === 'big') { ++ for (var t = 8; t < this.padLength; t++) ++ res[i++] = 0; ++ ++ res[i++] = 0; ++ res[i++] = 0; ++ res[i++] = 0; ++ res[i++] = 0; ++ res[i++] = (len >>> 24) & 0xff; ++ res[i++] = (len >>> 16) & 0xff; ++ res[i++] = (len >>> 8) & 0xff; ++ res[i++] = len & 0xff; ++ } else { ++ res[i++] = len & 0xff; ++ res[i++] = (len >>> 8) & 0xff; ++ res[i++] = (len >>> 16) & 0xff; ++ res[i++] = (len >>> 24) & 0xff; ++ res[i++] = 0; ++ res[i++] = 0; ++ res[i++] = 0; ++ res[i++] = 0; ++ ++ for (var t = 8; t < this.padLength; t++) ++ res[i++] = 0; ++ } ++ ++ return res; ++}; ++ ++},{"../hash":19}],21:[function(require,module,exports){ ++var hmac = exports; ++ ++var hash = require('../hash'); ++var utils = hash.utils; ++var assert = utils.assert; ++ ++function Hmac(hash, key, enc) { ++ if (!(this instanceof Hmac)) ++ return new Hmac(hash, key, enc); ++ this.Hash = hash; ++ this.blockSize = hash.blockSize / 8; ++ this.outSize = hash.outSize / 8; ++ this.inner = null; ++ this.outer = null; ++ ++ this._init(utils.toArray(key, enc)); ++} ++module.exports = Hmac; ++ ++Hmac.prototype._init = function init(key) { ++ // Shorten key, if needed ++ if (key.length > this.blockSize) ++ key = new this.Hash().update(key).digest(); ++ assert(key.length <= this.blockSize); ++ ++ // Add padding to key ++ for (var i = key.length; i < this.blockSize; i++) ++ key.push(0); ++ ++ for (var i = 0; i < key.length; i++) ++ key[i] ^= 0x36; ++ this.inner = new this.Hash().update(key); ++ ++ // 0x36 ^ 0x5c = 0x6a ++ for (var i = 0; i < key.length; i++) ++ key[i] ^= 0x6a; ++ this.outer = new this.Hash().update(key); ++}; ++ ++Hmac.prototype.update = function update(msg, enc) { ++ this.inner.update(msg, enc); ++ return this; ++}; ++ ++Hmac.prototype.digest = function digest(enc) { ++ this.outer.update(this.inner.digest()); ++ return this.outer.digest(enc); ++}; ++ ++},{"../hash":19}],22:[function(require,module,exports){ ++var hash = require('../hash'); ++var utils = hash.utils; ++ ++var rotl32 = utils.rotl32; ++var sum32 = utils.sum32; ++var sum32_3 = utils.sum32_3; ++var sum32_4 = utils.sum32_4; ++var BlockHash = hash.common.BlockHash; ++ ++function RIPEMD160() { ++ if (!(this instanceof RIPEMD160)) ++ return new RIPEMD160(); ++ ++ BlockHash.call(this); ++ ++ this.h = [ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 ]; ++ this.endian = 'little'; ++} ++utils.inherits(RIPEMD160, BlockHash); ++exports.ripemd160 = RIPEMD160; ++ ++RIPEMD160.blockSize = 512; ++RIPEMD160.outSize = 160; ++RIPEMD160.hmacStrength = 192; ++RIPEMD160.padLength = 64; ++ ++RIPEMD160.prototype._update = function update(msg, start) { ++ var A = this.h[0]; ++ var B = this.h[1]; ++ var C = this.h[2]; ++ var D = this.h[3]; ++ var E = this.h[4]; ++ var Ah = A; ++ var Bh = B; ++ var Ch = C; ++ var Dh = D; ++ var Eh = E; ++ for (var j = 0; j < 80; j++) { ++ var T = sum32( ++ rotl32( ++ sum32_4(A, f(j, B, C, D), msg[r[j] + start], K(j)), ++ s[j]), ++ E); ++ A = E; ++ E = D; ++ D = rotl32(C, 10); ++ C = B; ++ B = T; ++ T = sum32( ++ rotl32( ++ sum32_4(Ah, f(79 - j, Bh, Ch, Dh), msg[rh[j] + start], Kh(j)), ++ sh[j]), ++ Eh); ++ Ah = Eh; ++ Eh = Dh; ++ Dh = rotl32(Ch, 10); ++ Ch = Bh; ++ Bh = T; ++ } ++ T = sum32_3(this.h[1], C, Dh); ++ this.h[1] = sum32_3(this.h[2], D, Eh); ++ this.h[2] = sum32_3(this.h[3], E, Ah); ++ this.h[3] = sum32_3(this.h[4], A, Bh); ++ this.h[4] = sum32_3(this.h[0], B, Ch); ++ this.h[0] = T; ++}; ++ ++RIPEMD160.prototype._digest = function digest(enc) { ++ if (enc === 'hex') ++ return utils.toHex32(this.h, 'little'); ++ else ++ return utils.split32(this.h, 'little'); ++}; ++ ++function f(j, x, y, z) { ++ if (j <= 15) ++ return x ^ y ^ z; ++ else if (j <= 31) ++ return (x & y) | ((~x) & z); ++ else if (j <= 47) ++ return (x | (~y)) ^ z; ++ else if (j <= 63) ++ return (x & z) | (y & (~z)); ++ else ++ return x ^ (y | (~z)); ++} ++ ++function K(j) { ++ if (j <= 15) ++ return 0x00000000; ++ else if (j <= 31) ++ return 0x5a827999; ++ else if (j <= 47) ++ return 0x6ed9eba1; ++ else if (j <= 63) ++ return 0x8f1bbcdc; ++ else ++ return 0xa953fd4e; ++} ++ ++function Kh(j) { ++ if (j <= 15) ++ return 0x50a28be6; ++ else if (j <= 31) ++ return 0x5c4dd124; ++ else if (j <= 47) ++ return 0x6d703ef3; ++ else if (j <= 63) ++ return 0x7a6d76e9; ++ else ++ return 0x00000000; ++} ++ ++var r = [ ++ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, ++ 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, ++ 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, ++ 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, ++ 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13 ++]; ++ ++var rh = [ ++ 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, ++ 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, ++ 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, ++ 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, ++ 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11 ++]; ++ ++var s = [ ++ 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, ++ 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, ++ 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, ++ 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, ++ 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 ++]; ++ ++var sh = [ ++ 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, ++ 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, ++ 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, ++ 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, ++ 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 ++]; ++ ++},{"../hash":19}],23:[function(require,module,exports){ ++var hash = require('../hash'); ++var utils = hash.utils; ++var assert = utils.assert; ++ ++var rotr32 = utils.rotr32; ++var rotl32 = utils.rotl32; ++var sum32 = utils.sum32; ++var sum32_4 = utils.sum32_4; ++var sum32_5 = utils.sum32_5; ++var rotr64_hi = utils.rotr64_hi; ++var rotr64_lo = utils.rotr64_lo; ++var shr64_hi = utils.shr64_hi; ++var shr64_lo = utils.shr64_lo; ++var sum64 = utils.sum64; ++var sum64_hi = utils.sum64_hi; ++var sum64_lo = utils.sum64_lo; ++var sum64_4_hi = utils.sum64_4_hi; ++var sum64_4_lo = utils.sum64_4_lo; ++var sum64_5_hi = utils.sum64_5_hi; ++var sum64_5_lo = utils.sum64_5_lo; ++var BlockHash = hash.common.BlockHash; ++ ++var sha256_K = [ ++ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, ++ 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, ++ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, ++ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, ++ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, ++ 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, ++ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, ++ 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, ++ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, ++ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, ++ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, ++ 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, ++ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, ++ 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, ++ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, ++ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 ++]; ++ ++var sha512_K = [ ++ 0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd, ++ 0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc, ++ 0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019, ++ 0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118, ++ 0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe, ++ 0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2, ++ 0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1, ++ 0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694, ++ 0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3, ++ 0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65, ++ 0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483, ++ 0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5, ++ 0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210, ++ 0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4, ++ 0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725, ++ 0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70, ++ 0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926, ++ 0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df, ++ 0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8, ++ 0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b, ++ 0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001, ++ 0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30, ++ 0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910, ++ 0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8, ++ 0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53, ++ 0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8, ++ 0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb, ++ 0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3, ++ 0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60, ++ 0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec, ++ 0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9, ++ 0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b, ++ 0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207, ++ 0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178, ++ 0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6, ++ 0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b, ++ 0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493, ++ 0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c, ++ 0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a, ++ 0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817 ++]; ++ ++var sha1_K = [ ++ 0x5A827999, 0x6ED9EBA1, ++ 0x8F1BBCDC, 0xCA62C1D6 ++]; ++ ++function SHA256() { ++ if (!(this instanceof SHA256)) ++ return new SHA256(); ++ ++ BlockHash.call(this); ++ this.h = [ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, ++ 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 ]; ++ this.k = sha256_K; ++ this.W = new Array(64); ++} ++utils.inherits(SHA256, BlockHash); ++exports.sha256 = SHA256; ++ ++SHA256.blockSize = 512; ++SHA256.outSize = 256; ++SHA256.hmacStrength = 192; ++SHA256.padLength = 64; ++ ++SHA256.prototype._update = function _update(msg, start) { ++ var W = this.W; ++ ++ for (var i = 0; i < 16; i++) ++ W[i] = msg[start + i]; ++ for (; i < W.length; i++) ++ W[i] = sum32_4(g1_256(W[i - 2]), W[i - 7], g0_256(W[i - 15]), W[i - 16]); ++ ++ var a = this.h[0]; ++ var b = this.h[1]; ++ var c = this.h[2]; ++ var d = this.h[3]; ++ var e = this.h[4]; ++ var f = this.h[5]; ++ var g = this.h[6]; ++ var h = this.h[7]; ++ ++ assert(this.k.length === W.length); ++ for (var i = 0; i < W.length; i++) { ++ var T1 = sum32_5(h, s1_256(e), ch32(e, f, g), this.k[i], W[i]); ++ var T2 = sum32(s0_256(a), maj32(a, b, c)); ++ h = g; ++ g = f; ++ f = e; ++ e = sum32(d, T1); ++ d = c; ++ c = b; ++ b = a; ++ a = sum32(T1, T2); ++ } ++ ++ this.h[0] = sum32(this.h[0], a); ++ this.h[1] = sum32(this.h[1], b); ++ this.h[2] = sum32(this.h[2], c); ++ this.h[3] = sum32(this.h[3], d); ++ this.h[4] = sum32(this.h[4], e); ++ this.h[5] = sum32(this.h[5], f); ++ this.h[6] = sum32(this.h[6], g); ++ this.h[7] = sum32(this.h[7], h); ++}; ++ ++SHA256.prototype._digest = function digest(enc) { ++ if (enc === 'hex') ++ return utils.toHex32(this.h, 'big'); ++ else ++ return utils.split32(this.h, 'big'); ++}; ++ ++function SHA224() { ++ if (!(this instanceof SHA224)) ++ return new SHA224(); ++ ++ SHA256.call(this); ++ this.h = [ 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, ++ 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 ]; ++} ++utils.inherits(SHA224, SHA256); ++exports.sha224 = SHA224; ++ ++SHA224.blockSize = 512; ++SHA224.outSize = 224; ++SHA224.hmacStrength = 192; ++SHA224.padLength = 64; ++ ++SHA224.prototype._digest = function digest(enc) { ++ // Just truncate output ++ if (enc === 'hex') ++ return utils.toHex32(this.h.slice(0, 7), 'big'); ++ else ++ return utils.split32(this.h.slice(0, 7), 'big'); ++}; ++ ++function SHA512() { ++ if (!(this instanceof SHA512)) ++ return new SHA512(); ++ ++ BlockHash.call(this); ++ this.h = [ 0x6a09e667, 0xf3bcc908, ++ 0xbb67ae85, 0x84caa73b, ++ 0x3c6ef372, 0xfe94f82b, ++ 0xa54ff53a, 0x5f1d36f1, ++ 0x510e527f, 0xade682d1, ++ 0x9b05688c, 0x2b3e6c1f, ++ 0x1f83d9ab, 0xfb41bd6b, ++ 0x5be0cd19, 0x137e2179 ]; ++ this.k = sha512_K; ++ this.W = new Array(160); ++} ++utils.inherits(SHA512, BlockHash); ++exports.sha512 = SHA512; ++ ++SHA512.blockSize = 1024; ++SHA512.outSize = 512; ++SHA512.hmacStrength = 192; ++SHA512.padLength = 128; ++ ++SHA512.prototype._prepareBlock = function _prepareBlock(msg, start) { ++ var W = this.W; ++ ++ // 32 x 32bit words ++ for (var i = 0; i < 32; i++) ++ W[i] = msg[start + i]; ++ for (; i < W.length; i += 2) { ++ var c0_hi = g1_512_hi(W[i - 4], W[i - 3]); // i - 2 ++ var c0_lo = g1_512_lo(W[i - 4], W[i - 3]); ++ var c1_hi = W[i - 14]; // i - 7 ++ var c1_lo = W[i - 13]; ++ var c2_hi = g0_512_hi(W[i - 30], W[i - 29]); // i - 15 ++ var c2_lo = g0_512_lo(W[i - 30], W[i - 29]); ++ var c3_hi = W[i - 32]; // i - 16 ++ var c3_lo = W[i - 31]; ++ ++ W[i] = sum64_4_hi(c0_hi, c0_lo, ++ c1_hi, c1_lo, ++ c2_hi, c2_lo, ++ c3_hi, c3_lo); ++ W[i + 1] = sum64_4_lo(c0_hi, c0_lo, ++ c1_hi, c1_lo, ++ c2_hi, c2_lo, ++ c3_hi, c3_lo); ++ } ++}; ++ ++SHA512.prototype._update = function _update(msg, start) { ++ this._prepareBlock(msg, start); ++ ++ var W = this.W; ++ ++ var ah = this.h[0]; ++ var al = this.h[1]; ++ var bh = this.h[2]; ++ var bl = this.h[3]; ++ var ch = this.h[4]; ++ var cl = this.h[5]; ++ var dh = this.h[6]; ++ var dl = this.h[7]; ++ var eh = this.h[8]; ++ var el = this.h[9]; ++ var fh = this.h[10]; ++ var fl = this.h[11]; ++ var gh = this.h[12]; ++ var gl = this.h[13]; ++ var hh = this.h[14]; ++ var hl = this.h[15]; ++ ++ assert(this.k.length === W.length); ++ for (var i = 0; i < W.length; i += 2) { ++ var c0_hi = hh; ++ var c0_lo = hl; ++ var c1_hi = s1_512_hi(eh, el); ++ var c1_lo = s1_512_lo(eh, el); ++ var c2_hi = ch64_hi(eh, el, fh, fl, gh, gl); ++ var c2_lo = ch64_lo(eh, el, fh, fl, gh, gl); ++ var c3_hi = this.k[i]; ++ var c3_lo = this.k[i + 1]; ++ var c4_hi = W[i]; ++ var c4_lo = W[i + 1]; ++ ++ var T1_hi = sum64_5_hi(c0_hi, c0_lo, ++ c1_hi, c1_lo, ++ c2_hi, c2_lo, ++ c3_hi, c3_lo, ++ c4_hi, c4_lo); ++ var T1_lo = sum64_5_lo(c0_hi, c0_lo, ++ c1_hi, c1_lo, ++ c2_hi, c2_lo, ++ c3_hi, c3_lo, ++ c4_hi, c4_lo); ++ ++ var c0_hi = s0_512_hi(ah, al); ++ var c0_lo = s0_512_lo(ah, al); ++ var c1_hi = maj64_hi(ah, al, bh, bl, ch, cl); ++ var c1_lo = maj64_lo(ah, al, bh, bl, ch, cl); ++ ++ var T2_hi = sum64_hi(c0_hi, c0_lo, c1_hi, c1_lo); ++ var T2_lo = sum64_lo(c0_hi, c0_lo, c1_hi, c1_lo); ++ ++ hh = gh; ++ hl = gl; ++ ++ gh = fh; ++ gl = fl; ++ ++ fh = eh; ++ fl = el; ++ ++ eh = sum64_hi(dh, dl, T1_hi, T1_lo); ++ el = sum64_lo(dl, dl, T1_hi, T1_lo); ++ ++ dh = ch; ++ dl = cl; ++ ++ ch = bh; ++ cl = bl; ++ ++ bh = ah; ++ bl = al; ++ ++ ah = sum64_hi(T1_hi, T1_lo, T2_hi, T2_lo); ++ al = sum64_lo(T1_hi, T1_lo, T2_hi, T2_lo); ++ } ++ ++ sum64(this.h, 0, ah, al); ++ sum64(this.h, 2, bh, bl); ++ sum64(this.h, 4, ch, cl); ++ sum64(this.h, 6, dh, dl); ++ sum64(this.h, 8, eh, el); ++ sum64(this.h, 10, fh, fl); ++ sum64(this.h, 12, gh, gl); ++ sum64(this.h, 14, hh, hl); ++}; ++ ++SHA512.prototype._digest = function digest(enc) { ++ if (enc === 'hex') ++ return utils.toHex32(this.h, 'big'); ++ else ++ return utils.split32(this.h, 'big'); ++}; ++ ++function SHA384() { ++ if (!(this instanceof SHA384)) ++ return new SHA384(); ++ ++ SHA512.call(this); ++ this.h = [ 0xcbbb9d5d, 0xc1059ed8, ++ 0x629a292a, 0x367cd507, ++ 0x9159015a, 0x3070dd17, ++ 0x152fecd8, 0xf70e5939, ++ 0x67332667, 0xffc00b31, ++ 0x8eb44a87, 0x68581511, ++ 0xdb0c2e0d, 0x64f98fa7, ++ 0x47b5481d, 0xbefa4fa4 ]; ++} ++utils.inherits(SHA384, SHA512); ++exports.sha384 = SHA384; ++ ++SHA384.blockSize = 1024; ++SHA384.outSize = 384; ++SHA384.hmacStrength = 192; ++SHA384.padLength = 128; ++ ++SHA384.prototype._digest = function digest(enc) { ++ if (enc === 'hex') ++ return utils.toHex32(this.h.slice(0, 12), 'big'); ++ else ++ return utils.split32(this.h.slice(0, 12), 'big'); ++}; ++ ++function SHA1() { ++ if (!(this instanceof SHA1)) ++ return new SHA1(); ++ ++ BlockHash.call(this); ++ this.h = [ 0x67452301, 0xefcdab89, 0x98badcfe, ++ 0x10325476, 0xc3d2e1f0 ]; ++ this.W = new Array(80); ++} ++ ++utils.inherits(SHA1, BlockHash); ++exports.sha1 = SHA1; ++ ++SHA1.blockSize = 512; ++SHA1.outSize = 160; ++SHA1.hmacStrength = 80; ++SHA1.padLength = 64; ++ ++SHA1.prototype._update = function _update(msg, start) { ++ var W = this.W; ++ ++ for (var i = 0; i < 16; i++) ++ W[i] = msg[start + i]; ++ ++ for(; i < W.length; i++) ++ W[i] = rotl32(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1); ++ ++ var a = this.h[0]; ++ var b = this.h[1]; ++ var c = this.h[2]; ++ var d = this.h[3]; ++ var e = this.h[4]; ++ ++ for (var i = 0; i < W.length; i++) { ++ var s = ~~(i / 20); ++ var t = sum32_5(rotl32(a, 5), ft_1(s, b, c, d), e, W[i], sha1_K[s]); ++ e = d; ++ d = c; ++ c = rotl32(b, 30); ++ b = a; ++ a = t; ++ } ++ ++ this.h[0] = sum32(this.h[0], a); ++ this.h[1] = sum32(this.h[1], b); ++ this.h[2] = sum32(this.h[2], c); ++ this.h[3] = sum32(this.h[3], d); ++ this.h[4] = sum32(this.h[4], e); ++}; ++ ++SHA1.prototype._digest = function digest(enc) { ++ if (enc === 'hex') ++ return utils.toHex32(this.h, 'big'); ++ else ++ return utils.split32(this.h, 'big'); ++}; ++ ++function ch32(x, y, z) { ++ return (x & y) ^ ((~x) & z); ++} ++ ++function maj32(x, y, z) { ++ return (x & y) ^ (x & z) ^ (y & z); ++} ++ ++function p32(x, y, z) { ++ return x ^ y ^ z; ++} ++ ++function s0_256(x) { ++ return rotr32(x, 2) ^ rotr32(x, 13) ^ rotr32(x, 22); ++} ++ ++function s1_256(x) { ++ return rotr32(x, 6) ^ rotr32(x, 11) ^ rotr32(x, 25); ++} ++ ++function g0_256(x) { ++ return rotr32(x, 7) ^ rotr32(x, 18) ^ (x >>> 3); ++} ++ ++function g1_256(x) { ++ return rotr32(x, 17) ^ rotr32(x, 19) ^ (x >>> 10); ++} ++ ++function ft_1(s, x, y, z) { ++ if (s === 0) ++ return ch32(x, y, z); ++ if (s === 1 || s === 3) ++ return p32(x, y, z); ++ if (s === 2) ++ return maj32(x, y, z); ++} ++ ++function ch64_hi(xh, xl, yh, yl, zh, zl) { ++ var r = (xh & yh) ^ ((~xh) & zh); ++ if (r < 0) ++ r += 0x100000000; ++ return r; ++} ++ ++function ch64_lo(xh, xl, yh, yl, zh, zl) { ++ var r = (xl & yl) ^ ((~xl) & zl); ++ if (r < 0) ++ r += 0x100000000; ++ return r; ++} ++ ++function maj64_hi(xh, xl, yh, yl, zh, zl) { ++ var r = (xh & yh) ^ (xh & zh) ^ (yh & zh); ++ if (r < 0) ++ r += 0x100000000; ++ return r; ++} ++ ++function maj64_lo(xh, xl, yh, yl, zh, zl) { ++ var r = (xl & yl) ^ (xl & zl) ^ (yl & zl); ++ if (r < 0) ++ r += 0x100000000; ++ return r; ++} ++ ++function s0_512_hi(xh, xl) { ++ var c0_hi = rotr64_hi(xh, xl, 28); ++ var c1_hi = rotr64_hi(xl, xh, 2); // 34 ++ var c2_hi = rotr64_hi(xl, xh, 7); // 39 ++ ++ var r = c0_hi ^ c1_hi ^ c2_hi; ++ if (r < 0) ++ r += 0x100000000; ++ return r; ++} ++ ++function s0_512_lo(xh, xl) { ++ var c0_lo = rotr64_lo(xh, xl, 28); ++ var c1_lo = rotr64_lo(xl, xh, 2); // 34 ++ var c2_lo = rotr64_lo(xl, xh, 7); // 39 ++ ++ var r = c0_lo ^ c1_lo ^ c2_lo; ++ if (r < 0) ++ r += 0x100000000; ++ return r; ++} ++ ++function s1_512_hi(xh, xl) { ++ var c0_hi = rotr64_hi(xh, xl, 14); ++ var c1_hi = rotr64_hi(xh, xl, 18); ++ var c2_hi = rotr64_hi(xl, xh, 9); // 41 ++ ++ var r = c0_hi ^ c1_hi ^ c2_hi; ++ if (r < 0) ++ r += 0x100000000; ++ return r; ++} ++ ++function s1_512_lo(xh, xl) { ++ var c0_lo = rotr64_lo(xh, xl, 14); ++ var c1_lo = rotr64_lo(xh, xl, 18); ++ var c2_lo = rotr64_lo(xl, xh, 9); // 41 ++ ++ var r = c0_lo ^ c1_lo ^ c2_lo; ++ if (r < 0) ++ r += 0x100000000; ++ return r; ++} ++ ++function g0_512_hi(xh, xl) { ++ var c0_hi = rotr64_hi(xh, xl, 1); ++ var c1_hi = rotr64_hi(xh, xl, 8); ++ var c2_hi = shr64_hi(xh, xl, 7); ++ ++ var r = c0_hi ^ c1_hi ^ c2_hi; ++ if (r < 0) ++ r += 0x100000000; ++ return r; ++} ++ ++function g0_512_lo(xh, xl) { ++ var c0_lo = rotr64_lo(xh, xl, 1); ++ var c1_lo = rotr64_lo(xh, xl, 8); ++ var c2_lo = shr64_lo(xh, xl, 7); ++ ++ var r = c0_lo ^ c1_lo ^ c2_lo; ++ if (r < 0) ++ r += 0x100000000; ++ return r; ++} ++ ++function g1_512_hi(xh, xl) { ++ var c0_hi = rotr64_hi(xh, xl, 19); ++ var c1_hi = rotr64_hi(xl, xh, 29); // 61 ++ var c2_hi = shr64_hi(xh, xl, 6); ++ ++ var r = c0_hi ^ c1_hi ^ c2_hi; ++ if (r < 0) ++ r += 0x100000000; ++ return r; ++} ++ ++function g1_512_lo(xh, xl) { ++ var c0_lo = rotr64_lo(xh, xl, 19); ++ var c1_lo = rotr64_lo(xl, xh, 29); // 61 ++ var c2_lo = shr64_lo(xh, xl, 6); ++ ++ var r = c0_lo ^ c1_lo ^ c2_lo; ++ if (r < 0) ++ r += 0x100000000; ++ return r; ++} ++ ++},{"../hash":19}],24:[function(require,module,exports){ ++var utils = exports; ++var inherits = require('inherits'); ++ ++function toArray(msg, enc) { ++ if (Array.isArray(msg)) ++ return msg.slice(); ++ if (!msg) ++ return []; ++ var res = []; ++ if (typeof msg === 'string') { ++ if (!enc) { ++ for (var i = 0; i < msg.length; i++) { ++ var c = msg.charCodeAt(i); ++ var hi = c >> 8; ++ var lo = c & 0xff; ++ if (hi) ++ res.push(hi, lo); ++ else ++ res.push(lo); ++ } ++ } else if (enc === 'hex') { ++ msg = msg.replace(/[^a-z0-9]+/ig, ''); ++ if (msg.length % 2 !== 0) ++ msg = '0' + msg; ++ for (var i = 0; i < msg.length; i += 2) ++ res.push(parseInt(msg[i] + msg[i + 1], 16)); ++ } ++ } else { ++ for (var i = 0; i < msg.length; i++) ++ res[i] = msg[i] | 0; ++ } ++ return res; ++} ++utils.toArray = toArray; ++ ++function toHex(msg) { ++ var res = ''; ++ for (var i = 0; i < msg.length; i++) ++ res += zero2(msg[i].toString(16)); ++ return res; ++} ++utils.toHex = toHex; ++ ++function htonl(w) { ++ var res = (w >>> 24) | ++ ((w >>> 8) & 0xff00) | ++ ((w << 8) & 0xff0000) | ++ ((w & 0xff) << 24); ++ return res >>> 0; ++} ++utils.htonl = htonl; ++ ++function toHex32(msg, endian) { ++ var res = ''; ++ for (var i = 0; i < msg.length; i++) { ++ var w = msg[i]; ++ if (endian === 'little') ++ w = htonl(w); ++ res += zero8(w.toString(16)); ++ } ++ return res; ++} ++utils.toHex32 = toHex32; ++ ++function zero2(word) { ++ if (word.length === 1) ++ return '0' + word; ++ else ++ return word; ++} ++utils.zero2 = zero2; ++ ++function zero8(word) { ++ if (word.length === 7) ++ return '0' + word; ++ else if (word.length === 6) ++ return '00' + word; ++ else if (word.length === 5) ++ return '000' + word; ++ else if (word.length === 4) ++ return '0000' + word; ++ else if (word.length === 3) ++ return '00000' + word; ++ else if (word.length === 2) ++ return '000000' + word; ++ else if (word.length === 1) ++ return '0000000' + word; ++ else ++ return word; ++} ++utils.zero8 = zero8; ++ ++function join32(msg, start, end, endian) { ++ var len = end - start; ++ assert(len % 4 === 0); ++ var res = new Array(len / 4); ++ for (var i = 0, k = start; i < res.length; i++, k += 4) { ++ var w; ++ if (endian === 'big') ++ w = (msg[k] << 24) | (msg[k + 1] << 16) | (msg[k + 2] << 8) | msg[k + 3]; ++ else ++ w = (msg[k + 3] << 24) | (msg[k + 2] << 16) | (msg[k + 1] << 8) | msg[k]; ++ res[i] = w >>> 0; ++ } ++ return res; ++} ++utils.join32 = join32; ++ ++function split32(msg, endian) { ++ var res = new Array(msg.length * 4); ++ for (var i = 0, k = 0; i < msg.length; i++, k += 4) { ++ var m = msg[i]; ++ if (endian === 'big') { ++ res[k] = m >>> 24; ++ res[k + 1] = (m >>> 16) & 0xff; ++ res[k + 2] = (m >>> 8) & 0xff; ++ res[k + 3] = m & 0xff; ++ } else { ++ res[k + 3] = m >>> 24; ++ res[k + 2] = (m >>> 16) & 0xff; ++ res[k + 1] = (m >>> 8) & 0xff; ++ res[k] = m & 0xff; ++ } ++ } ++ return res; ++} ++utils.split32 = split32; ++ ++function rotr32(w, b) { ++ return (w >>> b) | (w << (32 - b)); ++} ++utils.rotr32 = rotr32; ++ ++function rotl32(w, b) { ++ return (w << b) | (w >>> (32 - b)); ++} ++utils.rotl32 = rotl32; ++ ++function sum32(a, b) { ++ return (a + b) >>> 0; ++} ++utils.sum32 = sum32; ++ ++function sum32_3(a, b, c) { ++ return (a + b + c) >>> 0; ++} ++utils.sum32_3 = sum32_3; ++ ++function sum32_4(a, b, c, d) { ++ return (a + b + c + d) >>> 0; ++} ++utils.sum32_4 = sum32_4; ++ ++function sum32_5(a, b, c, d, e) { ++ return (a + b + c + d + e) >>> 0; ++} ++utils.sum32_5 = sum32_5; ++ ++function assert(cond, msg) { ++ if (!cond) ++ throw new Error(msg || 'Assertion failed'); ++} ++utils.assert = assert; ++ ++utils.inherits = inherits; ++ ++function sum64(buf, pos, ah, al) { ++ var bh = buf[pos]; ++ var bl = buf[pos + 1]; ++ ++ var lo = (al + bl) >>> 0; ++ var hi = (lo < al ? 1 : 0) + ah + bh; ++ buf[pos] = hi >>> 0; ++ buf[pos + 1] = lo; ++} ++exports.sum64 = sum64; ++ ++function sum64_hi(ah, al, bh, bl) { ++ var lo = (al + bl) >>> 0; ++ var hi = (lo < al ? 1 : 0) + ah + bh; ++ return hi >>> 0; ++}; ++exports.sum64_hi = sum64_hi; ++ ++function sum64_lo(ah, al, bh, bl) { ++ var lo = al + bl; ++ return lo >>> 0; ++}; ++exports.sum64_lo = sum64_lo; ++ ++function sum64_4_hi(ah, al, bh, bl, ch, cl, dh, dl) { ++ var carry = 0; ++ var lo = al; ++ lo = (lo + bl) >>> 0; ++ carry += lo < al ? 1 : 0; ++ lo = (lo + cl) >>> 0; ++ carry += lo < cl ? 1 : 0; ++ lo = (lo + dl) >>> 0; ++ carry += lo < dl ? 1 : 0; ++ ++ var hi = ah + bh + ch + dh + carry; ++ return hi >>> 0; ++}; ++exports.sum64_4_hi = sum64_4_hi; ++ ++function sum64_4_lo(ah, al, bh, bl, ch, cl, dh, dl) { ++ var lo = al + bl + cl + dl; ++ return lo >>> 0; ++}; ++exports.sum64_4_lo = sum64_4_lo; ++ ++function sum64_5_hi(ah, al, bh, bl, ch, cl, dh, dl, eh, el) { ++ var carry = 0; ++ var lo = al; ++ lo = (lo + bl) >>> 0; ++ carry += lo < al ? 1 : 0; ++ lo = (lo + cl) >>> 0; ++ carry += lo < cl ? 1 : 0; ++ lo = (lo + dl) >>> 0; ++ carry += lo < dl ? 1 : 0; ++ lo = (lo + el) >>> 0; ++ carry += lo < el ? 1 : 0; ++ ++ var hi = ah + bh + ch + dh + eh + carry; ++ return hi >>> 0; ++}; ++exports.sum64_5_hi = sum64_5_hi; ++ ++function sum64_5_lo(ah, al, bh, bl, ch, cl, dh, dl, eh, el) { ++ var lo = al + bl + cl + dl + el; ++ ++ return lo >>> 0; ++}; ++exports.sum64_5_lo = sum64_5_lo; ++ ++function rotr64_hi(ah, al, num) { ++ var r = (al << (32 - num)) | (ah >>> num); ++ return r >>> 0; ++}; ++exports.rotr64_hi = rotr64_hi; ++ ++function rotr64_lo(ah, al, num) { ++ var r = (ah << (32 - num)) | (al >>> num); ++ return r >>> 0; ++}; ++exports.rotr64_lo = rotr64_lo; ++ ++function shr64_hi(ah, al, num) { ++ return ah >>> num; ++}; ++exports.shr64_hi = shr64_hi; ++ ++function shr64_lo(ah, al, num) { ++ var r = (ah << (32 - num)) | (al >>> num); ++ return r >>> 0; ++}; ++exports.shr64_lo = shr64_lo; ++ ++},{"inherits":25}],25:[function(require,module,exports){ ++if (typeof Object.create === 'function') { ++ // implementation from standard node.js 'util' module ++ module.exports = function inherits(ctor, superCtor) { ++ ctor.super_ = superCtor ++ ctor.prototype = Object.create(superCtor.prototype, { ++ constructor: { ++ value: ctor, ++ enumerable: false, ++ writable: true, ++ configurable: true ++ } ++ }); ++ }; ++} else { ++ // old school shim for old browsers ++ module.exports = function inherits(ctor, superCtor) { ++ ctor.super_ = superCtor ++ var TempCtor = function () {} ++ TempCtor.prototype = superCtor.prototype ++ ctor.prototype = new TempCtor() ++ ctor.prototype.constructor = ctor ++ } ++} ++ ++},{}],26:[function(require,module,exports){ ++module.exports={ ++ "name": "elliptic", ++ "version": "6.3.2", ++ "description": "EC cryptography", ++ "main": "lib/elliptic.js", ++ "files": [ ++ "lib" ++ ], ++ "scripts": { ++ "jscs": "jscs benchmarks/*.js lib/*.js lib/**/*.js lib/**/**/*.js test/index.js", ++ "jshint": "jscs benchmarks/*.js lib/*.js lib/**/*.js lib/**/**/*.js test/index.js", ++ "lint": "npm run jscs && npm run jshint", ++ "unit": "istanbul test _mocha --reporter=spec test/index.js", ++ "test": "npm run lint && npm run unit", ++ "version": "grunt dist && git add dist/" ++ }, ++ "repository": { ++ "type": "git", ++ "url": "git@github.com:indutny/elliptic" ++ }, ++ "keywords": [ ++ "EC", ++ "Elliptic", ++ "curve", ++ "Cryptography" ++ ], ++ "author": "Fedor Indutny fedor@indutny.com", ++ "license": "MIT", ++ "bugs": { ++ "url": "https://github.com/indutny/elliptic/issues" ++ }, ++ "homepage": "https://github.com/indutny/elliptic", ++ "devDependencies": { ++ "brfs": "^1.4.3", ++ "coveralls": "^2.11.3", ++ "grunt": "^0.4.5", ++ "grunt-browserify": "^5.0.0", ++ "grunt-contrib-connect": "^1.0.0", ++ "grunt-contrib-copy": "^1.0.0", ++ "grunt-contrib-uglify": "^1.0.1", ++ "grunt-mocha-istanbul": "^3.0.1", ++ "grunt-saucelabs": "^8.6.2", ++ "istanbul": "^0.4.2", ++ "jscs": "^2.9.0", ++ "jshint": "^2.6.0", ++ "mocha": "^2.1.0" ++ }, ++ "dependencies": { ++ "bn.js": "^4.4.0", ++ "brorand": "^1.0.1", ++ "hash.js": "^1.0.0", ++ "inherits": "^2.0.1" ++ } ++} ++ ++},{}]},{},[2])(2) ++}); ++ ++// End of the imported code from elliptic.js. ++ ++// Create the exported symbol for the JavaScript module. ++var elliptic = window.elliptic; +\ No newline at end of file +diff --git a/chat/protocols/irc/ircSASL.jsm b/chat/protocols/irc/ircSASL.jsm +index 561f055e0..8a2bd70aa 100644 +--- a/chat/protocols/irc/ircSASL.jsm ++++ b/chat/protocols/irc/ircSASL.jsm +@@ -14,6 +14,43 @@ var Cu = Components.utils; + + Cu.import("resource:///modules/ircHandlers.jsm"); + Cu.import("resource:///modules/ircUtils.jsm"); ++Cu.import("resource:///modules/elliptic.jsm"); ++ ++/** ++ ++ ECDSA-NIST256P-CHALLENGE ++ ++ Paste the following code snippit in the Firefox web console to generate a ++ private key (logged as hex string) and the irc command to execute to set ++ the public key on the server. ++ ++ crypto.subtle.generateKey({ name: "ECDSA", namedCurve: "P-256" }, true, ["sign"]) ++ .then((kp) => { ++ crypto.subtle.exportKey("jwk", kp.privateKey).then((o) => { ++ // convert from base64url to hex string ++ let d = o.d; ++ let padLen = (4 - (d.length % 4)) % 4; ++ d = d.padEnd(d.length + padLen, "=") ++ .replace(/-/g, "+") ++ .replace(/_/g, "/"); ++ let str = atob(d); ++ let a = Array.prototype.map.call(str, (x) => x.charCodeAt(0)); ++ let h = a.reduce((prev, next) => prev + next.toString(16), ""); ++ console.log(h); ++ }); ++ crypto.subtle.exportKey("raw", kp.publicKey).then((ab) => { ++ let v = new Uint8Array(ab); ++ let u = v.slice(0, 33); // +1 here for the compressed point ++ u[0] = 2 + (v[v.length - 1] & 1); ++ let s = String.fromCharCode.apply(null, u); ++ console.log("/msg nickserv set property pubkey", btoa(s)); ++ }); ++ }); ++ ++ Then, copy the private key to the preference `messenger.account.accountN.ecdsa` ++ in the config editor. ++ ++*/ + + var ircSASL = { + name: "SASL AUTHENTICATE", +@@ -22,23 +59,41 @@ var ircSASL = { + + commands: { + "AUTHENTICATE": function(aMessage) { +- // Expect an empty response, if something different is received abort. +- if (aMessage.params[0] != "+") { ++ let ecdsa = this.imAccount.wrappedJSObject.prefBranch.getCharPref("ecdsa"); ++ let hasECDSA = !!ecdsa.length; ++ ++ if (aMessage.params[0] === "+") { ++ // An authentication identity, authorization identity and password are ++ // used, separated by null. ++ let data = [this._requestedNickname, this._requestedNickname]; ++ if (!hasECDSA) data.push(this.imAccount.password); ++ // btoa for Unicode, see https://developer.mozilla.org/en-US/docs/DOM/window.btoa ++ let base64Data = btoa(unescape(encodeURIComponent(data.join("\0")))); ++ this.sendMessage("AUTHENTICATE", base64Data); ++ return true; ++ } else if (hasECDSA) { ++ let challenge = aMessage.params[0]; ++ ++ let EC = elliptic.ec; ++ let ec = new EC('p256'); ++ let key = ec.keyFromPrivate(ecdsa, 'hex'); ++ ++ let str = atob(challenge); ++ let arr = Array.prototype.map.call(str, (x) => x.charCodeAt(0)); ++ ++ let signature = key.sign(arr); ++ let der = String.fromCharCode.apply(null, signature.toDER()); ++ let response = btoa(der); ++ ++ this.sendMessage("AUTHENTICATE", response); ++ return true; ++ } else { ++ // Expect an empty response, if something different is received abort. + this.sendMessage("AUTHENTICATE", "*"); + this.WARN("Aborting SASL authentication, unexpected message " + + "received:\n" + aMessage.rawMessage); + return true; + } +- +- // An authentication identity, authorization identity and password are +- // used, separated by null. +- let data = [this._requestedNickname, this._requestedNickname, +- this.imAccount.password].join("\0"); +- // btoa for Unicode, see https://developer.mozilla.org/en-US/docs/DOM/window.btoa +- let base64Data = btoa(unescape(encodeURIComponent(data))); +- this.sendMessage("AUTHENTICATE", base64Data, +- "AUTHENTICATE <base64 encoded nick, user and password not logged>"); +- return true; + }, + + "900": function(aMessage) { +@@ -130,7 +185,10 @@ var capSASL = { + + commands: { + "sasl": function(aMessage) { +- if (aMessage.cap.subcommand == "LS" && this.imAccount.password) { ++ let ecdsa = this.imAccount.wrappedJSObject.prefBranch.getCharPref("ecdsa"); ++ let hasECDSA = !!ecdsa.length; ++ ++ if (aMessage.cap.subcommand == "LS" && (this.imAccount.password || hasECDSA)) { + // If it supports SASL, let the server know we're requiring SASL. + this.sendMessage("CAP", ["REQ", "sasl"]); + this.addCAP("sasl"); +@@ -138,7 +196,8 @@ var capSASL = { + else if (aMessage.cap.subcommand == "ACK") { + // The server acknowledges our choice to use SASL, send the first + // message. +- this.sendMessage("AUTHENTICATE", "PLAIN"); ++ this.sendMessage("AUTHENTICATE", ++ hasECDSA ? "ECDSA-NIST256P-CHALLENGE" : "PLAIN"); + } + + return true; +diff --git a/chat/protocols/irc/moz.build b/chat/protocols/irc/moz.build +index bc2539687..e46815dfe 100644 +--- a/chat/protocols/irc/moz.build ++++ b/chat/protocols/irc/moz.build +@@ -11,6 +11,7 @@ EXTRA_COMPONENTS += [ + ] + + EXTRA_JS_MODULES += [ ++ 'elliptic.jsm', + 'ircBase.jsm', + 'ircCAP.jsm', + 'ircCommands.jsm', +-- +2.11.0 + diff --git a/projects/instantbird/0020-Trac-17480-Content-sink.patch b/projects/instantbird/0020-Trac-17480-Content-sink.patch deleted file mode 100644 index 08c3b6b..0000000 --- a/projects/instantbird/0020-Trac-17480-Content-sink.patch +++ /dev/null @@ -1,111 +0,0 @@ -From 23de5560f17e825ff1c1f9595c8ac92eca45017d Mon Sep 17 00:00:00 2001 -From: Arlo Breault arlolra@gmail.com -Date: Wed, 5 Oct 2016 11:09:25 -0700 -Subject: [PATCH 20/27] Trac 17480: Content sink - ---- - chat/modules/imContentSink.jsm | 33 ++++++--------------------------- - im/content/preferences/content.xul | 2 +- - 2 files changed, 7 insertions(+), 28 deletions(-) - -diff --git a/chat/modules/imContentSink.jsm b/chat/modules/imContentSink.jsm -index abd95fc71..fa32442e4 100644 ---- a/chat/modules/imContentSink.jsm -+++ b/chat/modules/imContentSink.jsm -@@ -42,7 +42,7 @@ this.EXPORTED_SYMBOLS = [ - * See the 3 examples of rulesets below. - */ - --var kAllowedURLs = aValue => /^(https?|ftp|mailto):/.test(aValue); -+var kAllowedURLs = aValue => /^(https?|mailto):/.test(aValue); - var kAllowedMozClasses = - aClassName => aClassName == "moz-txt-underscore" || - aClassName == "moz-txt-tag" || -@@ -60,11 +60,6 @@ var kStrictMode = { - attrs: { }, - - tags: { -- 'a': { -- 'title': true, -- 'href': kAllowedURLs, -- 'class': kAllowedAnchorClasses -- }, - 'br': true, - 'p': true - }, -@@ -74,12 +69,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, -@@ -90,24 +82,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 -@@ -162,7 +141,7 @@ var kPermissiveMode = { - }; - - var kModePref = "messenger.options.filterMode"; --var kModes = [kStrictMode, kStandardMode, kPermissiveMode]; -+var kModes = [kStrictMode, kStandardMode]; - - var gGlobalRuleset = null; - -@@ -188,8 +167,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 3b8ccfa2b..ba41da76a 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.11.0 - diff --git a/projects/instantbird/0021-Bug-1313137-msg-is-not-defined-error-in-irc.js-chang.patch b/projects/instantbird/0021-Bug-1313137-msg-is-not-defined-error-in-irc.js-chang.patch new file mode 100644 index 0000000..7ba6a0d --- /dev/null +++ b/projects/instantbird/0021-Bug-1313137-msg-is-not-defined-error-in-irc.js-chang.patch @@ -0,0 +1,29 @@ +From f11d397c27deb2f34b069e4c6c952793fc67657c Mon Sep 17 00:00:00 2001 +From: aleth aleth@instantbird.org +Date: Wed, 26 Oct 2016 20:16:58 +0200 +Subject: [PATCH 21/26] Bug 1313137 - "msg is not defined" error in + irc.js:changeBuddyNick. r=clokep + +--HG-- +extra : rebase_source : 5752a69059ecd48b947809ef12de177ccab8528f +--- + chat/protocols/irc/irc.js | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/chat/protocols/irc/irc.js b/chat/protocols/irc/irc.js +index c2167a5ec..b58c2c2eb 100644 +--- a/chat/protocols/irc/irc.js ++++ b/chat/protocols/irc/irc.js +@@ -1289,7 +1289,8 @@ ircAccount.prototype = { + this.conversations.set(aNewNick, conversation); + + conversation.updateNick(aNewNick); +- conversation.writeMessage(aOldNick, msg, {system: true}); ++ conversation.writeMessage(aOldNick, _conv("nickSet", aOldNick, aNewNick), ++ {system: true}); + } + }, + +-- +2.11.0 + diff --git a/projects/instantbird/0021-SASL-ECDSA-NIST256P-CHALLENGE.patch b/projects/instantbird/0021-SASL-ECDSA-NIST256P-CHALLENGE.patch deleted file mode 100644 index e7fd09f..0000000 --- a/projects/instantbird/0021-SASL-ECDSA-NIST256P-CHALLENGE.patch +++ /dev/null @@ -1,8919 +0,0 @@ -From b9d9eccfeb4d08804a02b7d09576f14526c90ff0 Mon Sep 17 00:00:00 2001 -From: Arlo Breault arlolra@gmail.com -Date: Sun, 2 Oct 2016 08:46:55 -0700 -Subject: [PATCH 21/27] SASL ECDSA-NIST256P-CHALLENGE - ---- - chat/components/src/imAccounts.js | 1 + - chat/protocols/irc/elliptic.jsm | 8748 +++++++++++++++++++++++++++++++++++++ - chat/protocols/irc/ircSASL.jsm | 87 +- - chat/protocols/irc/moz.build | 1 + - 4 files changed, 8823 insertions(+), 14 deletions(-) - create mode 100644 chat/protocols/irc/elliptic.jsm - -diff --git a/chat/components/src/imAccounts.js b/chat/components/src/imAccounts.js -index 5bfea57f2..da8525ffd 100644 ---- a/chat/components/src/imAccounts.js -+++ b/chat/components/src/imAccounts.js -@@ -193,6 +193,7 @@ function imAccount(aKey, aName, aPrplId) - - imAccount.prototype = { - __proto__: ClassInfo(["imIAccount", "prplIAccount"], "im account object"), -+ get wrappedJSObject() { return this; }, - - name: "", - id: "", -diff --git a/chat/protocols/irc/elliptic.jsm b/chat/protocols/irc/elliptic.jsm -new file mode 100644 -index 000000000..bccab018c ---- /dev/null -+++ b/chat/protocols/irc/elliptic.jsm -@@ -0,0 +1,8748 @@ -+/* This software is licensed under the MIT License. -+ * -+ * Copyright Fedor Indutny, 2014. -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a copy -+ * of this software and associated documentation files (the "Software"), to deal -+ * in the Software without restriction, including without limitation the rights -+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+ * copies of the Software, and to permit persons to whom the Software is -+ * furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -+ * SOFTWARE. -+ */ -+ -+this.EXPORTED_SYMBOLS = ["elliptic"]; -+ -+var window = {}; -+ -+// The code below is imported from indutny's elliptic.js. The original version -+// of this file can be found at -+// https://github.com/indutny/elliptic/blob/master/dist/elliptic.js -+ -+(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.elliptic = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ -+(function (module, exports) { -+ 'use strict'; -+ -+ // Utils -+ function assert (val, msg) { -+ if (!val) throw new Error(msg || 'Assertion failed'); -+ } -+ -+ // Could use `inherits` module, but don't want to move from single file -+ // architecture yet. -+ function inherits (ctor, superCtor) { -+ ctor.super_ = superCtor; -+ var TempCtor = function () {}; -+ TempCtor.prototype = superCtor.prototype; -+ ctor.prototype = new TempCtor(); -+ ctor.prototype.constructor = ctor; -+ } -+ -+ // BN -+ -+ function BN (number, base, endian) { -+ if (BN.isBN(number)) { -+ return number; -+ } -+ -+ this.negative = 0; -+ this.words = null; -+ this.length = 0; -+ -+ // Reduction context -+ this.red = null; -+ -+ if (number !== null) { -+ if (base === 'le' || base === 'be') { -+ endian = base; -+ base = 10; -+ } -+ -+ this._init(number || 0, base || 10, endian || 'be'); -+ } -+ } -+ if (typeof module === 'object') { -+ module.exports = BN; -+ } else { -+ exports.BN = BN; -+ } -+ -+ BN.BN = BN; -+ BN.wordSize = 26; -+ -+ var Buffer; -+ try { -+ Buffer = require('buf' + 'fer').Buffer; -+ } catch (e) { -+ } -+ -+ BN.isBN = function isBN (num) { -+ if (num instanceof BN) { -+ return true; -+ } -+ -+ return num !== null && typeof num === 'object' && -+ num.constructor.wordSize === BN.wordSize && Array.isArray(num.words); -+ }; -+ -+ BN.max = function max (left, right) { -+ if (left.cmp(right) > 0) return left; -+ return right; -+ }; -+ -+ BN.min = function min (left, right) { -+ if (left.cmp(right) < 0) return left; -+ return right; -+ }; -+ -+ BN.prototype._init = function init (number, base, endian) { -+ if (typeof number === 'number') { -+ return this._initNumber(number, base, endian); -+ } -+ -+ if (typeof number === 'object') { -+ return this._initArray(number, base, endian); -+ } -+ -+ if (base === 'hex') { -+ base = 16; -+ } -+ assert(base === (base | 0) && base >= 2 && base <= 36); -+ -+ number = number.toString().replace(/\s+/g, ''); -+ var start = 0; -+ if (number[0] === '-') { -+ start++; -+ } -+ -+ if (base === 16) { -+ this._parseHex(number, start); -+ } else { -+ this._parseBase(number, base, start); -+ } -+ -+ if (number[0] === '-') { -+ this.negative = 1; -+ } -+ -+ this.strip(); -+ -+ if (endian !== 'le') return; -+ -+ this._initArray(this.toArray(), base, endian); -+ }; -+ -+ BN.prototype._initNumber = function _initNumber (number, base, endian) { -+ if (number < 0) { -+ this.negative = 1; -+ number = -number; -+ } -+ if (number < 0x4000000) { -+ this.words = [ number & 0x3ffffff ]; -+ this.length = 1; -+ } else if (number < 0x10000000000000) { -+ this.words = [ -+ number & 0x3ffffff, -+ (number / 0x4000000) & 0x3ffffff -+ ]; -+ this.length = 2; -+ } else { -+ assert(number < 0x20000000000000); // 2 ^ 53 (unsafe) -+ this.words = [ -+ number & 0x3ffffff, -+ (number / 0x4000000) & 0x3ffffff, -+ 1 -+ ]; -+ this.length = 3; -+ } -+ -+ if (endian !== 'le') return; -+ -+ // Reverse the bytes -+ this._initArray(this.toArray(), base, endian); -+ }; -+ -+ BN.prototype._initArray = function _initArray (number, base, endian) { -+ // Perhaps a Uint8Array -+ assert(typeof number.length === 'number'); -+ if (number.length <= 0) { -+ this.words = [ 0 ]; -+ this.length = 1; -+ return this; -+ } -+ -+ this.length = Math.ceil(number.length / 3); -+ this.words = new Array(this.length); -+ for (var i = 0; i < this.length; i++) { -+ this.words[i] = 0; -+ } -+ -+ var j, w; -+ var off = 0; -+ if (endian === 'be') { -+ for (i = number.length - 1, j = 0; i >= 0; i -= 3) { -+ w = number[i] | (number[i - 1] << 8) | (number[i - 2] << 16); -+ this.words[j] |= (w << off) & 0x3ffffff; -+ this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff; -+ off += 24; -+ if (off >= 26) { -+ off -= 26; -+ j++; -+ } -+ } -+ } else if (endian === 'le') { -+ for (i = 0, j = 0; i < number.length; i += 3) { -+ w = number[i] | (number[i + 1] << 8) | (number[i + 2] << 16); -+ this.words[j] |= (w << off) & 0x3ffffff; -+ this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff; -+ off += 24; -+ if (off >= 26) { -+ off -= 26; -+ j++; -+ } -+ } -+ } -+ return this.strip(); -+ }; -+ -+ function parseHex (str, start, end) { -+ var r = 0; -+ var len = Math.min(str.length, end); -+ for (var i = start; i < len; i++) { -+ var c = str.charCodeAt(i) - 48; -+ -+ r <<= 4; -+ -+ // 'a' - 'f' -+ if (c >= 49 && c <= 54) { -+ r |= c - 49 + 0xa; -+ -+ // 'A' - 'F' -+ } else if (c >= 17 && c <= 22) { -+ r |= c - 17 + 0xa; -+ -+ // '0' - '9' -+ } else { -+ r |= c & 0xf; -+ } -+ } -+ return r; -+ } -+ -+ BN.prototype._parseHex = function _parseHex (number, start) { -+ // Create possibly bigger array to ensure that it fits the number -+ this.length = Math.ceil((number.length - start) / 6); -+ this.words = new Array(this.length); -+ for (var i = 0; i < this.length; i++) { -+ this.words[i] = 0; -+ } -+ -+ var j, w; -+ // Scan 24-bit chunks and add them to the number -+ var off = 0; -+ for (i = number.length - 6, j = 0; i >= start; i -= 6) { -+ w = parseHex(number, i, i + 6); -+ this.words[j] |= (w << off) & 0x3ffffff; -+ // NOTE: `0x3fffff` is intentional here, 26bits max shift + 24bit hex limb -+ this.words[j + 1] |= w >>> (26 - off) & 0x3fffff; -+ off += 24; -+ if (off >= 26) { -+ off -= 26; -+ j++; -+ } -+ } -+ if (i + 6 !== start) { -+ w = parseHex(number, start, i + 6); -+ this.words[j] |= (w << off) & 0x3ffffff; -+ this.words[j + 1] |= w >>> (26 - off) & 0x3fffff; -+ } -+ this.strip(); -+ }; -+ -+ function parseBase (str, start, end, mul) { -+ var r = 0; -+ var len = Math.min(str.length, end); -+ for (var i = start; i < len; i++) { -+ var c = str.charCodeAt(i) - 48; -+ -+ r *= mul; -+ -+ // 'a' -+ if (c >= 49) { -+ r += c - 49 + 0xa; -+ -+ // 'A' -+ } else if (c >= 17) { -+ r += c - 17 + 0xa; -+ -+ // '0' - '9' -+ } else { -+ r += c; -+ } -+ } -+ return r; -+ } -+ -+ BN.prototype._parseBase = function _parseBase (number, base, start) { -+ // Initialize as zero -+ this.words = [ 0 ]; -+ this.length = 1; -+ -+ // Find length of limb in base -+ for (var limbLen = 0, limbPow = 1; limbPow <= 0x3ffffff; limbPow *= base) { -+ limbLen++; -+ } -+ limbLen--; -+ limbPow = (limbPow / base) | 0; -+ -+ var total = number.length - start; -+ var mod = total % limbLen; -+ var end = Math.min(total, total - mod) + start; -+ -+ var word = 0; -+ for (var i = start; i < end; i += limbLen) { -+ word = parseBase(number, i, i + limbLen, base); -+ -+ this.imuln(limbPow); -+ if (this.words[0] + word < 0x4000000) { -+ this.words[0] += word; -+ } else { -+ this._iaddn(word); -+ } -+ } -+ -+ if (mod !== 0) { -+ var pow = 1; -+ word = parseBase(number, i, number.length, base); -+ -+ for (i = 0; i < mod; i++) { -+ pow *= base; -+ } -+ -+ this.imuln(pow); -+ if (this.words[0] + word < 0x4000000) { -+ this.words[0] += word; -+ } else { -+ this._iaddn(word); -+ } -+ } -+ }; -+ -+ BN.prototype.copy = function copy (dest) { -+ dest.words = new Array(this.length); -+ for (var i = 0; i < this.length; i++) { -+ dest.words[i] = this.words[i]; -+ } -+ dest.length = this.length; -+ dest.negative = this.negative; -+ dest.red = this.red; -+ }; -+ -+ BN.prototype.clone = function clone () { -+ var r = new BN(null); -+ this.copy(r); -+ return r; -+ }; -+ -+ BN.prototype._expand = function _expand (size) { -+ while (this.length < size) { -+ this.words[this.length++] = 0; -+ } -+ return this; -+ }; -+ -+ // Remove leading `0` from `this` -+ BN.prototype.strip = function strip () { -+ while (this.length > 1 && this.words[this.length - 1] === 0) { -+ this.length--; -+ } -+ return this._normSign(); -+ }; -+ -+ BN.prototype._normSign = function _normSign () { -+ // -0 = 0 -+ if (this.length === 1 && this.words[0] === 0) { -+ this.negative = 0; -+ } -+ return this; -+ }; -+ -+ BN.prototype.inspect = function inspect () { -+ return (this.red ? '<BN-R: ' : '<BN: ') + this.toString(16) + '>'; -+ }; -+ -+ /* -+ -+ var zeros = []; -+ var groupSizes = []; -+ var groupBases = []; -+ -+ var s = ''; -+ var i = -1; -+ while (++i < BN.wordSize) { -+ zeros[i] = s; -+ s += '0'; -+ } -+ groupSizes[0] = 0; -+ groupSizes[1] = 0; -+ groupBases[0] = 0; -+ groupBases[1] = 0; -+ var base = 2 - 1; -+ while (++base < 36 + 1) { -+ var groupSize = 0; -+ var groupBase = 1; -+ while (groupBase < (1 << BN.wordSize) / base) { -+ groupBase *= base; -+ groupSize += 1; -+ } -+ groupSizes[base] = groupSize; -+ groupBases[base] = groupBase; -+ } -+ -+ */ -+ -+ var zeros = [ -+ '', -+ '0', -+ '00', -+ '000', -+ '0000', -+ '00000', -+ '000000', -+ '0000000', -+ '00000000', -+ '000000000', -+ '0000000000', -+ '00000000000', -+ '000000000000', -+ '0000000000000', -+ '00000000000000', -+ '000000000000000', -+ '0000000000000000', -+ '00000000000000000', -+ '000000000000000000', -+ '0000000000000000000', -+ '00000000000000000000', -+ '000000000000000000000', -+ '0000000000000000000000', -+ '00000000000000000000000', -+ '000000000000000000000000', -+ '0000000000000000000000000' -+ ]; -+ -+ var groupSizes = [ -+ 0, 0, -+ 25, 16, 12, 11, 10, 9, 8, -+ 8, 7, 7, 7, 7, 6, 6, -+ 6, 6, 6, 6, 6, 5, 5, -+ 5, 5, 5, 5, 5, 5, 5, -+ 5, 5, 5, 5, 5, 5, 5 -+ ]; -+ -+ var groupBases = [ -+ 0, 0, -+ 33554432, 43046721, 16777216, 48828125, 60466176, 40353607, 16777216, -+ 43046721, 10000000, 19487171, 35831808, 62748517, 7529536, 11390625, -+ 16777216, 24137569, 34012224, 47045881, 64000000, 4084101, 5153632, -+ 6436343, 7962624, 9765625, 11881376, 14348907, 17210368, 20511149, -+ 24300000, 28629151, 33554432, 39135393, 45435424, 52521875, 60466176 -+ ]; -+ -+ BN.prototype.toString = function toString (base, padding) { -+ base = base || 10; -+ padding = padding | 0 || 1; -+ -+ var out; -+ if (base === 16 || base === 'hex') { -+ out = ''; -+ var off = 0; -+ var carry = 0; -+ for (var i = 0; i < this.length; i++) { -+ var w = this.words[i]; -+ var word = (((w << off) | carry) & 0xffffff).toString(16); -+ carry = (w >>> (24 - off)) & 0xffffff; -+ if (carry !== 0 || i !== this.length - 1) { -+ out = zeros[6 - word.length] + word + out; -+ } else { -+ out = word + out; -+ } -+ off += 2; -+ if (off >= 26) { -+ off -= 26; -+ i--; -+ } -+ } -+ if (carry !== 0) { -+ out = carry.toString(16) + out; -+ } -+ while (out.length % padding !== 0) { -+ out = '0' + out; -+ } -+ if (this.negative !== 0) { -+ out = '-' + out; -+ } -+ return out; -+ } -+ -+ if (base === (base | 0) && base >= 2 && base <= 36) { -+ // var groupSize = Math.floor(BN.wordSize * Math.LN2 / Math.log(base)); -+ var groupSize = groupSizes[base]; -+ // var groupBase = Math.pow(base, groupSize); -+ var groupBase = groupBases[base]; -+ out = ''; -+ var c = this.clone(); -+ c.negative = 0; -+ while (!c.isZero()) { -+ var r = c.modn(groupBase).toString(base); -+ c = c.idivn(groupBase); -+ -+ if (!c.isZero()) { -+ out = zeros[groupSize - r.length] + r + out; -+ } else { -+ out = r + out; -+ } -+ } -+ if (this.isZero()) { -+ out = '0' + out; -+ } -+ while (out.length % padding !== 0) { -+ out = '0' + out; -+ } -+ if (this.negative !== 0) { -+ out = '-' + out; -+ } -+ return out; -+ } -+ -+ assert(false, 'Base should be between 2 and 36'); -+ }; -+ -+ BN.prototype.toNumber = function toNumber () { -+ var ret = this.words[0]; -+ if (this.length === 2) { -+ ret += this.words[1] * 0x4000000; -+ } else if (this.length === 3 && this.words[2] === 0x01) { -+ // NOTE: at this stage it is known that the top bit is set -+ ret += 0x10000000000000 + (this.words[1] * 0x4000000); -+ } else if (this.length > 2) { -+ assert(false, 'Number can only safely store up to 53 bits'); -+ } -+ return (this.negative !== 0) ? -ret : ret; -+ }; -+ -+ BN.prototype.toJSON = function toJSON () { -+ return this.toString(16); -+ }; -+ -+ BN.prototype.toBuffer = function toBuffer (endian, length) { -+ assert(typeof Buffer !== 'undefined'); -+ return this.toArrayLike(Buffer, endian, length); -+ }; -+ -+ BN.prototype.toArray = function toArray (endian, length) { -+ return this.toArrayLike(Array, endian, length); -+ }; -+ -+ BN.prototype.toArrayLike = function toArrayLike (ArrayType, endian, length) { -+ var byteLength = this.byteLength(); -+ var reqLength = length || Math.max(1, byteLength); -+ assert(byteLength <= reqLength, 'byte array longer than desired length'); -+ assert(reqLength > 0, 'Requested array length <= 0'); -+ -+ this.strip(); -+ var littleEndian = endian === 'le'; -+ var res = new ArrayType(reqLength); -+ -+ var b, i; -+ var q = this.clone(); -+ if (!littleEndian) { -+ // Assume big-endian -+ for (i = 0; i < reqLength - byteLength; i++) { -+ res[i] = 0; -+ } -+ -+ for (i = 0; !q.isZero(); i++) { -+ b = q.andln(0xff); -+ q.iushrn(8); -+ -+ res[reqLength - i - 1] = b; -+ } -+ } else { -+ for (i = 0; !q.isZero(); i++) { -+ b = q.andln(0xff); -+ q.iushrn(8); -+ -+ res[i] = b; -+ } -+ -+ for (; i < reqLength; i++) { -+ res[i] = 0; -+ } -+ } -+ -+ return res; -+ }; -+ -+ if (Math.clz32) { -+ BN.prototype._countBits = function _countBits (w) { -+ return 32 - Math.clz32(w); -+ }; -+ } else { -+ BN.prototype._countBits = function _countBits (w) { -+ var t = w; -+ var r = 0; -+ if (t >= 0x1000) { -+ r += 13; -+ t >>>= 13; -+ } -+ if (t >= 0x40) { -+ r += 7; -+ t >>>= 7; -+ } -+ if (t >= 0x8) { -+ r += 4; -+ t >>>= 4; -+ } -+ if (t >= 0x02) { -+ r += 2; -+ t >>>= 2; -+ } -+ return r + t; -+ }; -+ } -+ -+ BN.prototype._zeroBits = function _zeroBits (w) { -+ // Short-cut -+ if (w === 0) return 26; -+ -+ var t = w; -+ var r = 0; -+ if ((t & 0x1fff) === 0) { -+ r += 13; -+ t >>>= 13; -+ } -+ if ((t & 0x7f) === 0) { -+ r += 7; -+ t >>>= 7; -+ } -+ if ((t & 0xf) === 0) { -+ r += 4; -+ t >>>= 4; -+ } -+ if ((t & 0x3) === 0) { -+ r += 2; -+ t >>>= 2; -+ } -+ if ((t & 0x1) === 0) { -+ r++; -+ } -+ return r; -+ }; -+ -+ // Return number of used bits in a BN -+ BN.prototype.bitLength = function bitLength () { -+ var w = this.words[this.length - 1]; -+ var hi = this._countBits(w); -+ return (this.length - 1) * 26 + hi; -+ }; -+ -+ function toBitArray (num) { -+ var w = new Array(num.bitLength()); -+ -+ for (var bit = 0; bit < w.length; bit++) { -+ var off = (bit / 26) | 0; -+ var wbit = bit % 26; -+ -+ w[bit] = (num.words[off] & (1 << wbit)) >>> wbit; -+ } -+ -+ return w; -+ } -+ -+ // Number of trailing zero bits -+ BN.prototype.zeroBits = function zeroBits () { -+ if (this.isZero()) return 0; -+ -+ var r = 0; -+ for (var i = 0; i < this.length; i++) { -+ var b = this._zeroBits(this.words[i]); -+ r += b; -+ if (b !== 26) break; -+ } -+ return r; -+ }; -+ -+ BN.prototype.byteLength = function byteLength () { -+ return Math.ceil(this.bitLength() / 8); -+ }; -+ -+ BN.prototype.toTwos = function toTwos (width) { -+ if (this.negative !== 0) { -+ return this.abs().inotn(width).iaddn(1); -+ } -+ return this.clone(); -+ }; -+ -+ BN.prototype.fromTwos = function fromTwos (width) { -+ if (this.testn(width - 1)) { -+ return this.notn(width).iaddn(1).ineg(); -+ } -+ return this.clone(); -+ }; -+ -+ BN.prototype.isNeg = function isNeg () { -+ return this.negative !== 0; -+ }; -+ -+ // Return negative clone of `this` -+ BN.prototype.neg = function neg () { -+ return this.clone().ineg(); -+ }; -+ -+ BN.prototype.ineg = function ineg () { -+ if (!this.isZero()) { -+ this.negative ^= 1; -+ } -+ -+ return this; -+ }; -+ -+ // Or `num` with `this` in-place -+ BN.prototype.iuor = function iuor (num) { -+ while (this.length < num.length) { -+ this.words[this.length++] = 0; -+ } -+ -+ for (var i = 0; i < num.length; i++) { -+ this.words[i] = this.words[i] | num.words[i]; -+ } -+ -+ return this.strip(); -+ }; -+ -+ BN.prototype.ior = function ior (num) { -+ assert((this.negative | num.negative) === 0); -+ return this.iuor(num); -+ }; -+ -+ // Or `num` with `this` -+ BN.prototype.or = function or (num) { -+ if (this.length > num.length) return this.clone().ior(num); -+ return num.clone().ior(this); -+ }; -+ -+ BN.prototype.uor = function uor (num) { -+ if (this.length > num.length) return this.clone().iuor(num); -+ return num.clone().iuor(this); -+ }; -+ -+ // And `num` with `this` in-place -+ BN.prototype.iuand = function iuand (num) { -+ // b = min-length(num, this) -+ var b; -+ if (this.length > num.length) { -+ b = num; -+ } else { -+ b = this; -+ } -+ -+ for (var i = 0; i < b.length; i++) { -+ this.words[i] = this.words[i] & num.words[i]; -+ } -+ -+ this.length = b.length; -+ -+ return this.strip(); -+ }; -+ -+ BN.prototype.iand = function iand (num) { -+ assert((this.negative | num.negative) === 0); -+ return this.iuand(num); -+ }; -+ -+ // And `num` with `this` -+ BN.prototype.and = function and (num) { -+ if (this.length > num.length) return this.clone().iand(num); -+ return num.clone().iand(this); -+ }; -+ -+ BN.prototype.uand = function uand (num) { -+ if (this.length > num.length) return this.clone().iuand(num); -+ return num.clone().iuand(this); -+ }; -+ -+ // Xor `num` with `this` in-place -+ BN.prototype.iuxor = function iuxor (num) { -+ // a.length > b.length -+ var a; -+ var b; -+ if (this.length > num.length) { -+ a = this; -+ b = num; -+ } else { -+ a = num; -+ b = this; -+ } -+ -+ for (var i = 0; i < b.length; i++) { -+ this.words[i] = a.words[i] ^ b.words[i]; -+ } -+ -+ if (this !== a) { -+ for (; i < a.length; i++) { -+ this.words[i] = a.words[i]; -+ } -+ } -+ -+ this.length = a.length; -+ -+ return this.strip(); -+ }; -+ -+ BN.prototype.ixor = function ixor (num) { -+ assert((this.negative | num.negative) === 0); -+ return this.iuxor(num); -+ }; -+ -+ // Xor `num` with `this` -+ BN.prototype.xor = function xor (num) { -+ if (this.length > num.length) return this.clone().ixor(num); -+ return num.clone().ixor(this); -+ }; -+ -+ BN.prototype.uxor = function uxor (num) { -+ if (this.length > num.length) return this.clone().iuxor(num); -+ return num.clone().iuxor(this); -+ }; -+ -+ // Not ``this`` with ``width`` bitwidth -+ BN.prototype.inotn = function inotn (width) { -+ assert(typeof width === 'number' && width >= 0); -+ -+ var bytesNeeded = Math.ceil(width / 26) | 0; -+ var bitsLeft = width % 26; -+ -+ // Extend the buffer with leading zeroes -+ this._expand(bytesNeeded); -+ -+ if (bitsLeft > 0) { -+ bytesNeeded--; -+ } -+ -+ // Handle complete words -+ for (var i = 0; i < bytesNeeded; i++) { -+ this.words[i] = ~this.words[i] & 0x3ffffff; -+ } -+ -+ // Handle the residue -+ if (bitsLeft > 0) { -+ this.words[i] = ~this.words[i] & (0x3ffffff >> (26 - bitsLeft)); -+ } -+ -+ // And remove leading zeroes -+ return this.strip(); -+ }; -+ -+ BN.prototype.notn = function notn (width) { -+ return this.clone().inotn(width); -+ }; -+ -+ // Set `bit` of `this` -+ BN.prototype.setn = function setn (bit, val) { -+ assert(typeof bit === 'number' && bit >= 0); -+ -+ var off = (bit / 26) | 0; -+ var wbit = bit % 26; -+ -+ this._expand(off + 1); -+ -+ if (val) { -+ this.words[off] = this.words[off] | (1 << wbit); -+ } else { -+ this.words[off] = this.words[off] & ~(1 << wbit); -+ } -+ -+ return this.strip(); -+ }; -+ -+ // Add `num` to `this` in-place -+ BN.prototype.iadd = function iadd (num) { -+ var r; -+ -+ // negative + positive -+ if (this.negative !== 0 && num.negative === 0) { -+ this.negative = 0; -+ r = this.isub(num); -+ this.negative ^= 1; -+ return this._normSign(); -+ -+ // positive + negative -+ } else if (this.negative === 0 && num.negative !== 0) { -+ num.negative = 0; -+ r = this.isub(num); -+ num.negative = 1; -+ return r._normSign(); -+ } -+ -+ // a.length > b.length -+ var a, b; -+ if (this.length > num.length) { -+ a = this; -+ b = num; -+ } else { -+ a = num; -+ b = this; -+ } -+ -+ var carry = 0; -+ for (var i = 0; i < b.length; i++) { -+ r = (a.words[i] | 0) + (b.words[i] | 0) + carry; -+ this.words[i] = r & 0x3ffffff; -+ carry = r >>> 26; -+ } -+ for (; carry !== 0 && i < a.length; i++) { -+ r = (a.words[i] | 0) + carry; -+ this.words[i] = r & 0x3ffffff; -+ carry = r >>> 26; -+ } -+ -+ this.length = a.length; -+ if (carry !== 0) { -+ this.words[this.length] = carry; -+ this.length++; -+ // Copy the rest of the words -+ } else if (a !== this) { -+ for (; i < a.length; i++) { -+ this.words[i] = a.words[i]; -+ } -+ } -+ -+ return this; -+ }; -+ -+ // Add `num` to `this` -+ BN.prototype.add = function add (num) { -+ var res; -+ if (num.negative !== 0 && this.negative === 0) { -+ num.negative = 0; -+ res = this.sub(num); -+ num.negative ^= 1; -+ return res; -+ } else if (num.negative === 0 && this.negative !== 0) { -+ this.negative = 0; -+ res = num.sub(this); -+ this.negative = 1; -+ return res; -+ } -+ -+ if (this.length > num.length) return this.clone().iadd(num); -+ -+ return num.clone().iadd(this); -+ }; -+ -+ // Subtract `num` from `this` in-place -+ BN.prototype.isub = function isub (num) { -+ // this - (-num) = this + num -+ if (num.negative !== 0) { -+ num.negative = 0; -+ var r = this.iadd(num); -+ num.negative = 1; -+ return r._normSign(); -+ -+ // -this - num = -(this + num) -+ } else if (this.negative !== 0) { -+ this.negative = 0; -+ this.iadd(num); -+ this.negative = 1; -+ return this._normSign(); -+ } -+ -+ // At this point both numbers are positive -+ var cmp = this.cmp(num); -+ -+ // Optimization - zeroify -+ if (cmp === 0) { -+ this.negative = 0; -+ this.length = 1; -+ this.words[0] = 0; -+ return this; -+ } -+ -+ // a > b -+ var a, b; -+ if (cmp > 0) { -+ a = this; -+ b = num; -+ } else { -+ a = num; -+ b = this; -+ } -+ -+ var carry = 0; -+ for (var i = 0; i < b.length; i++) { -+ r = (a.words[i] | 0) - (b.words[i] | 0) + carry; -+ carry = r >> 26; -+ this.words[i] = r & 0x3ffffff; -+ } -+ for (; carry !== 0 && i < a.length; i++) { -+ r = (a.words[i] | 0) + carry; -+ carry = r >> 26; -+ this.words[i] = r & 0x3ffffff; -+ } -+ -+ // Copy rest of the words -+ if (carry === 0 && i < a.length && a !== this) { -+ for (; i < a.length; i++) { -+ this.words[i] = a.words[i]; -+ } -+ } -+ -+ this.length = Math.max(this.length, i); -+ -+ if (a !== this) { -+ this.negative = 1; -+ } -+ -+ return this.strip(); -+ }; -+ -+ // Subtract `num` from `this` -+ BN.prototype.sub = function sub (num) { -+ return this.clone().isub(num); -+ }; -+ -+ function smallMulTo (self, num, out) { -+ out.negative = num.negative ^ self.negative; -+ var len = (self.length + num.length) | 0; -+ out.length = len; -+ len = (len - 1) | 0; -+ -+ // Peel one iteration (compiler can't do it, because of code complexity) -+ var a = self.words[0] | 0; -+ var b = num.words[0] | 0; -+ var r = a * b; -+ -+ var lo = r & 0x3ffffff; -+ var carry = (r / 0x4000000) | 0; -+ out.words[0] = lo; -+ -+ for (var k = 1; k < len; k++) { -+ // Sum all words with the same `i + j = k` and accumulate `ncarry`, -+ // note that ncarry could be >= 0x3ffffff -+ var ncarry = carry >>> 26; -+ var rword = carry & 0x3ffffff; -+ var maxJ = Math.min(k, num.length - 1); -+ for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) { -+ var i = (k - j) | 0; -+ a = self.words[i] | 0; -+ b = num.words[j] | 0; -+ r = a * b + rword; -+ ncarry += (r / 0x4000000) | 0; -+ rword = r & 0x3ffffff; -+ } -+ out.words[k] = rword | 0; -+ carry = ncarry | 0; -+ } -+ if (carry !== 0) { -+ out.words[k] = carry | 0; -+ } else { -+ out.length--; -+ } -+ -+ return out.strip(); -+ } -+ -+ // TODO(indutny): it may be reasonable to omit it for users who don't need -+ // to work with 256-bit numbers, otherwise it gives 20% improvement for 256-bit -+ // multiplication (like elliptic secp256k1). -+ var comb10MulTo = function comb10MulTo (self, num, out) { -+ var a = self.words; -+ var b = num.words; -+ var o = out.words; -+ var c = 0; -+ var lo; -+ var mid; -+ var hi; -+ var a0 = a[0] | 0; -+ var al0 = a0 & 0x1fff; -+ var ah0 = a0 >>> 13; -+ var a1 = a[1] | 0; -+ var al1 = a1 & 0x1fff; -+ var ah1 = a1 >>> 13; -+ var a2 = a[2] | 0; -+ var al2 = a2 & 0x1fff; -+ var ah2 = a2 >>> 13; -+ var a3 = a[3] | 0; -+ var al3 = a3 & 0x1fff; -+ var ah3 = a3 >>> 13; -+ var a4 = a[4] | 0; -+ var al4 = a4 & 0x1fff; -+ var ah4 = a4 >>> 13; -+ var a5 = a[5] | 0; -+ var al5 = a5 & 0x1fff; -+ var ah5 = a5 >>> 13; -+ var a6 = a[6] | 0; -+ var al6 = a6 & 0x1fff; -+ var ah6 = a6 >>> 13; -+ var a7 = a[7] | 0; -+ var al7 = a7 & 0x1fff; -+ var ah7 = a7 >>> 13; -+ var a8 = a[8] | 0; -+ var al8 = a8 & 0x1fff; -+ var ah8 = a8 >>> 13; -+ var a9 = a[9] | 0; -+ var al9 = a9 & 0x1fff; -+ var ah9 = a9 >>> 13; -+ var b0 = b[0] | 0; -+ var bl0 = b0 & 0x1fff; -+ var bh0 = b0 >>> 13; -+ var b1 = b[1] | 0; -+ var bl1 = b1 & 0x1fff; -+ var bh1 = b1 >>> 13; -+ var b2 = b[2] | 0; -+ var bl2 = b2 & 0x1fff; -+ var bh2 = b2 >>> 13; -+ var b3 = b[3] | 0; -+ var bl3 = b3 & 0x1fff; -+ var bh3 = b3 >>> 13; -+ var b4 = b[4] | 0; -+ var bl4 = b4 & 0x1fff; -+ var bh4 = b4 >>> 13; -+ var b5 = b[5] | 0; -+ var bl5 = b5 & 0x1fff; -+ var bh5 = b5 >>> 13; -+ var b6 = b[6] | 0; -+ var bl6 = b6 & 0x1fff; -+ var bh6 = b6 >>> 13; -+ var b7 = b[7] | 0; -+ var bl7 = b7 & 0x1fff; -+ var bh7 = b7 >>> 13; -+ var b8 = b[8] | 0; -+ var bl8 = b8 & 0x1fff; -+ var bh8 = b8 >>> 13; -+ var b9 = b[9] | 0; -+ var bl9 = b9 & 0x1fff; -+ var bh9 = b9 >>> 13; -+ -+ out.negative = self.negative ^ num.negative; -+ out.length = 19; -+ /* k = 0 */ -+ lo = Math.imul(al0, bl0); -+ mid = Math.imul(al0, bh0); -+ mid = (mid + Math.imul(ah0, bl0)) | 0; -+ hi = Math.imul(ah0, bh0); -+ var w0 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; -+ c = (((hi + (mid >>> 13)) | 0) + (w0 >>> 26)) | 0; -+ w0 &= 0x3ffffff; -+ /* k = 1 */ -+ lo = Math.imul(al1, bl0); -+ mid = Math.imul(al1, bh0); -+ mid = (mid + Math.imul(ah1, bl0)) | 0; -+ hi = Math.imul(ah1, bh0); -+ lo = (lo + Math.imul(al0, bl1)) | 0; -+ mid = (mid + Math.imul(al0, bh1)) | 0; -+ mid = (mid + Math.imul(ah0, bl1)) | 0; -+ hi = (hi + Math.imul(ah0, bh1)) | 0; -+ var w1 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; -+ c = (((hi + (mid >>> 13)) | 0) + (w1 >>> 26)) | 0; -+ w1 &= 0x3ffffff; -+ /* k = 2 */ -+ lo = Math.imul(al2, bl0); -+ mid = Math.imul(al2, bh0); -+ mid = (mid + Math.imul(ah2, bl0)) | 0; -+ hi = Math.imul(ah2, bh0); -+ lo = (lo + Math.imul(al1, bl1)) | 0; -+ mid = (mid + Math.imul(al1, bh1)) | 0; -+ mid = (mid + Math.imul(ah1, bl1)) | 0; -+ hi = (hi + Math.imul(ah1, bh1)) | 0; -+ lo = (lo + Math.imul(al0, bl2)) | 0; -+ mid = (mid + Math.imul(al0, bh2)) | 0; -+ mid = (mid + Math.imul(ah0, bl2)) | 0; -+ hi = (hi + Math.imul(ah0, bh2)) | 0; -+ var w2 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; -+ c = (((hi + (mid >>> 13)) | 0) + (w2 >>> 26)) | 0; -+ w2 &= 0x3ffffff; -+ /* k = 3 */ -+ lo = Math.imul(al3, bl0); -+ mid = Math.imul(al3, bh0); -+ mid = (mid + Math.imul(ah3, bl0)) | 0; -+ hi = Math.imul(ah3, bh0); -+ lo = (lo + Math.imul(al2, bl1)) | 0; -+ mid = (mid + Math.imul(al2, bh1)) | 0; -+ mid = (mid + Math.imul(ah2, bl1)) | 0; -+ hi = (hi + Math.imul(ah2, bh1)) | 0; -+ lo = (lo + Math.imul(al1, bl2)) | 0; -+ mid = (mid + Math.imul(al1, bh2)) | 0; -+ mid = (mid + Math.imul(ah1, bl2)) | 0; -+ hi = (hi + Math.imul(ah1, bh2)) | 0; -+ lo = (lo + Math.imul(al0, bl3)) | 0; -+ mid = (mid + Math.imul(al0, bh3)) | 0; -+ mid = (mid + Math.imul(ah0, bl3)) | 0; -+ hi = (hi + Math.imul(ah0, bh3)) | 0; -+ var w3 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; -+ c = (((hi + (mid >>> 13)) | 0) + (w3 >>> 26)) | 0; -+ w3 &= 0x3ffffff; -+ /* k = 4 */ -+ lo = Math.imul(al4, bl0); -+ mid = Math.imul(al4, bh0); -+ mid = (mid + Math.imul(ah4, bl0)) | 0; -+ hi = Math.imul(ah4, bh0); -+ lo = (lo + Math.imul(al3, bl1)) | 0; -+ mid = (mid + Math.imul(al3, bh1)) | 0; -+ mid = (mid + Math.imul(ah3, bl1)) | 0; -+ hi = (hi + Math.imul(ah3, bh1)) | 0; -+ lo = (lo + Math.imul(al2, bl2)) | 0; -+ mid = (mid + Math.imul(al2, bh2)) | 0; -+ mid = (mid + Math.imul(ah2, bl2)) | 0; -+ hi = (hi + Math.imul(ah2, bh2)) | 0; -+ lo = (lo + Math.imul(al1, bl3)) | 0; -+ mid = (mid + Math.imul(al1, bh3)) | 0; -+ mid = (mid + Math.imul(ah1, bl3)) | 0; -+ hi = (hi + Math.imul(ah1, bh3)) | 0; -+ lo = (lo + Math.imul(al0, bl4)) | 0; -+ mid = (mid + Math.imul(al0, bh4)) | 0; -+ mid = (mid + Math.imul(ah0, bl4)) | 0; -+ hi = (hi + Math.imul(ah0, bh4)) | 0; -+ var w4 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; -+ c = (((hi + (mid >>> 13)) | 0) + (w4 >>> 26)) | 0; -+ w4 &= 0x3ffffff; -+ /* k = 5 */ -+ lo = Math.imul(al5, bl0); -+ mid = Math.imul(al5, bh0); -+ mid = (mid + Math.imul(ah5, bl0)) | 0; -+ hi = Math.imul(ah5, bh0); -+ lo = (lo + Math.imul(al4, bl1)) | 0; -+ mid = (mid + Math.imul(al4, bh1)) | 0; -+ mid = (mid + Math.imul(ah4, bl1)) | 0; -+ hi = (hi + Math.imul(ah4, bh1)) | 0; -+ lo = (lo + Math.imul(al3, bl2)) | 0; -+ mid = (mid + Math.imul(al3, bh2)) | 0; -+ mid = (mid + Math.imul(ah3, bl2)) | 0; -+ hi = (hi + Math.imul(ah3, bh2)) | 0; -+ lo = (lo + Math.imul(al2, bl3)) | 0; -+ mid = (mid + Math.imul(al2, bh3)) | 0; -+ mid = (mid + Math.imul(ah2, bl3)) | 0; -+ hi = (hi + Math.imul(ah2, bh3)) | 0; -+ lo = (lo + Math.imul(al1, bl4)) | 0; -+ mid = (mid + Math.imul(al1, bh4)) | 0; -+ mid = (mid + Math.imul(ah1, bl4)) | 0; -+ hi = (hi + Math.imul(ah1, bh4)) | 0; -+ lo = (lo + Math.imul(al0, bl5)) | 0; -+ mid = (mid + Math.imul(al0, bh5)) | 0; -+ mid = (mid + Math.imul(ah0, bl5)) | 0; -+ hi = (hi + Math.imul(ah0, bh5)) | 0; -+ var w5 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; -+ c = (((hi + (mid >>> 13)) | 0) + (w5 >>> 26)) | 0; -+ w5 &= 0x3ffffff; -+ /* k = 6 */ -+ lo = Math.imul(al6, bl0); -+ mid = Math.imul(al6, bh0); -+ mid = (mid + Math.imul(ah6, bl0)) | 0; -+ hi = Math.imul(ah6, bh0); -+ lo = (lo + Math.imul(al5, bl1)) | 0; -+ mid = (mid + Math.imul(al5, bh1)) | 0; -+ mid = (mid + Math.imul(ah5, bl1)) | 0; -+ hi = (hi + Math.imul(ah5, bh1)) | 0; -+ lo = (lo + Math.imul(al4, bl2)) | 0; -+ mid = (mid + Math.imul(al4, bh2)) | 0; -+ mid = (mid + Math.imul(ah4, bl2)) | 0; -+ hi = (hi + Math.imul(ah4, bh2)) | 0; -+ lo = (lo + Math.imul(al3, bl3)) | 0; -+ mid = (mid + Math.imul(al3, bh3)) | 0; -+ mid = (mid + Math.imul(ah3, bl3)) | 0; -+ hi = (hi + Math.imul(ah3, bh3)) | 0; -+ lo = (lo + Math.imul(al2, bl4)) | 0; -+ mid = (mid + Math.imul(al2, bh4)) | 0; -+ mid = (mid + Math.imul(ah2, bl4)) | 0; -+ hi = (hi + Math.imul(ah2, bh4)) | 0; -+ lo = (lo + Math.imul(al1, bl5)) | 0; -+ mid = (mid + Math.imul(al1, bh5)) | 0; -+ mid = (mid + Math.imul(ah1, bl5)) | 0; -+ hi = (hi + Math.imul(ah1, bh5)) | 0; -+ lo = (lo + Math.imul(al0, bl6)) | 0; -+ mid = (mid + Math.imul(al0, bh6)) | 0; -+ mid = (mid + Math.imul(ah0, bl6)) | 0; -+ hi = (hi + Math.imul(ah0, bh6)) | 0; -+ var w6 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; -+ c = (((hi + (mid >>> 13)) | 0) + (w6 >>> 26)) | 0; -+ w6 &= 0x3ffffff; -+ /* k = 7 */ -+ lo = Math.imul(al7, bl0); -+ mid = Math.imul(al7, bh0); -+ mid = (mid + Math.imul(ah7, bl0)) | 0; -+ hi = Math.imul(ah7, bh0); -+ lo = (lo + Math.imul(al6, bl1)) | 0; -+ mid = (mid + Math.imul(al6, bh1)) | 0; -+ mid = (mid + Math.imul(ah6, bl1)) | 0; -+ hi = (hi + Math.imul(ah6, bh1)) | 0; -+ lo = (lo + Math.imul(al5, bl2)) | 0; -+ mid = (mid + Math.imul(al5, bh2)) | 0; -+ mid = (mid + Math.imul(ah5, bl2)) | 0; -+ hi = (hi + Math.imul(ah5, bh2)) | 0; -+ lo = (lo + Math.imul(al4, bl3)) | 0; -+ mid = (mid + Math.imul(al4, bh3)) | 0; -+ mid = (mid + Math.imul(ah4, bl3)) | 0; -+ hi = (hi + Math.imul(ah4, bh3)) | 0; -+ lo = (lo + Math.imul(al3, bl4)) | 0; -+ mid = (mid + Math.imul(al3, bh4)) | 0; -+ mid = (mid + Math.imul(ah3, bl4)) | 0; -+ hi = (hi + Math.imul(ah3, bh4)) | 0; -+ lo = (lo + Math.imul(al2, bl5)) | 0; -+ mid = (mid + Math.imul(al2, bh5)) | 0; -+ mid = (mid + Math.imul(ah2, bl5)) | 0; -+ hi = (hi + Math.imul(ah2, bh5)) | 0; -+ lo = (lo + Math.imul(al1, bl6)) | 0; -+ mid = (mid + Math.imul(al1, bh6)) | 0; -+ mid = (mid + Math.imul(ah1, bl6)) | 0; -+ hi = (hi + Math.imul(ah1, bh6)) | 0; -+ lo = (lo + Math.imul(al0, bl7)) | 0; -+ mid = (mid + Math.imul(al0, bh7)) | 0; -+ mid = (mid + Math.imul(ah0, bl7)) | 0; -+ hi = (hi + Math.imul(ah0, bh7)) | 0; -+ var w7 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; -+ c = (((hi + (mid >>> 13)) | 0) + (w7 >>> 26)) | 0; -+ w7 &= 0x3ffffff; -+ /* k = 8 */ -+ lo = Math.imul(al8, bl0); -+ mid = Math.imul(al8, bh0); -+ mid = (mid + Math.imul(ah8, bl0)) | 0; -+ hi = Math.imul(ah8, bh0); -+ lo = (lo + Math.imul(al7, bl1)) | 0; -+ mid = (mid + Math.imul(al7, bh1)) | 0; -+ mid = (mid + Math.imul(ah7, bl1)) | 0; -+ hi = (hi + Math.imul(ah7, bh1)) | 0; -+ lo = (lo + Math.imul(al6, bl2)) | 0; -+ mid = (mid + Math.imul(al6, bh2)) | 0; -+ mid = (mid + Math.imul(ah6, bl2)) | 0; -+ hi = (hi + Math.imul(ah6, bh2)) | 0; -+ lo = (lo + Math.imul(al5, bl3)) | 0; -+ mid = (mid + Math.imul(al5, bh3)) | 0; -+ mid = (mid + Math.imul(ah5, bl3)) | 0; -+ hi = (hi + Math.imul(ah5, bh3)) | 0; -+ lo = (lo + Math.imul(al4, bl4)) | 0; -+ mid = (mid + Math.imul(al4, bh4)) | 0; -+ mid = (mid + Math.imul(ah4, bl4)) | 0; -+ hi = (hi + Math.imul(ah4, bh4)) | 0; -+ lo = (lo + Math.imul(al3, bl5)) | 0; -+ mid = (mid + Math.imul(al3, bh5)) | 0; -+ mid = (mid + Math.imul(ah3, bl5)) | 0; -+ hi = (hi + Math.imul(ah3, bh5)) | 0; -+ lo = (lo + Math.imul(al2, bl6)) | 0; -+ mid = (mid + Math.imul(al2, bh6)) | 0; -+ mid = (mid + Math.imul(ah2, bl6)) | 0; -+ hi = (hi + Math.imul(ah2, bh6)) | 0; -+ lo = (lo + Math.imul(al1, bl7)) | 0; -+ mid = (mid + Math.imul(al1, bh7)) | 0; -+ mid = (mid + Math.imul(ah1, bl7)) | 0; -+ hi = (hi + Math.imul(ah1, bh7)) | 0; -+ lo = (lo + Math.imul(al0, bl8)) | 0; -+ mid = (mid + Math.imul(al0, bh8)) | 0; -+ mid = (mid + Math.imul(ah0, bl8)) | 0; -+ hi = (hi + Math.imul(ah0, bh8)) | 0; -+ var w8 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; -+ c = (((hi + (mid >>> 13)) | 0) + (w8 >>> 26)) | 0; -+ w8 &= 0x3ffffff; -+ /* k = 9 */ -+ lo = Math.imul(al9, bl0); -+ mid = Math.imul(al9, bh0); -+ mid = (mid + Math.imul(ah9, bl0)) | 0; -+ hi = Math.imul(ah9, bh0); -+ lo = (lo + Math.imul(al8, bl1)) | 0; -+ mid = (mid + Math.imul(al8, bh1)) | 0; -+ mid = (mid + Math.imul(ah8, bl1)) | 0; -+ hi = (hi + Math.imul(ah8, bh1)) | 0; -+ lo = (lo + Math.imul(al7, bl2)) | 0; -+ mid = (mid + Math.imul(al7, bh2)) | 0; -+ mid = (mid + Math.imul(ah7, bl2)) | 0; -+ hi = (hi + Math.imul(ah7, bh2)) | 0; -+ lo = (lo + Math.imul(al6, bl3)) | 0; -+ mid = (mid + Math.imul(al6, bh3)) | 0; -+ mid = (mid + Math.imul(ah6, bl3)) | 0; -+ hi = (hi + Math.imul(ah6, bh3)) | 0; -+ lo = (lo + Math.imul(al5, bl4)) | 0; -+ mid = (mid + Math.imul(al5, bh4)) | 0; -+ mid = (mid + Math.imul(ah5, bl4)) | 0; -+ hi = (hi + Math.imul(ah5, bh4)) | 0; -+ lo = (lo + Math.imul(al4, bl5)) | 0; -+ mid = (mid + Math.imul(al4, bh5)) | 0; -+ mid = (mid + Math.imul(ah4, bl5)) | 0; -+ hi = (hi + Math.imul(ah4, bh5)) | 0; -+ lo = (lo + Math.imul(al3, bl6)) | 0; -+ mid = (mid + Math.imul(al3, bh6)) | 0; -+ mid = (mid + Math.imul(ah3, bl6)) | 0; -+ hi = (hi + Math.imul(ah3, bh6)) | 0; -+ lo = (lo + Math.imul(al2, bl7)) | 0; -+ mid = (mid + Math.imul(al2, bh7)) | 0; -+ mid = (mid + Math.imul(ah2, bl7)) | 0; -+ hi = (hi + Math.imul(ah2, bh7)) | 0; -+ lo = (lo + Math.imul(al1, bl8)) | 0; -+ mid = (mid + Math.imul(al1, bh8)) | 0; -+ mid = (mid + Math.imul(ah1, bl8)) | 0; -+ hi = (hi + Math.imul(ah1, bh8)) | 0; -+ lo = (lo + Math.imul(al0, bl9)) | 0; -+ mid = (mid + Math.imul(al0, bh9)) | 0; -+ mid = (mid + Math.imul(ah0, bl9)) | 0; -+ hi = (hi + Math.imul(ah0, bh9)) | 0; -+ var w9 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; -+ c = (((hi + (mid >>> 13)) | 0) + (w9 >>> 26)) | 0; -+ w9 &= 0x3ffffff; -+ /* k = 10 */ -+ lo = Math.imul(al9, bl1); -+ mid = Math.imul(al9, bh1); -+ mid = (mid + Math.imul(ah9, bl1)) | 0; -+ hi = Math.imul(ah9, bh1); -+ lo = (lo + Math.imul(al8, bl2)) | 0; -+ mid = (mid + Math.imul(al8, bh2)) | 0; -+ mid = (mid + Math.imul(ah8, bl2)) | 0; -+ hi = (hi + Math.imul(ah8, bh2)) | 0; -+ lo = (lo + Math.imul(al7, bl3)) | 0; -+ mid = (mid + Math.imul(al7, bh3)) | 0; -+ mid = (mid + Math.imul(ah7, bl3)) | 0; -+ hi = (hi + Math.imul(ah7, bh3)) | 0; -+ lo = (lo + Math.imul(al6, bl4)) | 0; -+ mid = (mid + Math.imul(al6, bh4)) | 0; -+ mid = (mid + Math.imul(ah6, bl4)) | 0; -+ hi = (hi + Math.imul(ah6, bh4)) | 0; -+ lo = (lo + Math.imul(al5, bl5)) | 0; -+ mid = (mid + Math.imul(al5, bh5)) | 0; -+ mid = (mid + Math.imul(ah5, bl5)) | 0; -+ hi = (hi + Math.imul(ah5, bh5)) | 0; -+ lo = (lo + Math.imul(al4, bl6)) | 0; -+ mid = (mid + Math.imul(al4, bh6)) | 0; -+ mid = (mid + Math.imul(ah4, bl6)) | 0; -+ hi = (hi + Math.imul(ah4, bh6)) | 0; -+ lo = (lo + Math.imul(al3, bl7)) | 0; -+ mid = (mid + Math.imul(al3, bh7)) | 0; -+ mid = (mid + Math.imul(ah3, bl7)) | 0; -+ hi = (hi + Math.imul(ah3, bh7)) | 0; -+ lo = (lo + Math.imul(al2, bl8)) | 0; -+ mid = (mid + Math.imul(al2, bh8)) | 0; -+ mid = (mid + Math.imul(ah2, bl8)) | 0; -+ hi = (hi + Math.imul(ah2, bh8)) | 0; -+ lo = (lo + Math.imul(al1, bl9)) | 0; -+ mid = (mid + Math.imul(al1, bh9)) | 0; -+ mid = (mid + Math.imul(ah1, bl9)) | 0; -+ hi = (hi + Math.imul(ah1, bh9)) | 0; -+ var w10 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; -+ c = (((hi + (mid >>> 13)) | 0) + (w10 >>> 26)) | 0; -+ w10 &= 0x3ffffff; -+ /* k = 11 */ -+ lo = Math.imul(al9, bl2); -+ mid = Math.imul(al9, bh2); -+ mid = (mid + Math.imul(ah9, bl2)) | 0; -+ hi = Math.imul(ah9, bh2); -+ lo = (lo + Math.imul(al8, bl3)) | 0; -+ mid = (mid + Math.imul(al8, bh3)) | 0; -+ mid = (mid + Math.imul(ah8, bl3)) | 0; -+ hi = (hi + Math.imul(ah8, bh3)) | 0; -+ lo = (lo + Math.imul(al7, bl4)) | 0; -+ mid = (mid + Math.imul(al7, bh4)) | 0; -+ mid = (mid + Math.imul(ah7, bl4)) | 0; -+ hi = (hi + Math.imul(ah7, bh4)) | 0; -+ lo = (lo + Math.imul(al6, bl5)) | 0; -+ mid = (mid + Math.imul(al6, bh5)) | 0; -+ mid = (mid + Math.imul(ah6, bl5)) | 0; -+ hi = (hi + Math.imul(ah6, bh5)) | 0; -+ lo = (lo + Math.imul(al5, bl6)) | 0; -+ mid = (mid + Math.imul(al5, bh6)) | 0; -+ mid = (mid + Math.imul(ah5, bl6)) | 0; -+ hi = (hi + Math.imul(ah5, bh6)) | 0; -+ lo = (lo + Math.imul(al4, bl7)) | 0; -+ mid = (mid + Math.imul(al4, bh7)) | 0; -+ mid = (mid + Math.imul(ah4, bl7)) | 0; -+ hi = (hi + Math.imul(ah4, bh7)) | 0; -+ lo = (lo + Math.imul(al3, bl8)) | 0; -+ mid = (mid + Math.imul(al3, bh8)) | 0; -+ mid = (mid + Math.imul(ah3, bl8)) | 0; -+ hi = (hi + Math.imul(ah3, bh8)) | 0; -+ lo = (lo + Math.imul(al2, bl9)) | 0; -+ mid = (mid + Math.imul(al2, bh9)) | 0; -+ mid = (mid + Math.imul(ah2, bl9)) | 0; -+ hi = (hi + Math.imul(ah2, bh9)) | 0; -+ var w11 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; -+ c = (((hi + (mid >>> 13)) | 0) + (w11 >>> 26)) | 0; -+ w11 &= 0x3ffffff; -+ /* k = 12 */ -+ lo = Math.imul(al9, bl3); -+ mid = Math.imul(al9, bh3); -+ mid = (mid + Math.imul(ah9, bl3)) | 0; -+ hi = Math.imul(ah9, bh3); -+ lo = (lo + Math.imul(al8, bl4)) | 0; -+ mid = (mid + Math.imul(al8, bh4)) | 0; -+ mid = (mid + Math.imul(ah8, bl4)) | 0; -+ hi = (hi + Math.imul(ah8, bh4)) | 0; -+ lo = (lo + Math.imul(al7, bl5)) | 0; -+ mid = (mid + Math.imul(al7, bh5)) | 0; -+ mid = (mid + Math.imul(ah7, bl5)) | 0; -+ hi = (hi + Math.imul(ah7, bh5)) | 0; -+ lo = (lo + Math.imul(al6, bl6)) | 0; -+ mid = (mid + Math.imul(al6, bh6)) | 0; -+ mid = (mid + Math.imul(ah6, bl6)) | 0; -+ hi = (hi + Math.imul(ah6, bh6)) | 0; -+ lo = (lo + Math.imul(al5, bl7)) | 0; -+ mid = (mid + Math.imul(al5, bh7)) | 0; -+ mid = (mid + Math.imul(ah5, bl7)) | 0; -+ hi = (hi + Math.imul(ah5, bh7)) | 0; -+ lo = (lo + Math.imul(al4, bl8)) | 0; -+ mid = (mid + Math.imul(al4, bh8)) | 0; -+ mid = (mid + Math.imul(ah4, bl8)) | 0; -+ hi = (hi + Math.imul(ah4, bh8)) | 0; -+ lo = (lo + Math.imul(al3, bl9)) | 0; -+ mid = (mid + Math.imul(al3, bh9)) | 0; -+ mid = (mid + Math.imul(ah3, bl9)) | 0; -+ hi = (hi + Math.imul(ah3, bh9)) | 0; -+ var w12 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; -+ c = (((hi + (mid >>> 13)) | 0) + (w12 >>> 26)) | 0; -+ w12 &= 0x3ffffff; -+ /* k = 13 */ -+ lo = Math.imul(al9, bl4); -+ mid = Math.imul(al9, bh4); -+ mid = (mid + Math.imul(ah9, bl4)) | 0; -+ hi = Math.imul(ah9, bh4); -+ lo = (lo + Math.imul(al8, bl5)) | 0; -+ mid = (mid + Math.imul(al8, bh5)) | 0; -+ mid = (mid + Math.imul(ah8, bl5)) | 0; -+ hi = (hi + Math.imul(ah8, bh5)) | 0; -+ lo = (lo + Math.imul(al7, bl6)) | 0; -+ mid = (mid + Math.imul(al7, bh6)) | 0; -+ mid = (mid + Math.imul(ah7, bl6)) | 0; -+ hi = (hi + Math.imul(ah7, bh6)) | 0; -+ lo = (lo + Math.imul(al6, bl7)) | 0; -+ mid = (mid + Math.imul(al6, bh7)) | 0; -+ mid = (mid + Math.imul(ah6, bl7)) | 0; -+ hi = (hi + Math.imul(ah6, bh7)) | 0; -+ lo = (lo + Math.imul(al5, bl8)) | 0; -+ mid = (mid + Math.imul(al5, bh8)) | 0; -+ mid = (mid + Math.imul(ah5, bl8)) | 0; -+ hi = (hi + Math.imul(ah5, bh8)) | 0; -+ lo = (lo + Math.imul(al4, bl9)) | 0; -+ mid = (mid + Math.imul(al4, bh9)) | 0; -+ mid = (mid + Math.imul(ah4, bl9)) | 0; -+ hi = (hi + Math.imul(ah4, bh9)) | 0; -+ var w13 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; -+ c = (((hi + (mid >>> 13)) | 0) + (w13 >>> 26)) | 0; -+ w13 &= 0x3ffffff; -+ /* k = 14 */ -+ lo = Math.imul(al9, bl5); -+ mid = Math.imul(al9, bh5); -+ mid = (mid + Math.imul(ah9, bl5)) | 0; -+ hi = Math.imul(ah9, bh5); -+ lo = (lo + Math.imul(al8, bl6)) | 0; -+ mid = (mid + Math.imul(al8, bh6)) | 0; -+ mid = (mid + Math.imul(ah8, bl6)) | 0; -+ hi = (hi + Math.imul(ah8, bh6)) | 0; -+ lo = (lo + Math.imul(al7, bl7)) | 0; -+ mid = (mid + Math.imul(al7, bh7)) | 0; -+ mid = (mid + Math.imul(ah7, bl7)) | 0; -+ hi = (hi + Math.imul(ah7, bh7)) | 0; -+ lo = (lo + Math.imul(al6, bl8)) | 0; -+ mid = (mid + Math.imul(al6, bh8)) | 0; -+ mid = (mid + Math.imul(ah6, bl8)) | 0; -+ hi = (hi + Math.imul(ah6, bh8)) | 0; -+ lo = (lo + Math.imul(al5, bl9)) | 0; -+ mid = (mid + Math.imul(al5, bh9)) | 0; -+ mid = (mid + Math.imul(ah5, bl9)) | 0; -+ hi = (hi + Math.imul(ah5, bh9)) | 0; -+ var w14 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; -+ c = (((hi + (mid >>> 13)) | 0) + (w14 >>> 26)) | 0; -+ w14 &= 0x3ffffff; -+ /* k = 15 */ -+ lo = Math.imul(al9, bl6); -+ mid = Math.imul(al9, bh6); -+ mid = (mid + Math.imul(ah9, bl6)) | 0; -+ hi = Math.imul(ah9, bh6); -+ lo = (lo + Math.imul(al8, bl7)) | 0; -+ mid = (mid + Math.imul(al8, bh7)) | 0; -+ mid = (mid + Math.imul(ah8, bl7)) | 0; -+ hi = (hi + Math.imul(ah8, bh7)) | 0; -+ lo = (lo + Math.imul(al7, bl8)) | 0; -+ mid = (mid + Math.imul(al7, bh8)) | 0; -+ mid = (mid + Math.imul(ah7, bl8)) | 0; -+ hi = (hi + Math.imul(ah7, bh8)) | 0; -+ lo = (lo + Math.imul(al6, bl9)) | 0; -+ mid = (mid + Math.imul(al6, bh9)) | 0; -+ mid = (mid + Math.imul(ah6, bl9)) | 0; -+ hi = (hi + Math.imul(ah6, bh9)) | 0; -+ var w15 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; -+ c = (((hi + (mid >>> 13)) | 0) + (w15 >>> 26)) | 0; -+ w15 &= 0x3ffffff; -+ /* k = 16 */ -+ lo = Math.imul(al9, bl7); -+ mid = Math.imul(al9, bh7); -+ mid = (mid + Math.imul(ah9, bl7)) | 0; -+ hi = Math.imul(ah9, bh7); -+ lo = (lo + Math.imul(al8, bl8)) | 0; -+ mid = (mid + Math.imul(al8, bh8)) | 0; -+ mid = (mid + Math.imul(ah8, bl8)) | 0; -+ hi = (hi + Math.imul(ah8, bh8)) | 0; -+ lo = (lo + Math.imul(al7, bl9)) | 0; -+ mid = (mid + Math.imul(al7, bh9)) | 0; -+ mid = (mid + Math.imul(ah7, bl9)) | 0; -+ hi = (hi + Math.imul(ah7, bh9)) | 0; -+ var w16 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; -+ c = (((hi + (mid >>> 13)) | 0) + (w16 >>> 26)) | 0; -+ w16 &= 0x3ffffff; -+ /* k = 17 */ -+ lo = Math.imul(al9, bl8); -+ mid = Math.imul(al9, bh8); -+ mid = (mid + Math.imul(ah9, bl8)) | 0; -+ hi = Math.imul(ah9, bh8); -+ lo = (lo + Math.imul(al8, bl9)) | 0; -+ mid = (mid + Math.imul(al8, bh9)) | 0; -+ mid = (mid + Math.imul(ah8, bl9)) | 0; -+ hi = (hi + Math.imul(ah8, bh9)) | 0; -+ var w17 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; -+ c = (((hi + (mid >>> 13)) | 0) + (w17 >>> 26)) | 0; -+ w17 &= 0x3ffffff; -+ /* k = 18 */ -+ lo = Math.imul(al9, bl9); -+ mid = Math.imul(al9, bh9); -+ mid = (mid + Math.imul(ah9, bl9)) | 0; -+ hi = Math.imul(ah9, bh9); -+ var w18 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; -+ c = (((hi + (mid >>> 13)) | 0) + (w18 >>> 26)) | 0; -+ w18 &= 0x3ffffff; -+ o[0] = w0; -+ o[1] = w1; -+ o[2] = w2; -+ o[3] = w3; -+ o[4] = w4; -+ o[5] = w5; -+ o[6] = w6; -+ o[7] = w7; -+ o[8] = w8; -+ o[9] = w9; -+ o[10] = w10; -+ o[11] = w11; -+ o[12] = w12; -+ o[13] = w13; -+ o[14] = w14; -+ o[15] = w15; -+ o[16] = w16; -+ o[17] = w17; -+ o[18] = w18; -+ if (c !== 0) { -+ o[19] = c; -+ out.length++; -+ } -+ return out; -+ }; -+ -+ // Polyfill comb -+ if (!Math.imul) { -+ comb10MulTo = smallMulTo; -+ } -+ -+ function bigMulTo (self, num, out) { -+ out.negative = num.negative ^ self.negative; -+ out.length = self.length + num.length; -+ -+ var carry = 0; -+ var hncarry = 0; -+ for (var k = 0; k < out.length - 1; k++) { -+ // Sum all words with the same `i + j = k` and accumulate `ncarry`, -+ // note that ncarry could be >= 0x3ffffff -+ var ncarry = hncarry; -+ hncarry = 0; -+ var rword = carry & 0x3ffffff; -+ var maxJ = Math.min(k, num.length - 1); -+ for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) { -+ var i = k - j; -+ var a = self.words[i] | 0; -+ var b = num.words[j] | 0; -+ var r = a * b; -+ -+ var lo = r & 0x3ffffff; -+ ncarry = (ncarry + ((r / 0x4000000) | 0)) | 0; -+ lo = (lo + rword) | 0; -+ rword = lo & 0x3ffffff; -+ ncarry = (ncarry + (lo >>> 26)) | 0; -+ -+ hncarry += ncarry >>> 26; -+ ncarry &= 0x3ffffff; -+ } -+ out.words[k] = rword; -+ carry = ncarry; -+ ncarry = hncarry; -+ } -+ if (carry !== 0) { -+ out.words[k] = carry; -+ } else { -+ out.length--; -+ } -+ -+ return out.strip(); -+ } -+ -+ function jumboMulTo (self, num, out) { -+ var fftm = new FFTM(); -+ return fftm.mulp(self, num, out); -+ } -+ -+ BN.prototype.mulTo = function mulTo (num, out) { -+ var res; -+ var len = this.length + num.length; -+ if (this.length === 10 && num.length === 10) { -+ res = comb10MulTo(this, num, out); -+ } else if (len < 63) { -+ res = smallMulTo(this, num, out); -+ } else if (len < 1024) { -+ res = bigMulTo(this, num, out); -+ } else { -+ res = jumboMulTo(this, num, out); -+ } -+ -+ return res; -+ }; -+ -+ // Cooley-Tukey algorithm for FFT -+ // slightly revisited to rely on looping instead of recursion -+ -+ function FFTM (x, y) { -+ this.x = x; -+ this.y = y; -+ } -+ -+ FFTM.prototype.makeRBT = function makeRBT (N) { -+ var t = new Array(N); -+ var l = BN.prototype._countBits(N) - 1; -+ for (var i = 0; i < N; i++) { -+ t[i] = this.revBin(i, l, N); -+ } -+ -+ return t; -+ }; -+ -+ // Returns binary-reversed representation of `x` -+ FFTM.prototype.revBin = function revBin (x, l, N) { -+ if (x === 0 || x === N - 1) return x; -+ -+ var rb = 0; -+ for (var i = 0; i < l; i++) { -+ rb |= (x & 1) << (l - i - 1); -+ x >>= 1; -+ } -+ -+ return rb; -+ }; -+ -+ // Performs "tweedling" phase, therefore 'emulating' -+ // behaviour of the recursive algorithm -+ FFTM.prototype.permute = function permute (rbt, rws, iws, rtws, itws, N) { -+ for (var i = 0; i < N; i++) { -+ rtws[i] = rws[rbt[i]]; -+ itws[i] = iws[rbt[i]]; -+ } -+ }; -+ -+ FFTM.prototype.transform = function transform (rws, iws, rtws, itws, N, rbt) { -+ this.permute(rbt, rws, iws, rtws, itws, N); -+ -+ for (var s = 1; s < N; s <<= 1) { -+ var l = s << 1; -+ -+ var rtwdf = Math.cos(2 * Math.PI / l); -+ var itwdf = Math.sin(2 * Math.PI / l); -+ -+ for (var p = 0; p < N; p += l) { -+ var rtwdf_ = rtwdf; -+ var itwdf_ = itwdf; -+ -+ for (var j = 0; j < s; j++) { -+ var re = rtws[p + j]; -+ var ie = itws[p + j]; -+ -+ var ro = rtws[p + j + s]; -+ var io = itws[p + j + s]; -+ -+ var rx = rtwdf_ * ro - itwdf_ * io; -+ -+ io = rtwdf_ * io + itwdf_ * ro; -+ ro = rx; -+ -+ rtws[p + j] = re + ro; -+ itws[p + j] = ie + io; -+ -+ rtws[p + j + s] = re - ro; -+ itws[p + j + s] = ie - io; -+ -+ /* jshint maxdepth : false */ -+ if (j !== l) { -+ rx = rtwdf * rtwdf_ - itwdf * itwdf_; -+ -+ itwdf_ = rtwdf * itwdf_ + itwdf * rtwdf_; -+ rtwdf_ = rx; -+ } -+ } -+ } -+ } -+ }; -+ -+ FFTM.prototype.guessLen13b = function guessLen13b (n, m) { -+ var N = Math.max(m, n) | 1; -+ var odd = N & 1; -+ var i = 0; -+ for (N = N / 2 | 0; N; N = N >>> 1) { -+ i++; -+ } -+ -+ return 1 << i + 1 + odd; -+ }; -+ -+ FFTM.prototype.conjugate = function conjugate (rws, iws, N) { -+ if (N <= 1) return; -+ -+ for (var i = 0; i < N / 2; i++) { -+ var t = rws[i]; -+ -+ rws[i] = rws[N - i - 1]; -+ rws[N - i - 1] = t; -+ -+ t = iws[i]; -+ -+ iws[i] = -iws[N - i - 1]; -+ iws[N - i - 1] = -t; -+ } -+ }; -+ -+ FFTM.prototype.normalize13b = function normalize13b (ws, N) { -+ var carry = 0; -+ for (var i = 0; i < N / 2; i++) { -+ var w = Math.round(ws[2 * i + 1] / N) * 0x2000 + -+ Math.round(ws[2 * i] / N) + -+ carry; -+ -+ ws[i] = w & 0x3ffffff; -+ -+ if (w < 0x4000000) { -+ carry = 0; -+ } else { -+ carry = w / 0x4000000 | 0; -+ } -+ } -+ -+ return ws; -+ }; -+ -+ FFTM.prototype.convert13b = function convert13b (ws, len, rws, N) { -+ var carry = 0; -+ for (var i = 0; i < len; i++) { -+ carry = carry + (ws[i] | 0); -+ -+ rws[2 * i] = carry & 0x1fff; carry = carry >>> 13; -+ rws[2 * i + 1] = carry & 0x1fff; carry = carry >>> 13; -+ } -+ -+ // Pad with zeroes -+ for (i = 2 * len; i < N; ++i) { -+ rws[i] = 0; -+ } -+ -+ assert(carry === 0); -+ assert((carry & ~0x1fff) === 0); -+ }; -+ -+ FFTM.prototype.stub = function stub (N) { -+ var ph = new Array(N); -+ for (var i = 0; i < N; i++) { -+ ph[i] = 0; -+ } -+ -+ return ph; -+ }; -+ -+ FFTM.prototype.mulp = function mulp (x, y, out) { -+ var N = 2 * this.guessLen13b(x.length, y.length); -+ -+ var rbt = this.makeRBT(N); -+ -+ var _ = this.stub(N); -+ -+ var rws = new Array(N); -+ var rwst = new Array(N); -+ var iwst = new Array(N); -+ -+ var nrws = new Array(N); -+ var nrwst = new Array(N); -+ var niwst = new Array(N); -+ -+ var rmws = out.words; -+ rmws.length = N; -+ -+ this.convert13b(x.words, x.length, rws, N); -+ this.convert13b(y.words, y.length, nrws, N); -+ -+ this.transform(rws, _, rwst, iwst, N, rbt); -+ this.transform(nrws, _, nrwst, niwst, N, rbt); -+ -+ for (var i = 0; i < N; i++) { -+ var rx = rwst[i] * nrwst[i] - iwst[i] * niwst[i]; -+ iwst[i] = rwst[i] * niwst[i] + iwst[i] * nrwst[i]; -+ rwst[i] = rx; -+ } -+ -+ this.conjugate(rwst, iwst, N); -+ this.transform(rwst, iwst, rmws, _, N, rbt); -+ this.conjugate(rmws, _, N); -+ this.normalize13b(rmws, N); -+ -+ out.negative = x.negative ^ y.negative; -+ out.length = x.length + y.length; -+ return out.strip(); -+ }; -+ -+ // Multiply `this` by `num` -+ BN.prototype.mul = function mul (num) { -+ var out = new BN(null); -+ out.words = new Array(this.length + num.length); -+ return this.mulTo(num, out); -+ }; -+ -+ // Multiply employing FFT -+ BN.prototype.mulf = function mulf (num) { -+ var out = new BN(null); -+ out.words = new Array(this.length + num.length); -+ return jumboMulTo(this, num, out); -+ }; -+ -+ // In-place Multiplication -+ BN.prototype.imul = function imul (num) { -+ return this.clone().mulTo(num, this); -+ }; -+ -+ BN.prototype.imuln = function imuln (num) { -+ assert(typeof num === 'number'); -+ assert(num < 0x4000000); -+ -+ // Carry -+ var carry = 0; -+ for (var i = 0; i < this.length; i++) { -+ var w = (this.words[i] | 0) * num; -+ var lo = (w & 0x3ffffff) + (carry & 0x3ffffff); -+ carry >>= 26; -+ carry += (w / 0x4000000) | 0; -+ // NOTE: lo is 27bit maximum -+ carry += lo >>> 26; -+ this.words[i] = lo & 0x3ffffff; -+ } -+ -+ if (carry !== 0) { -+ this.words[i] = carry; -+ this.length++; -+ } -+ -+ return this; -+ }; -+ -+ BN.prototype.muln = function muln (num) { -+ return this.clone().imuln(num); -+ }; -+ -+ // `this` * `this` -+ BN.prototype.sqr = function sqr () { -+ return this.mul(this); -+ }; -+ -+ // `this` * `this` in-place -+ BN.prototype.isqr = function isqr () { -+ return this.imul(this.clone()); -+ }; -+ -+ // Math.pow(`this`, `num`) -+ BN.prototype.pow = function pow (num) { -+ var w = toBitArray(num); -+ if (w.length === 0) return new BN(1); -+ -+ // Skip leading zeroes -+ var res = this; -+ for (var i = 0; i < w.length; i++, res = res.sqr()) { -+ if (w[i] !== 0) break; -+ } -+ -+ if (++i < w.length) { -+ for (var q = res.sqr(); i < w.length; i++, q = q.sqr()) { -+ if (w[i] === 0) continue; -+ -+ res = res.mul(q); -+ } -+ } -+ -+ return res; -+ }; -+ -+ // Shift-left in-place -+ BN.prototype.iushln = function iushln (bits) { -+ assert(typeof bits === 'number' && bits >= 0); -+ var r = bits % 26; -+ var s = (bits - r) / 26; -+ var carryMask = (0x3ffffff >>> (26 - r)) << (26 - r); -+ var i; -+ -+ if (r !== 0) { -+ var carry = 0; -+ -+ for (i = 0; i < this.length; i++) { -+ var newCarry = this.words[i] & carryMask; -+ var c = ((this.words[i] | 0) - newCarry) << r; -+ this.words[i] = c | carry; -+ carry = newCarry >>> (26 - r); -+ } -+ -+ if (carry) { -+ this.words[i] = carry; -+ this.length++; -+ } -+ } -+ -+ if (s !== 0) { -+ for (i = this.length - 1; i >= 0; i--) { -+ this.words[i + s] = this.words[i]; -+ } -+ -+ for (i = 0; i < s; i++) { -+ this.words[i] = 0; -+ } -+ -+ this.length += s; -+ } -+ -+ return this.strip(); -+ }; -+ -+ BN.prototype.ishln = function ishln (bits) { -+ // TODO(indutny): implement me -+ assert(this.negative === 0); -+ return this.iushln(bits); -+ }; -+ -+ // Shift-right in-place -+ // NOTE: `hint` is a lowest bit before trailing zeroes -+ // NOTE: if `extended` is present - it will be filled with destroyed bits -+ BN.prototype.iushrn = function iushrn (bits, hint, extended) { -+ assert(typeof bits === 'number' && bits >= 0); -+ var h; -+ if (hint) { -+ h = (hint - (hint % 26)) / 26; -+ } else { -+ h = 0; -+ } -+ -+ var r = bits % 26; -+ var s = Math.min((bits - r) / 26, this.length); -+ var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r); -+ var maskedWords = extended; -+ -+ h -= s; -+ h = Math.max(0, h); -+ -+ // Extended mode, copy masked part -+ if (maskedWords) { -+ for (var i = 0; i < s; i++) { -+ maskedWords.words[i] = this.words[i]; -+ } -+ maskedWords.length = s; -+ } -+ -+ if (s === 0) { -+ // No-op, we should not move anything at all -+ } else if (this.length > s) { -+ this.length -= s; -+ for (i = 0; i < this.length; i++) { -+ this.words[i] = this.words[i + s]; -+ } -+ } else { -+ this.words[0] = 0; -+ this.length = 1; -+ } -+ -+ var carry = 0; -+ for (i = this.length - 1; i >= 0 && (carry !== 0 || i >= h); i--) { -+ var word = this.words[i] | 0; -+ this.words[i] = (carry << (26 - r)) | (word >>> r); -+ carry = word & mask; -+ } -+ -+ // Push carried bits as a mask -+ if (maskedWords && carry !== 0) { -+ maskedWords.words[maskedWords.length++] = carry; -+ } -+ -+ if (this.length === 0) { -+ this.words[0] = 0; -+ this.length = 1; -+ } -+ -+ return this.strip(); -+ }; -+ -+ BN.prototype.ishrn = function ishrn (bits, hint, extended) { -+ // TODO(indutny): implement me -+ assert(this.negative === 0); -+ return this.iushrn(bits, hint, extended); -+ }; -+ -+ // Shift-left -+ BN.prototype.shln = function shln (bits) { -+ return this.clone().ishln(bits); -+ }; -+ -+ BN.prototype.ushln = function ushln (bits) { -+ return this.clone().iushln(bits); -+ }; -+ -+ // Shift-right -+ BN.prototype.shrn = function shrn (bits) { -+ return this.clone().ishrn(bits); -+ }; -+ -+ BN.prototype.ushrn = function ushrn (bits) { -+ return this.clone().iushrn(bits); -+ }; -+ -+ // Test if n bit is set -+ BN.prototype.testn = function testn (bit) { -+ assert(typeof bit === 'number' && bit >= 0); -+ var r = bit % 26; -+ var s = (bit - r) / 26; -+ var q = 1 << r; -+ -+ // Fast case: bit is much higher than all existing words -+ if (this.length <= s) return false; -+ -+ // Check bit and return -+ var w = this.words[s]; -+ -+ return !!(w & q); -+ }; -+ -+ // Return only lowers bits of number (in-place) -+ BN.prototype.imaskn = function imaskn (bits) { -+ assert(typeof bits === 'number' && bits >= 0); -+ var r = bits % 26; -+ var s = (bits - r) / 26; -+ -+ assert(this.negative === 0, 'imaskn works only with positive numbers'); -+ -+ if (this.length <= s) { -+ return this; -+ } -+ -+ if (r !== 0) { -+ s++; -+ } -+ this.length = Math.min(s, this.length); -+ -+ if (r !== 0) { -+ var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r); -+ this.words[this.length - 1] &= mask; -+ } -+ -+ return this.strip(); -+ }; -+ -+ // Return only lowers bits of number -+ BN.prototype.maskn = function maskn (bits) { -+ return this.clone().imaskn(bits); -+ }; -+ -+ // Add plain number `num` to `this` -+ BN.prototype.iaddn = function iaddn (num) { -+ assert(typeof num === 'number'); -+ assert(num < 0x4000000); -+ if (num < 0) return this.isubn(-num); -+ -+ // Possible sign change -+ if (this.negative !== 0) { -+ if (this.length === 1 && (this.words[0] | 0) < num) { -+ this.words[0] = num - (this.words[0] | 0); -+ this.negative = 0; -+ return this; -+ } -+ -+ this.negative = 0; -+ this.isubn(num); -+ this.negative = 1; -+ return this; -+ } -+ -+ // Add without checks -+ return this._iaddn(num); -+ }; -+ -+ BN.prototype._iaddn = function _iaddn (num) { -+ this.words[0] += num; -+ -+ // Carry -+ for (var i = 0; i < this.length && this.words[i] >= 0x4000000; i++) { -+ this.words[i] -= 0x4000000; -+ if (i === this.length - 1) { -+ this.words[i + 1] = 1; -+ } else { -+ this.words[i + 1]++; -+ } -+ } -+ this.length = Math.max(this.length, i + 1); -+ -+ return this; -+ }; -+ -+ // Subtract plain number `num` from `this` -+ BN.prototype.isubn = function isubn (num) { -+ assert(typeof num === 'number'); -+ assert(num < 0x4000000); -+ if (num < 0) return this.iaddn(-num); -+ -+ if (this.negative !== 0) { -+ this.negative = 0; -+ this.iaddn(num); -+ this.negative = 1; -+ return this; -+ } -+ -+ this.words[0] -= num; -+ -+ if (this.length === 1 && this.words[0] < 0) { -+ this.words[0] = -this.words[0]; -+ this.negative = 1; -+ } else { -+ // Carry -+ for (var i = 0; i < this.length && this.words[i] < 0; i++) { -+ this.words[i] += 0x4000000; -+ this.words[i + 1] -= 1; -+ } -+ } -+ -+ return this.strip(); -+ }; -+ -+ BN.prototype.addn = function addn (num) { -+ return this.clone().iaddn(num); -+ }; -+ -+ BN.prototype.subn = function subn (num) { -+ return this.clone().isubn(num); -+ }; -+ -+ BN.prototype.iabs = function iabs () { -+ this.negative = 0; -+ -+ return this; -+ }; -+ -+ BN.prototype.abs = function abs () { -+ return this.clone().iabs(); -+ }; -+ -+ BN.prototype._ishlnsubmul = function _ishlnsubmul (num, mul, shift) { -+ var len = num.length + shift; -+ var i; -+ -+ this._expand(len); -+ -+ var w; -+ var carry = 0; -+ for (i = 0; i < num.length; i++) { -+ w = (this.words[i + shift] | 0) + carry; -+ var right = (num.words[i] | 0) * mul; -+ w -= right & 0x3ffffff; -+ carry = (w >> 26) - ((right / 0x4000000) | 0); -+ this.words[i + shift] = w & 0x3ffffff; -+ } -+ for (; i < this.length - shift; i++) { -+ w = (this.words[i + shift] | 0) + carry; -+ carry = w >> 26; -+ this.words[i + shift] = w & 0x3ffffff; -+ } -+ -+ if (carry === 0) return this.strip(); -+ -+ // Subtraction overflow -+ assert(carry === -1); -+ carry = 0; -+ for (i = 0; i < this.length; i++) { -+ w = -(this.words[i] | 0) + carry; -+ carry = w >> 26; -+ this.words[i] = w & 0x3ffffff; -+ } -+ this.negative = 1; -+ -+ return this.strip(); -+ }; -+ -+ BN.prototype._wordDiv = function _wordDiv (num, mode) { -+ var shift = this.length - num.length; -+ -+ var a = this.clone(); -+ var b = num; -+ -+ // Normalize -+ var bhi = b.words[b.length - 1] | 0; -+ var bhiBits = this._countBits(bhi); -+ shift = 26 - bhiBits; -+ if (shift !== 0) { -+ b = b.ushln(shift); -+ a.iushln(shift); -+ bhi = b.words[b.length - 1] | 0; -+ } -+ -+ // Initialize quotient -+ var m = a.length - b.length; -+ var q; -+ -+ if (mode !== 'mod') { -+ q = new BN(null); -+ q.length = m + 1; -+ q.words = new Array(q.length); -+ for (var i = 0; i < q.length; i++) { -+ q.words[i] = 0; -+ } -+ } -+ -+ var diff = a.clone()._ishlnsubmul(b, 1, m); -+ if (diff.negative === 0) { -+ a = diff; -+ if (q) { -+ q.words[m] = 1; -+ } -+ } -+ -+ for (var j = m - 1; j >= 0; j--) { -+ var qj = (a.words[b.length + j] | 0) * 0x4000000 + -+ (a.words[b.length + j - 1] | 0); -+ -+ // NOTE: (qj / bhi) is (0x3ffffff * 0x4000000 + 0x3ffffff) / 0x2000000 max -+ // (0x7ffffff) -+ qj = Math.min((qj / bhi) | 0, 0x3ffffff); -+ -+ a._ishlnsubmul(b, qj, j); -+ while (a.negative !== 0) { -+ qj--; -+ a.negative = 0; -+ a._ishlnsubmul(b, 1, j); -+ if (!a.isZero()) { -+ a.negative ^= 1; -+ } -+ } -+ if (q) { -+ q.words[j] = qj; -+ } -+ } -+ if (q) { -+ q.strip(); -+ } -+ a.strip(); -+ -+ // Denormalize -+ if (mode !== 'div' && shift !== 0) { -+ a.iushrn(shift); -+ } -+ -+ return { -+ div: q || null, -+ mod: a -+ }; -+ }; -+ -+ // NOTE: 1) `mode` can be set to `mod` to request mod only, -+ // to `div` to request div only, or be absent to -+ // request both div & mod -+ // 2) `positive` is true if unsigned mod is requested -+ BN.prototype.divmod = function divmod (num, mode, positive) { -+ assert(!num.isZero()); -+ -+ if (this.isZero()) { -+ return { -+ div: new BN(0), -+ mod: new BN(0) -+ }; -+ } -+ -+ var div, mod, res; -+ if (this.negative !== 0 && num.negative === 0) { -+ res = this.neg().divmod(num, mode); -+ -+ if (mode !== 'mod') { -+ div = res.div.neg(); -+ } -+ -+ if (mode !== 'div') { -+ mod = res.mod.neg(); -+ if (positive && mod.negative !== 0) { -+ mod.iadd(num); -+ } -+ } -+ -+ return { -+ div: div, -+ mod: mod -+ }; -+ } -+ -+ if (this.negative === 0 && num.negative !== 0) { -+ res = this.divmod(num.neg(), mode); -+ -+ if (mode !== 'mod') { -+ div = res.div.neg(); -+ } -+ -+ return { -+ div: div, -+ mod: res.mod -+ }; -+ } -+ -+ if ((this.negative & num.negative) !== 0) { -+ res = this.neg().divmod(num.neg(), mode); -+ -+ if (mode !== 'div') { -+ mod = res.mod.neg(); -+ if (positive && mod.negative !== 0) { -+ mod.isub(num); -+ } -+ } -+ -+ return { -+ div: res.div, -+ mod: mod -+ }; -+ } -+ -+ // Both numbers are positive at this point -+ -+ // Strip both numbers to approximate shift value -+ if (num.length > this.length || this.cmp(num) < 0) { -+ return { -+ div: new BN(0), -+ mod: this -+ }; -+ } -+ -+ // Very short reduction -+ if (num.length === 1) { -+ if (mode === 'div') { -+ return { -+ div: this.divn(num.words[0]), -+ mod: null -+ }; -+ } -+ -+ if (mode === 'mod') { -+ return { -+ div: null, -+ mod: new BN(this.modn(num.words[0])) -+ }; -+ } -+ -+ return { -+ div: this.divn(num.words[0]), -+ mod: new BN(this.modn(num.words[0])) -+ }; -+ } -+ -+ return this._wordDiv(num, mode); -+ }; -+ -+ // Find `this` / `num` -+ BN.prototype.div = function div (num) { -+ return this.divmod(num, 'div', false).div; -+ }; -+ -+ // Find `this` % `num` -+ BN.prototype.mod = function mod (num) { -+ return this.divmod(num, 'mod', false).mod; -+ }; -+ -+ BN.prototype.umod = function umod (num) { -+ return this.divmod(num, 'mod', true).mod; -+ }; -+ -+ // Find Round(`this` / `num`) -+ BN.prototype.divRound = function divRound (num) { -+ var dm = this.divmod(num); -+ -+ // Fast case - exact division -+ if (dm.mod.isZero()) return dm.div; -+ -+ var mod = dm.div.negative !== 0 ? dm.mod.isub(num) : dm.mod; -+ -+ var half = num.ushrn(1); -+ var r2 = num.andln(1); -+ var cmp = mod.cmp(half); -+ -+ // Round down -+ if (cmp < 0 || r2 === 1 && cmp === 0) return dm.div; -+ -+ // Round up -+ return dm.div.negative !== 0 ? dm.div.isubn(1) : dm.div.iaddn(1); -+ }; -+ -+ BN.prototype.modn = function modn (num) { -+ assert(num <= 0x3ffffff); -+ var p = (1 << 26) % num; -+ -+ var acc = 0; -+ for (var i = this.length - 1; i >= 0; i--) { -+ acc = (p * acc + (this.words[i] | 0)) % num; -+ } -+ -+ return acc; -+ }; -+ -+ // In-place division by number -+ BN.prototype.idivn = function idivn (num) { -+ assert(num <= 0x3ffffff); -+ -+ var carry = 0; -+ for (var i = this.length - 1; i >= 0; i--) { -+ var w = (this.words[i] | 0) + carry * 0x4000000; -+ this.words[i] = (w / num) | 0; -+ carry = w % num; -+ } -+ -+ return this.strip(); -+ }; -+ -+ BN.prototype.divn = function divn (num) { -+ return this.clone().idivn(num); -+ }; -+ -+ BN.prototype.egcd = function egcd (p) { -+ assert(p.negative === 0); -+ assert(!p.isZero()); -+ -+ var x = this; -+ var y = p.clone(); -+ -+ if (x.negative !== 0) { -+ x = x.umod(p); -+ } else { -+ x = x.clone(); -+ } -+ -+ // A * x + B * y = x -+ var A = new BN(1); -+ var B = new BN(0); -+ -+ // C * x + D * y = y -+ var C = new BN(0); -+ var D = new BN(1); -+ -+ var g = 0; -+ -+ while (x.isEven() && y.isEven()) { -+ x.iushrn(1); -+ y.iushrn(1); -+ ++g; -+ } -+ -+ var yp = y.clone(); -+ var xp = x.clone(); -+ -+ while (!x.isZero()) { -+ for (var i = 0, im = 1; (x.words[0] & im) === 0 && i < 26; ++i, im <<= 1); -+ if (i > 0) { -+ x.iushrn(i); -+ while (i-- > 0) { -+ if (A.isOdd() || B.isOdd()) { -+ A.iadd(yp); -+ B.isub(xp); -+ } -+ -+ A.iushrn(1); -+ B.iushrn(1); -+ } -+ } -+ -+ for (var j = 0, jm = 1; (y.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1); -+ if (j > 0) { -+ y.iushrn(j); -+ while (j-- > 0) { -+ if (C.isOdd() || D.isOdd()) { -+ C.iadd(yp); -+ D.isub(xp); -+ } -+ -+ C.iushrn(1); -+ D.iushrn(1); -+ } -+ } -+ -+ if (x.cmp(y) >= 0) { -+ x.isub(y); -+ A.isub(C); -+ B.isub(D); -+ } else { -+ y.isub(x); -+ C.isub(A); -+ D.isub(B); -+ } -+ } -+ -+ return { -+ a: C, -+ b: D, -+ gcd: y.iushln(g) -+ }; -+ }; -+ -+ // This is reduced incarnation of the binary EEA -+ // above, designated to invert members of the -+ // _prime_ fields F(p) at a maximal speed -+ BN.prototype._invmp = function _invmp (p) { -+ assert(p.negative === 0); -+ assert(!p.isZero()); -+ -+ var a = this; -+ var b = p.clone(); -+ -+ if (a.negative !== 0) { -+ a = a.umod(p); -+ } else { -+ a = a.clone(); -+ } -+ -+ var x1 = new BN(1); -+ var x2 = new BN(0); -+ -+ var delta = b.clone(); -+ -+ while (a.cmpn(1) > 0 && b.cmpn(1) > 0) { -+ for (var i = 0, im = 1; (a.words[0] & im) === 0 && i < 26; ++i, im <<= 1); -+ if (i > 0) { -+ a.iushrn(i); -+ while (i-- > 0) { -+ if (x1.isOdd()) { -+ x1.iadd(delta); -+ } -+ -+ x1.iushrn(1); -+ } -+ } -+ -+ for (var j = 0, jm = 1; (b.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1); -+ if (j > 0) { -+ b.iushrn(j); -+ while (j-- > 0) { -+ if (x2.isOdd()) { -+ x2.iadd(delta); -+ } -+ -+ x2.iushrn(1); -+ } -+ } -+ -+ if (a.cmp(b) >= 0) { -+ a.isub(b); -+ x1.isub(x2); -+ } else { -+ b.isub(a); -+ x2.isub(x1); -+ } -+ } -+ -+ var res; -+ if (a.cmpn(1) === 0) { -+ res = x1; -+ } else { -+ res = x2; -+ } -+ -+ if (res.cmpn(0) < 0) { -+ res.iadd(p); -+ } -+ -+ return res; -+ }; -+ -+ BN.prototype.gcd = function gcd (num) { -+ if (this.isZero()) return num.abs(); -+ if (num.isZero()) return this.abs(); -+ -+ var a = this.clone(); -+ var b = num.clone(); -+ a.negative = 0; -+ b.negative = 0; -+ -+ // Remove common factor of two -+ for (var shift = 0; a.isEven() && b.isEven(); shift++) { -+ a.iushrn(1); -+ b.iushrn(1); -+ } -+ -+ do { -+ while (a.isEven()) { -+ a.iushrn(1); -+ } -+ while (b.isEven()) { -+ b.iushrn(1); -+ } -+ -+ var r = a.cmp(b); -+ if (r < 0) { -+ // Swap `a` and `b` to make `a` always bigger than `b` -+ var t = a; -+ a = b; -+ b = t; -+ } else if (r === 0 || b.cmpn(1) === 0) { -+ break; -+ } -+ -+ a.isub(b); -+ } while (true); -+ -+ return b.iushln(shift); -+ }; -+ -+ // Invert number in the field F(num) -+ BN.prototype.invm = function invm (num) { -+ return this.egcd(num).a.umod(num); -+ }; -+ -+ BN.prototype.isEven = function isEven () { -+ return (this.words[0] & 1) === 0; -+ }; -+ -+ BN.prototype.isOdd = function isOdd () { -+ return (this.words[0] & 1) === 1; -+ }; -+ -+ // And first word and num -+ BN.prototype.andln = function andln (num) { -+ return this.words[0] & num; -+ }; -+ -+ // Increment at the bit position in-line -+ BN.prototype.bincn = function bincn (bit) { -+ assert(typeof bit === 'number'); -+ var r = bit % 26; -+ var s = (bit - r) / 26; -+ var q = 1 << r; -+ -+ // Fast case: bit is much higher than all existing words -+ if (this.length <= s) { -+ this._expand(s + 1); -+ this.words[s] |= q; -+ return this; -+ } -+ -+ // Add bit and propagate, if needed -+ var carry = q; -+ for (var i = s; carry !== 0 && i < this.length; i++) { -+ var w = this.words[i] | 0; -+ w += carry; -+ carry = w >>> 26; -+ w &= 0x3ffffff; -+ this.words[i] = w; -+ } -+ if (carry !== 0) { -+ this.words[i] = carry; -+ this.length++; -+ } -+ return this; -+ }; -+ -+ BN.prototype.isZero = function isZero () { -+ return this.length === 1 && this.words[0] === 0; -+ }; -+ -+ BN.prototype.cmpn = function cmpn (num) { -+ var negative = num < 0; -+ -+ if (this.negative !== 0 && !negative) return -1; -+ if (this.negative === 0 && negative) return 1; -+ -+ this.strip(); -+ -+ var res; -+ if (this.length > 1) { -+ res = 1; -+ } else { -+ if (negative) { -+ num = -num; -+ } -+ -+ assert(num <= 0x3ffffff, 'Number is too big'); -+ -+ var w = this.words[0] | 0; -+ res = w === num ? 0 : w < num ? -1 : 1; -+ } -+ if (this.negative !== 0) return -res | 0; -+ return res; -+ }; -+ -+ // Compare two numbers and return: -+ // 1 - if `this` > `num` -+ // 0 - if `this` == `num` -+ // -1 - if `this` < `num` -+ BN.prototype.cmp = function cmp (num) { -+ if (this.negative !== 0 && num.negative === 0) return -1; -+ if (this.negative === 0 && num.negative !== 0) return 1; -+ -+ var res = this.ucmp(num); -+ if (this.negative !== 0) return -res | 0; -+ return res; -+ }; -+ -+ // Unsigned comparison -+ BN.prototype.ucmp = function ucmp (num) { -+ // At this point both numbers have the same sign -+ if (this.length > num.length) return 1; -+ if (this.length < num.length) return -1; -+ -+ var res = 0; -+ for (var i = this.length - 1; i >= 0; i--) { -+ var a = this.words[i] | 0; -+ var b = num.words[i] | 0; -+ -+ if (a === b) continue; -+ if (a < b) { -+ res = -1; -+ } else if (a > b) { -+ res = 1; -+ } -+ break; -+ } -+ return res; -+ }; -+ -+ BN.prototype.gtn = function gtn (num) { -+ return this.cmpn(num) === 1; -+ }; -+ -+ BN.prototype.gt = function gt (num) { -+ return this.cmp(num) === 1; -+ }; -+ -+ BN.prototype.gten = function gten (num) { -+ return this.cmpn(num) >= 0; -+ }; -+ -+ BN.prototype.gte = function gte (num) { -+ return this.cmp(num) >= 0; -+ }; -+ -+ BN.prototype.ltn = function ltn (num) { -+ return this.cmpn(num) === -1; -+ }; -+ -+ BN.prototype.lt = function lt (num) { -+ return this.cmp(num) === -1; -+ }; -+ -+ BN.prototype.lten = function lten (num) { -+ return this.cmpn(num) <= 0; -+ }; -+ -+ BN.prototype.lte = function lte (num) { -+ return this.cmp(num) <= 0; -+ }; -+ -+ BN.prototype.eqn = function eqn (num) { -+ return this.cmpn(num) === 0; -+ }; -+ -+ BN.prototype.eq = function eq (num) { -+ return this.cmp(num) === 0; -+ }; -+ -+ // -+ // A reduce context, could be using montgomery or something better, depending -+ // on the `m` itself. -+ // -+ BN.red = function red (num) { -+ return new Red(num); -+ }; -+ -+ BN.prototype.toRed = function toRed (ctx) { -+ assert(!this.red, 'Already a number in reduction context'); -+ assert(this.negative === 0, 'red works only with positives'); -+ return ctx.convertTo(this)._forceRed(ctx); -+ }; -+ -+ BN.prototype.fromRed = function fromRed () { -+ assert(this.red, 'fromRed works only with numbers in reduction context'); -+ return this.red.convertFrom(this); -+ }; -+ -+ BN.prototype._forceRed = function _forceRed (ctx) { -+ this.red = ctx; -+ return this; -+ }; -+ -+ BN.prototype.forceRed = function forceRed (ctx) { -+ assert(!this.red, 'Already a number in reduction context'); -+ return this._forceRed(ctx); -+ }; -+ -+ BN.prototype.redAdd = function redAdd (num) { -+ assert(this.red, 'redAdd works only with red numbers'); -+ return this.red.add(this, num); -+ }; -+ -+ BN.prototype.redIAdd = function redIAdd (num) { -+ assert(this.red, 'redIAdd works only with red numbers'); -+ return this.red.iadd(this, num); -+ }; -+ -+ BN.prototype.redSub = function redSub (num) { -+ assert(this.red, 'redSub works only with red numbers'); -+ return this.red.sub(this, num); -+ }; -+ -+ BN.prototype.redISub = function redISub (num) { -+ assert(this.red, 'redISub works only with red numbers'); -+ return this.red.isub(this, num); -+ }; -+ -+ BN.prototype.redShl = function redShl (num) { -+ assert(this.red, 'redShl works only with red numbers'); -+ return this.red.shl(this, num); -+ }; -+ -+ BN.prototype.redMul = function redMul (num) { -+ assert(this.red, 'redMul works only with red numbers'); -+ this.red._verify2(this, num); -+ return this.red.mul(this, num); -+ }; -+ -+ BN.prototype.redIMul = function redIMul (num) { -+ assert(this.red, 'redMul works only with red numbers'); -+ this.red._verify2(this, num); -+ return this.red.imul(this, num); -+ }; -+ -+ BN.prototype.redSqr = function redSqr () { -+ assert(this.red, 'redSqr works only with red numbers'); -+ this.red._verify1(this); -+ return this.red.sqr(this); -+ }; -+ -+ BN.prototype.redISqr = function redISqr () { -+ assert(this.red, 'redISqr works only with red numbers'); -+ this.red._verify1(this); -+ return this.red.isqr(this); -+ }; -+ -+ // Square root over p -+ BN.prototype.redSqrt = function redSqrt () { -+ assert(this.red, 'redSqrt works only with red numbers'); -+ this.red._verify1(this); -+ return this.red.sqrt(this); -+ }; -+ -+ BN.prototype.redInvm = function redInvm () { -+ assert(this.red, 'redInvm works only with red numbers'); -+ this.red._verify1(this); -+ return this.red.invm(this); -+ }; -+ -+ // Return negative clone of `this` % `red modulo` -+ BN.prototype.redNeg = function redNeg () { -+ assert(this.red, 'redNeg works only with red numbers'); -+ this.red._verify1(this); -+ return this.red.neg(this); -+ }; -+ -+ BN.prototype.redPow = function redPow (num) { -+ assert(this.red && !num.red, 'redPow(normalNum)'); -+ this.red._verify1(this); -+ return this.red.pow(this, num); -+ }; -+ -+ // Prime numbers with efficient reduction -+ var primes = { -+ k256: null, -+ p224: null, -+ p192: null, -+ p25519: null -+ }; -+ -+ // Pseudo-Mersenne prime -+ function MPrime (name, p) { -+ // P = 2 ^ N - K -+ this.name = name; -+ this.p = new BN(p, 16); -+ this.n = this.p.bitLength(); -+ this.k = new BN(1).iushln(this.n).isub(this.p); -+ -+ this.tmp = this._tmp(); -+ } -+ -+ MPrime.prototype._tmp = function _tmp () { -+ var tmp = new BN(null); -+ tmp.words = new Array(Math.ceil(this.n / 13)); -+ return tmp; -+ }; -+ -+ MPrime.prototype.ireduce = function ireduce (num) { -+ // Assumes that `num` is less than `P^2` -+ // num = HI * (2 ^ N - K) + HI * K + LO = HI * K + LO (mod P) -+ var r = num; -+ var rlen; -+ -+ do { -+ this.split(r, this.tmp); -+ r = this.imulK(r); -+ r = r.iadd(this.tmp); -+ rlen = r.bitLength(); -+ } while (rlen > this.n); -+ -+ var cmp = rlen < this.n ? -1 : r.ucmp(this.p); -+ if (cmp === 0) { -+ r.words[0] = 0; -+ r.length = 1; -+ } else if (cmp > 0) { -+ r.isub(this.p); -+ } else { -+ r.strip(); -+ } -+ -+ return r; -+ }; -+ -+ MPrime.prototype.split = function split (input, out) { -+ input.iushrn(this.n, 0, out); -+ }; -+ -+ MPrime.prototype.imulK = function imulK (num) { -+ return num.imul(this.k); -+ }; -+ -+ function K256 () { -+ MPrime.call( -+ this, -+ 'k256', -+ 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f'); -+ } -+ inherits(K256, MPrime); -+ -+ K256.prototype.split = function split (input, output) { -+ // 256 = 9 * 26 + 22 -+ var mask = 0x3fffff; -+ -+ var outLen = Math.min(input.length, 9); -+ for (var i = 0; i < outLen; i++) { -+ output.words[i] = input.words[i]; -+ } -+ output.length = outLen; -+ -+ if (input.length <= 9) { -+ input.words[0] = 0; -+ input.length = 1; -+ return; -+ } -+ -+ // Shift by 9 limbs -+ var prev = input.words[9]; -+ output.words[output.length++] = prev & mask; -+ -+ for (i = 10; i < input.length; i++) { -+ var next = input.words[i] | 0; -+ input.words[i - 10] = ((next & mask) << 4) | (prev >>> 22); -+ prev = next; -+ } -+ prev >>>= 22; -+ input.words[i - 10] = prev; -+ if (prev === 0 && input.length > 10) { -+ input.length -= 10; -+ } else { -+ input.length -= 9; -+ } -+ }; -+ -+ K256.prototype.imulK = function imulK (num) { -+ // K = 0x1000003d1 = [ 0x40, 0x3d1 ] -+ num.words[num.length] = 0; -+ num.words[num.length + 1] = 0; -+ num.length += 2; -+ -+ // bounded at: 0x40 * 0x3ffffff + 0x3d0 = 0x100000390 -+ var lo = 0; -+ for (var i = 0; i < num.length; i++) { -+ var w = num.words[i] | 0; -+ lo += w * 0x3d1; -+ num.words[i] = lo & 0x3ffffff; -+ lo = w * 0x40 + ((lo / 0x4000000) | 0); -+ } -+ -+ // Fast length reduction -+ if (num.words[num.length - 1] === 0) { -+ num.length--; -+ if (num.words[num.length - 1] === 0) { -+ num.length--; -+ } -+ } -+ return num; -+ }; -+ -+ function P224 () { -+ MPrime.call( -+ this, -+ 'p224', -+ 'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001'); -+ } -+ inherits(P224, MPrime); -+ -+ function P192 () { -+ MPrime.call( -+ this, -+ 'p192', -+ 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff'); -+ } -+ inherits(P192, MPrime); -+ -+ function P25519 () { -+ // 2 ^ 255 - 19 -+ MPrime.call( -+ this, -+ '25519', -+ '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed'); -+ } -+ inherits(P25519, MPrime); -+ -+ P25519.prototype.imulK = function imulK (num) { -+ // K = 0x13 -+ var carry = 0; -+ for (var i = 0; i < num.length; i++) { -+ var hi = (num.words[i] | 0) * 0x13 + carry; -+ var lo = hi & 0x3ffffff; -+ hi >>>= 26; -+ -+ num.words[i] = lo; -+ carry = hi; -+ } -+ if (carry !== 0) { -+ num.words[num.length++] = carry; -+ } -+ return num; -+ }; -+ -+ // Exported mostly for testing purposes, use plain name instead -+ BN._prime = function prime (name) { -+ // Cached version of prime -+ if (primes[name]) return primes[name]; -+ -+ var prime; -+ if (name === 'k256') { -+ prime = new K256(); -+ } else if (name === 'p224') { -+ prime = new P224(); -+ } else if (name === 'p192') { -+ prime = new P192(); -+ } else if (name === 'p25519') { -+ prime = new P25519(); -+ } else { -+ throw new Error('Unknown prime ' + name); -+ } -+ primes[name] = prime; -+ -+ return prime; -+ }; -+ -+ // -+ // Base reduction engine -+ // -+ function Red (m) { -+ if (typeof m === 'string') { -+ var prime = BN._prime(m); -+ this.m = prime.p; -+ this.prime = prime; -+ } else { -+ assert(m.gtn(1), 'modulus must be greater than 1'); -+ this.m = m; -+ this.prime = null; -+ } -+ } -+ -+ Red.prototype._verify1 = function _verify1 (a) { -+ assert(a.negative === 0, 'red works only with positives'); -+ assert(a.red, 'red works only with red numbers'); -+ }; -+ -+ Red.prototype._verify2 = function _verify2 (a, b) { -+ assert((a.negative | b.negative) === 0, 'red works only with positives'); -+ assert(a.red && a.red === b.red, -+ 'red works only with red numbers'); -+ }; -+ -+ Red.prototype.imod = function imod (a) { -+ if (this.prime) return this.prime.ireduce(a)._forceRed(this); -+ return a.umod(this.m)._forceRed(this); -+ }; -+ -+ Red.prototype.neg = function neg (a) { -+ if (a.isZero()) { -+ return a.clone(); -+ } -+ -+ return this.m.sub(a)._forceRed(this); -+ }; -+ -+ Red.prototype.add = function add (a, b) { -+ this._verify2(a, b); -+ -+ var res = a.add(b); -+ if (res.cmp(this.m) >= 0) { -+ res.isub(this.m); -+ } -+ return res._forceRed(this); -+ }; -+ -+ Red.prototype.iadd = function iadd (a, b) { -+ this._verify2(a, b); -+ -+ var res = a.iadd(b); -+ if (res.cmp(this.m) >= 0) { -+ res.isub(this.m); -+ } -+ return res; -+ }; -+ -+ Red.prototype.sub = function sub (a, b) { -+ this._verify2(a, b); -+ -+ var res = a.sub(b); -+ if (res.cmpn(0) < 0) { -+ res.iadd(this.m); -+ } -+ return res._forceRed(this); -+ }; -+ -+ Red.prototype.isub = function isub (a, b) { -+ this._verify2(a, b); -+ -+ var res = a.isub(b); -+ if (res.cmpn(0) < 0) { -+ res.iadd(this.m); -+ } -+ return res; -+ }; -+ -+ Red.prototype.shl = function shl (a, num) { -+ this._verify1(a); -+ return this.imod(a.ushln(num)); -+ }; -+ -+ Red.prototype.imul = function imul (a, b) { -+ this._verify2(a, b); -+ return this.imod(a.imul(b)); -+ }; -+ -+ Red.prototype.mul = function mul (a, b) { -+ this._verify2(a, b); -+ return this.imod(a.mul(b)); -+ }; -+ -+ Red.prototype.isqr = function isqr (a) { -+ return this.imul(a, a.clone()); -+ }; -+ -+ Red.prototype.sqr = function sqr (a) { -+ return this.mul(a, a); -+ }; -+ -+ Red.prototype.sqrt = function sqrt (a) { -+ if (a.isZero()) return a.clone(); -+ -+ var mod3 = this.m.andln(3); -+ assert(mod3 % 2 === 1); -+ -+ // Fast case -+ if (mod3 === 3) { -+ var pow = this.m.add(new BN(1)).iushrn(2); -+ return this.pow(a, pow); -+ } -+ -+ // Tonelli-Shanks algorithm (Totally unoptimized and slow) -+ // -+ // Find Q and S, that Q * 2 ^ S = (P - 1) -+ var q = this.m.subn(1); -+ var s = 0; -+ while (!q.isZero() && q.andln(1) === 0) { -+ s++; -+ q.iushrn(1); -+ } -+ assert(!q.isZero()); -+ -+ var one = new BN(1).toRed(this); -+ var nOne = one.redNeg(); -+ -+ // Find quadratic non-residue -+ // NOTE: Max is such because of generalized Riemann hypothesis. -+ var lpow = this.m.subn(1).iushrn(1); -+ var z = this.m.bitLength(); -+ z = new BN(2 * z * z).toRed(this); -+ -+ while (this.pow(z, lpow).cmp(nOne) !== 0) { -+ z.redIAdd(nOne); -+ } -+ -+ var c = this.pow(z, q); -+ var r = this.pow(a, q.addn(1).iushrn(1)); -+ var t = this.pow(a, q); -+ var m = s; -+ while (t.cmp(one) !== 0) { -+ var tmp = t; -+ for (var i = 0; tmp.cmp(one) !== 0; i++) { -+ tmp = tmp.redSqr(); -+ } -+ assert(i < m); -+ var b = this.pow(c, new BN(1).iushln(m - i - 1)); -+ -+ r = r.redMul(b); -+ c = b.redSqr(); -+ t = t.redMul(c); -+ m = i; -+ } -+ -+ return r; -+ }; -+ -+ Red.prototype.invm = function invm (a) { -+ var inv = a._invmp(this.m); -+ if (inv.negative !== 0) { -+ inv.negative = 0; -+ return this.imod(inv).redNeg(); -+ } else { -+ return this.imod(inv); -+ } -+ }; -+ -+ Red.prototype.pow = function pow (a, num) { -+ if (num.isZero()) return new BN(1); -+ if (num.cmpn(1) === 0) return a.clone(); -+ -+ var windowSize = 4; -+ var wnd = new Array(1 << windowSize); -+ wnd[0] = new BN(1).toRed(this); -+ wnd[1] = a; -+ for (var i = 2; i < wnd.length; i++) { -+ wnd[i] = this.mul(wnd[i - 1], a); -+ } -+ -+ var res = wnd[0]; -+ var current = 0; -+ var currentLen = 0; -+ var start = num.bitLength() % 26; -+ if (start === 0) { -+ start = 26; -+ } -+ -+ for (i = num.length - 1; i >= 0; i--) { -+ var word = num.words[i]; -+ for (var j = start - 1; j >= 0; j--) { -+ var bit = (word >> j) & 1; -+ if (res !== wnd[0]) { -+ res = this.sqr(res); -+ } -+ -+ if (bit === 0 && current === 0) { -+ currentLen = 0; -+ continue; -+ } -+ -+ current <<= 1; -+ current |= bit; -+ currentLen++; -+ if (currentLen !== windowSize && (i !== 0 || j !== 0)) continue; -+ -+ res = this.mul(res, wnd[current]); -+ currentLen = 0; -+ current = 0; -+ } -+ start = 26; -+ } -+ -+ return res; -+ }; -+ -+ Red.prototype.convertTo = function convertTo (num) { -+ var r = num.umod(this.m); -+ -+ return r === num ? r.clone() : r; -+ }; -+ -+ Red.prototype.convertFrom = function convertFrom (num) { -+ var res = num.clone(); -+ res.red = null; -+ return res; -+ }; -+ -+ // -+ // Montgomery method engine -+ // -+ -+ BN.mont = function mont (num) { -+ return new Mont(num); -+ }; -+ -+ function Mont (m) { -+ Red.call(this, m); -+ -+ this.shift = this.m.bitLength(); -+ if (this.shift % 26 !== 0) { -+ this.shift += 26 - (this.shift % 26); -+ } -+ -+ this.r = new BN(1).iushln(this.shift); -+ this.r2 = this.imod(this.r.sqr()); -+ this.rinv = this.r._invmp(this.m); -+ -+ this.minv = this.rinv.mul(this.r).isubn(1).div(this.m); -+ this.minv = this.minv.umod(this.r); -+ this.minv = this.r.sub(this.minv); -+ } -+ inherits(Mont, Red); -+ -+ Mont.prototype.convertTo = function convertTo (num) { -+ return this.imod(num.ushln(this.shift)); -+ }; -+ -+ Mont.prototype.convertFrom = function convertFrom (num) { -+ var r = this.imod(num.mul(this.rinv)); -+ r.red = null; -+ return r; -+ }; -+ -+ Mont.prototype.imul = function imul (a, b) { -+ if (a.isZero() || b.isZero()) { -+ a.words[0] = 0; -+ a.length = 1; -+ return a; -+ } -+ -+ var t = a.imul(b); -+ var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m); -+ var u = t.isub(c).iushrn(this.shift); -+ var res = u; -+ -+ if (u.cmp(this.m) >= 0) { -+ res = u.isub(this.m); -+ } else if (u.cmpn(0) < 0) { -+ res = u.iadd(this.m); -+ } -+ -+ return res._forceRed(this); -+ }; -+ -+ Mont.prototype.mul = function mul (a, b) { -+ if (a.isZero() || b.isZero()) return new BN(0)._forceRed(this); -+ -+ var t = a.mul(b); -+ var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m); -+ var u = t.isub(c).iushrn(this.shift); -+ var res = u; -+ if (u.cmp(this.m) >= 0) { -+ res = u.isub(this.m); -+ } else if (u.cmpn(0) < 0) { -+ res = u.iadd(this.m); -+ } -+ -+ return res._forceRed(this); -+ }; -+ -+ Mont.prototype.invm = function invm (a) { -+ // (AR)^-1 * R^2 = (A^-1 * R^-1) * R^2 = A^-1 * R -+ var res = this.imod(a._invmp(this.m).mul(this.r2)); -+ return res._forceRed(this); -+ }; -+})(typeof module === 'undefined' || module, this); -+ -+},{}],2:[function(require,module,exports){ -+'use strict'; -+ -+var elliptic = exports; -+ -+elliptic.version = require('../package.json').version; -+elliptic.utils = require('./elliptic/utils'); -+elliptic.rand = require('brorand'); -+elliptic.hmacDRBG = require('./elliptic/hmac-drbg'); -+elliptic.curve = require('./elliptic/curve'); -+elliptic.curves = require('./elliptic/curves'); -+ -+// Protocols -+elliptic.ec = require('./elliptic/ec'); -+elliptic.eddsa = require('./elliptic/eddsa'); -+ -+},{"../package.json":26,"./elliptic/curve":5,"./elliptic/curves":8,"./elliptic/ec":9,"./elliptic/eddsa":12,"./elliptic/hmac-drbg":15,"./elliptic/utils":17,"brorand":18}],3:[function(require,module,exports){ -+'use strict'; -+ -+var BN = require('bn.js'); -+var elliptic = require('../../elliptic'); -+var utils = elliptic.utils; -+var getNAF = utils.getNAF; -+var getJSF = utils.getJSF; -+var assert = utils.assert; -+ -+function BaseCurve(type, conf) { -+ this.type = type; -+ this.p = new BN(conf.p, 16); -+ -+ // Use Montgomery, when there is no fast reduction for the prime -+ this.red = conf.prime ? BN.red(conf.prime) : BN.mont(this.p); -+ -+ // Useful for many curves -+ this.zero = new BN(0).toRed(this.red); -+ this.one = new BN(1).toRed(this.red); -+ this.two = new BN(2).toRed(this.red); -+ -+ // Curve configuration, optional -+ this.n = conf.n && new BN(conf.n, 16); -+ this.g = conf.g && this.pointFromJSON(conf.g, conf.gRed); -+ -+ // Temporary arrays -+ this._wnafT1 = new Array(4); -+ this._wnafT2 = new Array(4); -+ this._wnafT3 = new Array(4); -+ this._wnafT4 = new Array(4); -+ -+ // Generalized Greg Maxwell's trick -+ var adjustCount = this.n && this.p.div(this.n); -+ if (!adjustCount || adjustCount.cmpn(100) > 0) { -+ this.redN = null; -+ } else { -+ this._maxwellTrick = true; -+ this.redN = this.n.toRed(this.red); -+ } -+} -+module.exports = BaseCurve; -+ -+BaseCurve.prototype.point = function point() { -+ throw new Error('Not implemented'); -+}; -+ -+BaseCurve.prototype.validate = function validate() { -+ throw new Error('Not implemented'); -+}; -+ -+BaseCurve.prototype._fixedNafMul = function _fixedNafMul(p, k) { -+ assert(p.precomputed); -+ var doubles = p._getDoubles(); -+ -+ var naf = getNAF(k, 1); -+ var I = (1 << (doubles.step + 1)) - (doubles.step % 2 === 0 ? 2 : 1); -+ I /= 3; -+ -+ // Translate into more windowed form -+ var repr = []; -+ for (var j = 0; j < naf.length; j += doubles.step) { -+ var nafW = 0; -+ for (var k = j + doubles.step - 1; k >= j; k--) -+ nafW = (nafW << 1) + naf[k]; -+ repr.push(nafW); -+ } -+ -+ var a = this.jpoint(null, null, null); -+ var b = this.jpoint(null, null, null); -+ for (var i = I; i > 0; i--) { -+ for (var j = 0; j < repr.length; j++) { -+ var nafW = repr[j]; -+ if (nafW === i) -+ b = b.mixedAdd(doubles.points[j]); -+ else if (nafW === -i) -+ b = b.mixedAdd(doubles.points[j].neg()); -+ } -+ a = a.add(b); -+ } -+ return a.toP(); -+}; -+ -+BaseCurve.prototype._wnafMul = function _wnafMul(p, k) { -+ var w = 4; -+ -+ // Precompute window -+ var nafPoints = p._getNAFPoints(w); -+ w = nafPoints.wnd; -+ var wnd = nafPoints.points; -+ -+ // Get NAF form -+ var naf = getNAF(k, w); -+ -+ // Add `this`*(N+1) for every w-NAF index -+ var acc = this.jpoint(null, null, null); -+ for (var i = naf.length - 1; i >= 0; i--) { -+ // Count zeroes -+ for (var k = 0; i >= 0 && naf[i] === 0; i--) -+ k++; -+ if (i >= 0) -+ k++; -+ acc = acc.dblp(k); -+ -+ if (i < 0) -+ break; -+ var z = naf[i]; -+ assert(z !== 0); -+ if (p.type === 'affine') { -+ // J +- P -+ if (z > 0) -+ acc = acc.mixedAdd(wnd[(z - 1) >> 1]); -+ else -+ acc = acc.mixedAdd(wnd[(-z - 1) >> 1].neg()); -+ } else { -+ // J +- J -+ if (z > 0) -+ acc = acc.add(wnd[(z - 1) >> 1]); -+ else -+ acc = acc.add(wnd[(-z - 1) >> 1].neg()); -+ } -+ } -+ return p.type === 'affine' ? acc.toP() : acc; -+}; -+ -+BaseCurve.prototype._wnafMulAdd = function _wnafMulAdd(defW, -+ points, -+ coeffs, -+ len, -+ jacobianResult) { -+ var wndWidth = this._wnafT1; -+ var wnd = this._wnafT2; -+ var naf = this._wnafT3; -+ -+ // Fill all arrays -+ var max = 0; -+ for (var i = 0; i < len; i++) { -+ var p = points[i]; -+ var nafPoints = p._getNAFPoints(defW); -+ wndWidth[i] = nafPoints.wnd; -+ wnd[i] = nafPoints.points; -+ } -+ -+ // Comb small window NAFs -+ for (var i = len - 1; i >= 1; i -= 2) { -+ var a = i - 1; -+ var b = i; -+ if (wndWidth[a] !== 1 || wndWidth[b] !== 1) { -+ naf[a] = getNAF(coeffs[a], wndWidth[a]); -+ naf[b] = getNAF(coeffs[b], wndWidth[b]); -+ max = Math.max(naf[a].length, max); -+ max = Math.max(naf[b].length, max); -+ continue; -+ } -+ -+ var comb = [ -+ points[a], /* 1 */ -+ null, /* 3 */ -+ null, /* 5 */ -+ points[b] /* 7 */ -+ ]; -+ -+ // Try to avoid Projective points, if possible -+ if (points[a].y.cmp(points[b].y) === 0) { -+ comb[1] = points[a].add(points[b]); -+ comb[2] = points[a].toJ().mixedAdd(points[b].neg()); -+ } else if (points[a].y.cmp(points[b].y.redNeg()) === 0) { -+ comb[1] = points[a].toJ().mixedAdd(points[b]); -+ comb[2] = points[a].add(points[b].neg()); -+ } else { -+ comb[1] = points[a].toJ().mixedAdd(points[b]); -+ comb[2] = points[a].toJ().mixedAdd(points[b].neg()); -+ } -+ -+ var index = [ -+ -3, /* -1 -1 */ -+ -1, /* -1 0 */ -+ -5, /* -1 1 */ -+ -7, /* 0 -1 */ -+ 0, /* 0 0 */ -+ 7, /* 0 1 */ -+ 5, /* 1 -1 */ -+ 1, /* 1 0 */ -+ 3 /* 1 1 */ -+ ]; -+ -+ var jsf = getJSF(coeffs[a], coeffs[b]); -+ max = Math.max(jsf[0].length, max); -+ naf[a] = new Array(max); -+ naf[b] = new Array(max); -+ for (var j = 0; j < max; j++) { -+ var ja = jsf[0][j] | 0; -+ var jb = jsf[1][j] | 0; -+ -+ naf[a][j] = index[(ja + 1) * 3 + (jb + 1)]; -+ naf[b][j] = 0; -+ wnd[a] = comb; -+ } -+ } -+ -+ var acc = this.jpoint(null, null, null); -+ var tmp = this._wnafT4; -+ for (var i = max; i >= 0; i--) { -+ var k = 0; -+ -+ while (i >= 0) { -+ var zero = true; -+ for (var j = 0; j < len; j++) { -+ tmp[j] = naf[j][i] | 0; -+ if (tmp[j] !== 0) -+ zero = false; -+ } -+ if (!zero) -+ break; -+ k++; -+ i--; -+ } -+ if (i >= 0) -+ k++; -+ acc = acc.dblp(k); -+ if (i < 0) -+ break; -+ -+ for (var j = 0; j < len; j++) { -+ var z = tmp[j]; -+ var p; -+ if (z === 0) -+ continue; -+ else if (z > 0) -+ p = wnd[j][(z - 1) >> 1]; -+ else if (z < 0) -+ p = wnd[j][(-z - 1) >> 1].neg(); -+ -+ if (p.type === 'affine') -+ acc = acc.mixedAdd(p); -+ else -+ acc = acc.add(p); -+ } -+ } -+ // Zeroify references -+ for (var i = 0; i < len; i++) -+ wnd[i] = null; -+ -+ if (jacobianResult) -+ return acc; -+ else -+ return acc.toP(); -+}; -+ -+function BasePoint(curve, type) { -+ this.curve = curve; -+ this.type = type; -+ this.precomputed = null; -+} -+BaseCurve.BasePoint = BasePoint; -+ -+BasePoint.prototype.eq = function eq(/*other*/) { -+ throw new Error('Not implemented'); -+}; -+ -+BasePoint.prototype.validate = function validate() { -+ return this.curve.validate(this); -+}; -+ -+BaseCurve.prototype.decodePoint = function decodePoint(bytes, enc) { -+ bytes = utils.toArray(bytes, enc); -+ -+ var len = this.p.byteLength(); -+ -+ // uncompressed, hybrid-odd, hybrid-even -+ if ((bytes[0] === 0x04 || bytes[0] === 0x06 || bytes[0] === 0x07) && -+ bytes.length - 1 === 2 * len) { -+ if (bytes[0] === 0x06) -+ assert(bytes[bytes.length - 1] % 2 === 0); -+ else if (bytes[0] === 0x07) -+ assert(bytes[bytes.length - 1] % 2 === 1); -+ -+ var res = this.point(bytes.slice(1, 1 + len), -+ bytes.slice(1 + len, 1 + 2 * len)); -+ -+ return res; -+ } else if ((bytes[0] === 0x02 || bytes[0] === 0x03) && -+ bytes.length - 1 === len) { -+ return this.pointFromX(bytes.slice(1, 1 + len), bytes[0] === 0x03); -+ } -+ throw new Error('Unknown point format'); -+}; -+ -+BasePoint.prototype.encodeCompressed = function encodeCompressed(enc) { -+ return this.encode(enc, true); -+}; -+ -+BasePoint.prototype._encode = function _encode(compact) { -+ var len = this.curve.p.byteLength(); -+ var x = this.getX().toArray('be', len); -+ -+ if (compact) -+ return [ this.getY().isEven() ? 0x02 : 0x03 ].concat(x); -+ -+ return [ 0x04 ].concat(x, this.getY().toArray('be', len)) ; -+}; -+ -+BasePoint.prototype.encode = function encode(enc, compact) { -+ return utils.encode(this._encode(compact), enc); -+}; -+ -+BasePoint.prototype.precompute = function precompute(power) { -+ if (this.precomputed) -+ return this; -+ -+ var precomputed = { -+ doubles: null, -+ naf: null, -+ beta: null -+ }; -+ precomputed.naf = this._getNAFPoints(8); -+ precomputed.doubles = this._getDoubles(4, power); -+ precomputed.beta = this._getBeta(); -+ this.precomputed = precomputed; -+ -+ return this; -+}; -+ -+BasePoint.prototype._hasDoubles = function _hasDoubles(k) { -+ if (!this.precomputed) -+ return false; -+ -+ var doubles = this.precomputed.doubles; -+ if (!doubles) -+ return false; -+ -+ return doubles.points.length >= Math.ceil((k.bitLength() + 1) / doubles.step); -+}; -+ -+BasePoint.prototype._getDoubles = function _getDoubles(step, power) { -+ if (this.precomputed && this.precomputed.doubles) -+ return this.precomputed.doubles; -+ -+ var doubles = [ this ]; -+ var acc = this; -+ for (var i = 0; i < power; i += step) { -+ for (var j = 0; j < step; j++) -+ acc = acc.dbl(); -+ doubles.push(acc); -+ } -+ return { -+ step: step, -+ points: doubles -+ }; -+}; -+ -+BasePoint.prototype._getNAFPoints = function _getNAFPoints(wnd) { -+ if (this.precomputed && this.precomputed.naf) -+ return this.precomputed.naf; -+ -+ var res = [ this ]; -+ var max = (1 << wnd) - 1; -+ var dbl = max === 1 ? null : this.dbl(); -+ for (var i = 1; i < max; i++) -+ res[i] = res[i - 1].add(dbl); -+ return { -+ wnd: wnd, -+ points: res -+ }; -+}; -+ -+BasePoint.prototype._getBeta = function _getBeta() { -+ return null; -+}; -+ -+BasePoint.prototype.dblp = function dblp(k) { -+ var r = this; -+ for (var i = 0; i < k; i++) -+ r = r.dbl(); -+ return r; -+}; -+ -+},{"../../elliptic":2,"bn.js":1}],4:[function(require,module,exports){ -+'use strict'; -+ -+var curve = require('../curve'); -+var elliptic = require('../../elliptic'); -+var BN = require('bn.js'); -+var inherits = require('inherits'); -+var Base = curve.base; -+ -+var assert = elliptic.utils.assert; -+ -+function EdwardsCurve(conf) { -+ // NOTE: Important as we are creating point in Base.call() -+ this.twisted = (conf.a | 0) !== 1; -+ this.mOneA = this.twisted && (conf.a | 0) === -1; -+ this.extended = this.mOneA; -+ -+ Base.call(this, 'edwards', conf); -+ -+ this.a = new BN(conf.a, 16).umod(this.red.m); -+ this.a = this.a.toRed(this.red); -+ this.c = new BN(conf.c, 16).toRed(this.red); -+ this.c2 = this.c.redSqr(); -+ this.d = new BN(conf.d, 16).toRed(this.red); -+ this.dd = this.d.redAdd(this.d); -+ -+ assert(!this.twisted || this.c.fromRed().cmpn(1) === 0); -+ this.oneC = (conf.c | 0) === 1; -+} -+inherits(EdwardsCurve, Base); -+module.exports = EdwardsCurve; -+ -+EdwardsCurve.prototype._mulA = function _mulA(num) { -+ if (this.mOneA) -+ return num.redNeg(); -+ else -+ return this.a.redMul(num); -+}; -+ -+EdwardsCurve.prototype._mulC = function _mulC(num) { -+ if (this.oneC) -+ return num; -+ else -+ return this.c.redMul(num); -+}; -+ -+// Just for compatibility with Short curve -+EdwardsCurve.prototype.jpoint = function jpoint(x, y, z, t) { -+ return this.point(x, y, z, t); -+}; -+ -+EdwardsCurve.prototype.pointFromX = function pointFromX(x, odd) { -+ x = new BN(x, 16); -+ if (!x.red) -+ x = x.toRed(this.red); -+ -+ var x2 = x.redSqr(); -+ var rhs = this.c2.redSub(this.a.redMul(x2)); -+ var lhs = this.one.redSub(this.c2.redMul(this.d).redMul(x2)); -+ -+ var y2 = rhs.redMul(lhs.redInvm()); -+ var y = y2.redSqrt(); -+ if (y.redSqr().redSub(y2).cmp(this.zero) !== 0) -+ throw new Error('invalid point'); -+ -+ var isOdd = y.fromRed().isOdd(); -+ if (odd && !isOdd || !odd && isOdd) -+ y = y.redNeg(); -+ -+ return this.point(x, y); -+}; -+ -+EdwardsCurve.prototype.pointFromY = function pointFromY(y, odd) { -+ y = new BN(y, 16); -+ if (!y.red) -+ y = y.toRed(this.red); -+ -+ // x^2 = (y^2 - 1) / (d y^2 + 1) -+ var y2 = y.redSqr(); -+ var lhs = y2.redSub(this.one); -+ var rhs = y2.redMul(this.d).redAdd(this.one); -+ var x2 = lhs.redMul(rhs.redInvm()); -+ -+ if (x2.cmp(this.zero) === 0) { -+ if (odd) -+ throw new Error('invalid point'); -+ else -+ return this.point(this.zero, y); -+ } -+ -+ var x = x2.redSqrt(); -+ if (x.redSqr().redSub(x2).cmp(this.zero) !== 0) -+ throw new Error('invalid point'); -+ -+ if (x.isOdd() !== odd) -+ x = x.redNeg(); -+ -+ return this.point(x, y); -+}; -+ -+EdwardsCurve.prototype.validate = function validate(point) { -+ if (point.isInfinity()) -+ return true; -+ -+ // Curve: A * X^2 + Y^2 = C^2 * (1 + D * X^2 * Y^2) -+ point.normalize(); -+ -+ var x2 = point.x.redSqr(); -+ var y2 = point.y.redSqr(); -+ var lhs = x2.redMul(this.a).redAdd(y2); -+ var rhs = this.c2.redMul(this.one.redAdd(this.d.redMul(x2).redMul(y2))); -+ -+ return lhs.cmp(rhs) === 0; -+}; -+ -+function Point(curve, x, y, z, t) { -+ Base.BasePoint.call(this, curve, 'projective'); -+ if (x === null && y === null && z === null) { -+ this.x = this.curve.zero; -+ this.y = this.curve.one; -+ this.z = this.curve.one; -+ this.t = this.curve.zero; -+ this.zOne = true; -+ } else { -+ this.x = new BN(x, 16); -+ this.y = new BN(y, 16); -+ this.z = z ? new BN(z, 16) : this.curve.one; -+ this.t = t && new BN(t, 16); -+ if (!this.x.red) -+ this.x = this.x.toRed(this.curve.red); -+ if (!this.y.red) -+ this.y = this.y.toRed(this.curve.red); -+ if (!this.z.red) -+ this.z = this.z.toRed(this.curve.red); -+ if (this.t && !this.t.red) -+ this.t = this.t.toRed(this.curve.red); -+ this.zOne = this.z === this.curve.one; -+ -+ // Use extended coordinates -+ if (this.curve.extended && !this.t) { -+ this.t = this.x.redMul(this.y); -+ if (!this.zOne) -+ this.t = this.t.redMul(this.z.redInvm()); -+ } -+ } -+} -+inherits(Point, Base.BasePoint); -+ -+EdwardsCurve.prototype.pointFromJSON = function pointFromJSON(obj) { -+ return Point.fromJSON(this, obj); -+}; -+ -+EdwardsCurve.prototype.point = function point(x, y, z, t) { -+ return new Point(this, x, y, z, t); -+}; -+ -+Point.fromJSON = function fromJSON(curve, obj) { -+ return new Point(curve, obj[0], obj[1], obj[2]); -+}; -+ -+Point.prototype.inspect = function inspect() { -+ if (this.isInfinity()) -+ return '<EC Point Infinity>'; -+ return '<EC Point x: ' + this.x.fromRed().toString(16, 2) + -+ ' y: ' + this.y.fromRed().toString(16, 2) + -+ ' z: ' + this.z.fromRed().toString(16, 2) + '>'; -+}; -+ -+Point.prototype.isInfinity = function isInfinity() { -+ // XXX This code assumes that zero is always zero in red -+ return this.x.cmpn(0) === 0 && -+ this.y.cmp(this.z) === 0; -+}; -+ -+Point.prototype._extDbl = function _extDbl() { -+ // hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html -+ // #doubling-dbl-2008-hwcd -+ // 4M + 4S -+ -+ // A = X1^2 -+ var a = this.x.redSqr(); -+ // B = Y1^2 -+ var b = this.y.redSqr(); -+ // C = 2 * Z1^2 -+ var c = this.z.redSqr(); -+ c = c.redIAdd(c); -+ // D = a * A -+ var d = this.curve._mulA(a); -+ // E = (X1 + Y1)^2 - A - B -+ var e = this.x.redAdd(this.y).redSqr().redISub(a).redISub(b); -+ // G = D + B -+ var g = d.redAdd(b); -+ // F = G - C -+ var f = g.redSub(c); -+ // H = D - B -+ var h = d.redSub(b); -+ // X3 = E * F -+ var nx = e.redMul(f); -+ // Y3 = G * H -+ var ny = g.redMul(h); -+ // T3 = E * H -+ var nt = e.redMul(h); -+ // Z3 = F * G -+ var nz = f.redMul(g); -+ return this.curve.point(nx, ny, nz, nt); -+}; -+ -+Point.prototype._projDbl = function _projDbl() { -+ // hyperelliptic.org/EFD/g1p/auto-twisted-projective.html -+ // #doubling-dbl-2008-bbjlp -+ // #doubling-dbl-2007-bl -+ // and others -+ // Generally 3M + 4S or 2M + 4S -+ -+ // B = (X1 + Y1)^2 -+ var b = this.x.redAdd(this.y).redSqr(); -+ // C = X1^2 -+ var c = this.x.redSqr(); -+ // D = Y1^2 -+ var d = this.y.redSqr(); -+ -+ var nx; -+ var ny; -+ var nz; -+ if (this.curve.twisted) { -+ // E = a * C -+ var e = this.curve._mulA(c); -+ // F = E + D -+ var f = e.redAdd(d); -+ if (this.zOne) { -+ // X3 = (B - C - D) * (F - 2) -+ nx = b.redSub(c).redSub(d).redMul(f.redSub(this.curve.two)); -+ // Y3 = F * (E - D) -+ ny = f.redMul(e.redSub(d)); -+ // Z3 = F^2 - 2 * F -+ nz = f.redSqr().redSub(f).redSub(f); -+ } else { -+ // H = Z1^2 -+ var h = this.z.redSqr(); -+ // J = F - 2 * H -+ var j = f.redSub(h).redISub(h); -+ // X3 = (B-C-D)*J -+ nx = b.redSub(c).redISub(d).redMul(j); -+ // Y3 = F * (E - D) -+ ny = f.redMul(e.redSub(d)); -+ // Z3 = F * J -+ nz = f.redMul(j); -+ } -+ } else { -+ // E = C + D -+ var e = c.redAdd(d); -+ // H = (c * Z1)^2 -+ var h = this.curve._mulC(this.c.redMul(this.z)).redSqr(); -+ // J = E - 2 * H -+ var j = e.redSub(h).redSub(h); -+ // X3 = c * (B - E) * J -+ nx = this.curve._mulC(b.redISub(e)).redMul(j); -+ // Y3 = c * E * (C - D) -+ ny = this.curve._mulC(e).redMul(c.redISub(d)); -+ // Z3 = E * J -+ nz = e.redMul(j); -+ } -+ return this.curve.point(nx, ny, nz); -+}; -+ -+Point.prototype.dbl = function dbl() { -+ if (this.isInfinity()) -+ return this; -+ -+ // Double in extended coordinates -+ if (this.curve.extended) -+ return this._extDbl(); -+ else -+ return this._projDbl(); -+}; -+ -+Point.prototype._extAdd = function _extAdd(p) { -+ // hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html -+ // #addition-add-2008-hwcd-3 -+ // 8M -+ -+ // A = (Y1 - X1) * (Y2 - X2) -+ var a = this.y.redSub(this.x).redMul(p.y.redSub(p.x)); -+ // B = (Y1 + X1) * (Y2 + X2) -+ var b = this.y.redAdd(this.x).redMul(p.y.redAdd(p.x)); -+ // C = T1 * k * T2 -+ var c = this.t.redMul(this.curve.dd).redMul(p.t); -+ // D = Z1 * 2 * Z2 -+ var d = this.z.redMul(p.z.redAdd(p.z)); -+ // E = B - A -+ var e = b.redSub(a); -+ // F = D - C -+ var f = d.redSub(c); -+ // G = D + C -+ var g = d.redAdd(c); -+ // H = B + A -+ var h = b.redAdd(a); -+ // X3 = E * F -+ var nx = e.redMul(f); -+ // Y3 = G * H -+ var ny = g.redMul(h); -+ // T3 = E * H -+ var nt = e.redMul(h); -+ // Z3 = F * G -+ var nz = f.redMul(g); -+ return this.curve.point(nx, ny, nz, nt); -+}; -+ -+Point.prototype._projAdd = function _projAdd(p) { -+ // hyperelliptic.org/EFD/g1p/auto-twisted-projective.html -+ // #addition-add-2008-bbjlp -+ // #addition-add-2007-bl -+ // 10M + 1S -+ -+ // A = Z1 * Z2 -+ var a = this.z.redMul(p.z); -+ // B = A^2 -+ var b = a.redSqr(); -+ // C = X1 * X2 -+ var c = this.x.redMul(p.x); -+ // D = Y1 * Y2 -+ var d = this.y.redMul(p.y); -+ // E = d * C * D -+ var e = this.curve.d.redMul(c).redMul(d); -+ // F = B - E -+ var f = b.redSub(e); -+ // G = B + E -+ var g = b.redAdd(e); -+ // X3 = A * F * ((X1 + Y1) * (X2 + Y2) - C - D) -+ var tmp = this.x.redAdd(this.y).redMul(p.x.redAdd(p.y)).redISub(c).redISub(d); -+ var nx = a.redMul(f).redMul(tmp); -+ var ny; -+ var nz; -+ if (this.curve.twisted) { -+ // Y3 = A * G * (D - a * C) -+ ny = a.redMul(g).redMul(d.redSub(this.curve._mulA(c))); -+ // Z3 = F * G -+ nz = f.redMul(g); -+ } else { -+ // Y3 = A * G * (D - C) -+ ny = a.redMul(g).redMul(d.redSub(c)); -+ // Z3 = c * F * G -+ nz = this.curve._mulC(f).redMul(g); -+ } -+ return this.curve.point(nx, ny, nz); -+}; -+ -+Point.prototype.add = function add(p) { -+ if (this.isInfinity()) -+ return p; -+ if (p.isInfinity()) -+ return this; -+ -+ if (this.curve.extended) -+ return this._extAdd(p); -+ else -+ return this._projAdd(p); -+}; -+ -+Point.prototype.mul = function mul(k) { -+ if (this._hasDoubles(k)) -+ return this.curve._fixedNafMul(this, k); -+ else -+ return this.curve._wnafMul(this, k); -+}; -+ -+Point.prototype.mulAdd = function mulAdd(k1, p, k2) { -+ return this.curve._wnafMulAdd(1, [ this, p ], [ k1, k2 ], 2, false); -+}; -+ -+Point.prototype.jmulAdd = function jmulAdd(k1, p, k2) { -+ return this.curve._wnafMulAdd(1, [ this, p ], [ k1, k2 ], 2, true); -+}; -+ -+Point.prototype.normalize = function normalize() { -+ if (this.zOne) -+ return this; -+ -+ // Normalize coordinates -+ var zi = this.z.redInvm(); -+ this.x = this.x.redMul(zi); -+ this.y = this.y.redMul(zi); -+ if (this.t) -+ this.t = this.t.redMul(zi); -+ this.z = this.curve.one; -+ this.zOne = true; -+ return this; -+}; -+ -+Point.prototype.neg = function neg() { -+ return this.curve.point(this.x.redNeg(), -+ this.y, -+ this.z, -+ this.t && this.t.redNeg()); -+}; -+ -+Point.prototype.getX = function getX() { -+ this.normalize(); -+ return this.x.fromRed(); -+}; -+ -+Point.prototype.getY = function getY() { -+ this.normalize(); -+ return this.y.fromRed(); -+}; -+ -+Point.prototype.eq = function eq(other) { -+ return this === other || -+ this.getX().cmp(other.getX()) === 0 && -+ this.getY().cmp(other.getY()) === 0; -+}; -+ -+Point.prototype.eqXToP = function eqXToP(x) { -+ var rx = x.toRed(this.curve.red).redMul(this.z); -+ if (this.x.cmp(rx) === 0) -+ return true; -+ -+ var xc = x.clone(); -+ var t = this.curve.redN.redMul(this.z); -+ for (;;) { -+ xc.iadd(this.curve.n); -+ if (xc.cmp(this.curve.p) >= 0) -+ return false; -+ -+ rx.redIAdd(t); -+ if (this.x.cmp(rx) === 0) -+ return true; -+ } -+ return false; -+}; -+ -+// Compatibility with BaseCurve -+Point.prototype.toP = Point.prototype.normalize; -+Point.prototype.mixedAdd = Point.prototype.add; -+ -+},{"../../elliptic":2,"../curve":5,"bn.js":1,"inherits":25}],5:[function(require,module,exports){ -+'use strict'; -+ -+var curve = exports; -+ -+curve.base = require('./base'); -+curve.short = require('./short'); -+curve.mont = require('./mont'); -+curve.edwards = require('./edwards'); -+ -+},{"./base":3,"./edwards":4,"./mont":6,"./short":7}],6:[function(require,module,exports){ -+'use strict'; -+ -+var curve = require('../curve'); -+var BN = require('bn.js'); -+var inherits = require('inherits'); -+var Base = curve.base; -+ -+var elliptic = require('../../elliptic'); -+var utils = elliptic.utils; -+ -+function MontCurve(conf) { -+ Base.call(this, 'mont', conf); -+ -+ this.a = new BN(conf.a, 16).toRed(this.red); -+ this.b = new BN(conf.b, 16).toRed(this.red); -+ this.i4 = new BN(4).toRed(this.red).redInvm(); -+ this.two = new BN(2).toRed(this.red); -+ this.a24 = this.i4.redMul(this.a.redAdd(this.two)); -+} -+inherits(MontCurve, Base); -+module.exports = MontCurve; -+ -+MontCurve.prototype.validate = function validate(point) { -+ var x = point.normalize().x; -+ var x2 = x.redSqr(); -+ var rhs = x2.redMul(x).redAdd(x2.redMul(this.a)).redAdd(x); -+ var y = rhs.redSqrt(); -+ -+ return y.redSqr().cmp(rhs) === 0; -+}; -+ -+function Point(curve, x, z) { -+ Base.BasePoint.call(this, curve, 'projective'); -+ if (x === null && z === null) { -+ this.x = this.curve.one; -+ this.z = this.curve.zero; -+ } else { -+ this.x = new BN(x, 16); -+ this.z = new BN(z, 16); -+ if (!this.x.red) -+ this.x = this.x.toRed(this.curve.red); -+ if (!this.z.red) -+ this.z = this.z.toRed(this.curve.red); -+ } -+} -+inherits(Point, Base.BasePoint); -+ -+MontCurve.prototype.decodePoint = function decodePoint(bytes, enc) { -+ return this.point(utils.toArray(bytes, enc), 1); -+}; -+ -+MontCurve.prototype.point = function point(x, z) { -+ return new Point(this, x, z); -+}; -+ -+MontCurve.prototype.pointFromJSON = function pointFromJSON(obj) { -+ return Point.fromJSON(this, obj); -+}; -+ -+Point.prototype.precompute = function precompute() { -+ // No-op -+}; -+ -+Point.prototype._encode = function _encode() { -+ return this.getX().toArray('be', this.curve.p.byteLength()); -+}; -+ -+Point.fromJSON = function fromJSON(curve, obj) { -+ return new Point(curve, obj[0], obj[1] || curve.one); -+}; -+ -+Point.prototype.inspect = function inspect() { -+ if (this.isInfinity()) -+ return '<EC Point Infinity>'; -+ return '<EC Point x: ' + this.x.fromRed().toString(16, 2) + -+ ' z: ' + this.z.fromRed().toString(16, 2) + '>'; -+}; -+ -+Point.prototype.isInfinity = function isInfinity() { -+ // XXX This code assumes that zero is always zero in red -+ return this.z.cmpn(0) === 0; -+}; -+ -+Point.prototype.dbl = function dbl() { -+ // http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#doubling-dbl-1987-m-3 -+ // 2M + 2S + 4A -+ -+ // A = X1 + Z1 -+ var a = this.x.redAdd(this.z); -+ // AA = A^2 -+ var aa = a.redSqr(); -+ // B = X1 - Z1 -+ var b = this.x.redSub(this.z); -+ // BB = B^2 -+ var bb = b.redSqr(); -+ // C = AA - BB -+ var c = aa.redSub(bb); -+ // X3 = AA * BB -+ var nx = aa.redMul(bb); -+ // Z3 = C * (BB + A24 * C) -+ var nz = c.redMul(bb.redAdd(this.curve.a24.redMul(c))); -+ return this.curve.point(nx, nz); -+}; -+ -+Point.prototype.add = function add() { -+ throw new Error('Not supported on Montgomery curve'); -+}; -+ -+Point.prototype.diffAdd = function diffAdd(p, diff) { -+ // http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#diffadd-dadd-1987-m-3 -+ // 4M + 2S + 6A -+ -+ // A = X2 + Z2 -+ var a = this.x.redAdd(this.z); -+ // B = X2 - Z2 -+ var b = this.x.redSub(this.z); -+ // C = X3 + Z3 -+ var c = p.x.redAdd(p.z); -+ // D = X3 - Z3 -+ var d = p.x.redSub(p.z); -+ // DA = D * A -+ var da = d.redMul(a); -+ // CB = C * B -+ var cb = c.redMul(b); -+ // X5 = Z1 * (DA + CB)^2 -+ var nx = diff.z.redMul(da.redAdd(cb).redSqr()); -+ // Z5 = X1 * (DA - CB)^2 -+ var nz = diff.x.redMul(da.redISub(cb).redSqr()); -+ return this.curve.point(nx, nz); -+}; -+ -+Point.prototype.mul = function mul(k) { -+ var t = k.clone(); -+ var a = this; // (N / 2) * Q + Q -+ var b = this.curve.point(null, null); // (N / 2) * Q -+ var c = this; // Q -+ -+ for (var bits = []; t.cmpn(0) !== 0; t.iushrn(1)) -+ bits.push(t.andln(1)); -+ -+ for (var i = bits.length - 1; i >= 0; i--) { -+ if (bits[i] === 0) { -+ // N * Q + Q = ((N / 2) * Q + Q)) + (N / 2) * Q -+ a = a.diffAdd(b, c); -+ // N * Q = 2 * ((N / 2) * Q + Q)) -+ b = b.dbl(); -+ } else { -+ // N * Q = ((N / 2) * Q + Q) + ((N / 2) * Q) -+ b = a.diffAdd(b, c); -+ // N * Q + Q = 2 * ((N / 2) * Q + Q) -+ a = a.dbl(); -+ } -+ } -+ return b; -+}; -+ -+Point.prototype.mulAdd = function mulAdd() { -+ throw new Error('Not supported on Montgomery curve'); -+}; -+ -+Point.prototype.jumlAdd = function jumlAdd() { -+ throw new Error('Not supported on Montgomery curve'); -+}; -+ -+Point.prototype.eq = function eq(other) { -+ return this.getX().cmp(other.getX()) === 0; -+}; -+ -+Point.prototype.normalize = function normalize() { -+ this.x = this.x.redMul(this.z.redInvm()); -+ this.z = this.curve.one; -+ return this; -+}; -+ -+Point.prototype.getX = function getX() { -+ // Normalize coordinates -+ this.normalize(); -+ -+ return this.x.fromRed(); -+}; -+ -+},{"../../elliptic":2,"../curve":5,"bn.js":1,"inherits":25}],7:[function(require,module,exports){ -+'use strict'; -+ -+var curve = require('../curve'); -+var elliptic = require('../../elliptic'); -+var BN = require('bn.js'); -+var inherits = require('inherits'); -+var Base = curve.base; -+ -+var assert = elliptic.utils.assert; -+ -+function ShortCurve(conf) { -+ Base.call(this, 'short', conf); -+ -+ this.a = new BN(conf.a, 16).toRed(this.red); -+ this.b = new BN(conf.b, 16).toRed(this.red); -+ this.tinv = this.two.redInvm(); -+ -+ this.zeroA = this.a.fromRed().cmpn(0) === 0; -+ this.threeA = this.a.fromRed().sub(this.p).cmpn(-3) === 0; -+ -+ // If the curve is endomorphic, precalculate beta and lambda -+ this.endo = this._getEndomorphism(conf); -+ this._endoWnafT1 = new Array(4); -+ this._endoWnafT2 = new Array(4); -+} -+inherits(ShortCurve, Base); -+module.exports = ShortCurve; -+ -+ShortCurve.prototype._getEndomorphism = function _getEndomorphism(conf) { -+ // No efficient endomorphism -+ if (!this.zeroA || !this.g || !this.n || this.p.modn(3) !== 1) -+ return; -+ -+ // Compute beta and lambda, that lambda * P = (beta * Px; Py) -+ var beta; -+ var lambda; -+ if (conf.beta) { -+ beta = new BN(conf.beta, 16).toRed(this.red); -+ } else { -+ var betas = this._getEndoRoots(this.p); -+ // Choose the smallest beta -+ beta = betas[0].cmp(betas[1]) < 0 ? betas[0] : betas[1]; -+ beta = beta.toRed(this.red); -+ } -+ if (conf.lambda) { -+ lambda = new BN(conf.lambda, 16); -+ } else { -+ // Choose the lambda that is matching selected beta -+ var lambdas = this._getEndoRoots(this.n); -+ if (this.g.mul(lambdas[0]).x.cmp(this.g.x.redMul(beta)) === 0) { -+ lambda = lambdas[0]; -+ } else { -+ lambda = lambdas[1]; -+ assert(this.g.mul(lambda).x.cmp(this.g.x.redMul(beta)) === 0); -+ } -+ } -+ -+ // Get basis vectors, used for balanced length-two representation -+ var basis; -+ if (conf.basis) { -+ basis = conf.basis.map(function(vec) { -+ return { -+ a: new BN(vec.a, 16), -+ b: new BN(vec.b, 16) -+ }; -+ }); -+ } else { -+ basis = this._getEndoBasis(lambda); -+ } -+ -+ return { -+ beta: beta, -+ lambda: lambda, -+ basis: basis -+ }; -+}; -+ -+ShortCurve.prototype._getEndoRoots = function _getEndoRoots(num) { -+ // Find roots of for x^2 + x + 1 in F -+ // Root = (-1 +- Sqrt(-3)) / 2 -+ // -+ var red = num === this.p ? this.red : BN.mont(num); -+ var tinv = new BN(2).toRed(red).redInvm(); -+ var ntinv = tinv.redNeg(); -+ -+ var s = new BN(3).toRed(red).redNeg().redSqrt().redMul(tinv); -+ -+ var l1 = ntinv.redAdd(s).fromRed(); -+ var l2 = ntinv.redSub(s).fromRed(); -+ return [ l1, l2 ]; -+}; -+ -+ShortCurve.prototype._getEndoBasis = function _getEndoBasis(lambda) { -+ // aprxSqrt >= sqrt(this.n) -+ var aprxSqrt = this.n.ushrn(Math.floor(this.n.bitLength() / 2)); -+ -+ // 3.74 -+ // Run EGCD, until r(L + 1) < aprxSqrt -+ var u = lambda; -+ var v = this.n.clone(); -+ var x1 = new BN(1); -+ var y1 = new BN(0); -+ var x2 = new BN(0); -+ var y2 = new BN(1); -+ -+ // NOTE: all vectors are roots of: a + b * lambda = 0 (mod n) -+ var a0; -+ var b0; -+ // First vector -+ var a1; -+ var b1; -+ // Second vector -+ var a2; -+ var b2; -+ -+ var prevR; -+ var i = 0; -+ var r; -+ var x; -+ while (u.cmpn(0) !== 0) { -+ var q = v.div(u); -+ r = v.sub(q.mul(u)); -+ x = x2.sub(q.mul(x1)); -+ var y = y2.sub(q.mul(y1)); -+ -+ if (!a1 && r.cmp(aprxSqrt) < 0) { -+ a0 = prevR.neg(); -+ b0 = x1; -+ a1 = r.neg(); -+ b1 = x; -+ } else if (a1 && ++i === 2) { -+ break; -+ } -+ prevR = r; -+ -+ v = u; -+ u = r; -+ x2 = x1; -+ x1 = x; -+ y2 = y1; -+ y1 = y; -+ } -+ a2 = r.neg(); -+ b2 = x; -+ -+ var len1 = a1.sqr().add(b1.sqr()); -+ var len2 = a2.sqr().add(b2.sqr()); -+ if (len2.cmp(len1) >= 0) { -+ a2 = a0; -+ b2 = b0; -+ } -+ -+ // Normalize signs -+ if (a1.negative) { -+ a1 = a1.neg(); -+ b1 = b1.neg(); -+ } -+ if (a2.negative) { -+ a2 = a2.neg(); -+ b2 = b2.neg(); -+ } -+ -+ return [ -+ { a: a1, b: b1 }, -+ { a: a2, b: b2 } -+ ]; -+}; -+ -+ShortCurve.prototype._endoSplit = function _endoSplit(k) { -+ var basis = this.endo.basis; -+ var v1 = basis[0]; -+ var v2 = basis[1]; -+ -+ var c1 = v2.b.mul(k).divRound(this.n); -+ var c2 = v1.b.neg().mul(k).divRound(this.n); -+ -+ var p1 = c1.mul(v1.a); -+ var p2 = c2.mul(v2.a); -+ var q1 = c1.mul(v1.b); -+ var q2 = c2.mul(v2.b); -+ -+ // Calculate answer -+ var k1 = k.sub(p1).sub(p2); -+ var k2 = q1.add(q2).neg(); -+ return { k1: k1, k2: k2 }; -+}; -+ -+ShortCurve.prototype.pointFromX = function pointFromX(x, odd) { -+ x = new BN(x, 16); -+ if (!x.red) -+ x = x.toRed(this.red); -+ -+ var y2 = x.redSqr().redMul(x).redIAdd(x.redMul(this.a)).redIAdd(this.b); -+ var y = y2.redSqrt(); -+ if (y.redSqr().redSub(y2).cmp(this.zero) !== 0) -+ throw new Error('invalid point'); -+ -+ // XXX Is there any way to tell if the number is odd without converting it -+ // to non-red form? -+ var isOdd = y.fromRed().isOdd(); -+ if (odd && !isOdd || !odd && isOdd) -+ y = y.redNeg(); -+ -+ return this.point(x, y); -+}; -+ -+ShortCurve.prototype.validate = function validate(point) { -+ if (point.inf) -+ return true; -+ -+ var x = point.x; -+ var y = point.y; -+ -+ var ax = this.a.redMul(x); -+ var rhs = x.redSqr().redMul(x).redIAdd(ax).redIAdd(this.b); -+ return y.redSqr().redISub(rhs).cmpn(0) === 0; -+}; -+ -+ShortCurve.prototype._endoWnafMulAdd = -+ function _endoWnafMulAdd(points, coeffs, jacobianResult) { -+ var npoints = this._endoWnafT1; -+ var ncoeffs = this._endoWnafT2; -+ for (var i = 0; i < points.length; i++) { -+ var split = this._endoSplit(coeffs[i]); -+ var p = points[i]; -+ var beta = p._getBeta(); -+ -+ if (split.k1.negative) { -+ split.k1.ineg(); -+ p = p.neg(true); -+ } -+ if (split.k2.negative) { -+ split.k2.ineg(); -+ beta = beta.neg(true); -+ } -+ -+ npoints[i * 2] = p; -+ npoints[i * 2 + 1] = beta; -+ ncoeffs[i * 2] = split.k1; -+ ncoeffs[i * 2 + 1] = split.k2; -+ } -+ var res = this._wnafMulAdd(1, npoints, ncoeffs, i * 2, jacobianResult); -+ -+ // Clean-up references to points and coefficients -+ for (var j = 0; j < i * 2; j++) { -+ npoints[j] = null; -+ ncoeffs[j] = null; -+ } -+ return res; -+}; -+ -+function Point(curve, x, y, isRed) { -+ Base.BasePoint.call(this, curve, 'affine'); -+ if (x === null && y === null) { -+ this.x = null; -+ this.y = null; -+ this.inf = true; -+ } else { -+ this.x = new BN(x, 16); -+ this.y = new BN(y, 16); -+ // Force redgomery representation when loading from JSON -+ if (isRed) { -+ this.x.forceRed(this.curve.red); -+ this.y.forceRed(this.curve.red); -+ } -+ if (!this.x.red) -+ this.x = this.x.toRed(this.curve.red); -+ if (!this.y.red) -+ this.y = this.y.toRed(this.curve.red); -+ this.inf = false; -+ } -+} -+inherits(Point, Base.BasePoint); -+ -+ShortCurve.prototype.point = function point(x, y, isRed) { -+ return new Point(this, x, y, isRed); -+}; -+ -+ShortCurve.prototype.pointFromJSON = function pointFromJSON(obj, red) { -+ return Point.fromJSON(this, obj, red); -+}; -+ -+Point.prototype._getBeta = function _getBeta() { -+ if (!this.curve.endo) -+ return; -+ -+ var pre = this.precomputed; -+ if (pre && pre.beta) -+ return pre.beta; -+ -+ var beta = this.curve.point(this.x.redMul(this.curve.endo.beta), this.y); -+ if (pre) { -+ var curve = this.curve; -+ var endoMul = function(p) { -+ return curve.point(p.x.redMul(curve.endo.beta), p.y); -+ }; -+ pre.beta = beta; -+ beta.precomputed = { -+ beta: null, -+ naf: pre.naf && { -+ wnd: pre.naf.wnd, -+ points: pre.naf.points.map(endoMul) -+ }, -+ doubles: pre.doubles && { -+ step: pre.doubles.step, -+ points: pre.doubles.points.map(endoMul) -+ } -+ }; -+ } -+ return beta; -+}; -+ -+Point.prototype.toJSON = function toJSON() { -+ if (!this.precomputed) -+ return [ this.x, this.y ]; -+ -+ return [ this.x, this.y, this.precomputed && { -+ doubles: this.precomputed.doubles && { -+ step: this.precomputed.doubles.step, -+ points: this.precomputed.doubles.points.slice(1) -+ }, -+ naf: this.precomputed.naf && { -+ wnd: this.precomputed.naf.wnd, -+ points: this.precomputed.naf.points.slice(1) -+ } -+ } ]; -+}; -+ -+Point.fromJSON = function fromJSON(curve, obj, red) { -+ if (typeof obj === 'string') -+ obj = JSON.parse(obj); -+ var res = curve.point(obj[0], obj[1], red); -+ if (!obj[2]) -+ return res; -+ -+ function obj2point(obj) { -+ return curve.point(obj[0], obj[1], red); -+ } -+ -+ var pre = obj[2]; -+ res.precomputed = { -+ beta: null, -+ doubles: pre.doubles && { -+ step: pre.doubles.step, -+ points: [ res ].concat(pre.doubles.points.map(obj2point)) -+ }, -+ naf: pre.naf && { -+ wnd: pre.naf.wnd, -+ points: [ res ].concat(pre.naf.points.map(obj2point)) -+ } -+ }; -+ return res; -+}; -+ -+Point.prototype.inspect = function inspect() { -+ if (this.isInfinity()) -+ return '<EC Point Infinity>'; -+ return '<EC Point x: ' + this.x.fromRed().toString(16, 2) + -+ ' y: ' + this.y.fromRed().toString(16, 2) + '>'; -+}; -+ -+Point.prototype.isInfinity = function isInfinity() { -+ return this.inf; -+}; -+ -+Point.prototype.add = function add(p) { -+ // O + P = P -+ if (this.inf) -+ return p; -+ -+ // P + O = P -+ if (p.inf) -+ return this; -+ -+ // P + P = 2P -+ if (this.eq(p)) -+ return this.dbl(); -+ -+ // P + (-P) = O -+ if (this.neg().eq(p)) -+ return this.curve.point(null, null); -+ -+ // P + Q = O -+ if (this.x.cmp(p.x) === 0) -+ return this.curve.point(null, null); -+ -+ var c = this.y.redSub(p.y); -+ if (c.cmpn(0) !== 0) -+ c = c.redMul(this.x.redSub(p.x).redInvm()); -+ var nx = c.redSqr().redISub(this.x).redISub(p.x); -+ var ny = c.redMul(this.x.redSub(nx)).redISub(this.y); -+ return this.curve.point(nx, ny); -+}; -+ -+Point.prototype.dbl = function dbl() { -+ if (this.inf) -+ return this; -+ -+ // 2P = O -+ var ys1 = this.y.redAdd(this.y); -+ if (ys1.cmpn(0) === 0) -+ return this.curve.point(null, null); -+ -+ var a = this.curve.a; -+ -+ var x2 = this.x.redSqr(); -+ var dyinv = ys1.redInvm(); -+ var c = x2.redAdd(x2).redIAdd(x2).redIAdd(a).redMul(dyinv); -+ -+ var nx = c.redSqr().redISub(this.x.redAdd(this.x)); -+ var ny = c.redMul(this.x.redSub(nx)).redISub(this.y); -+ return this.curve.point(nx, ny); -+}; -+ -+Point.prototype.getX = function getX() { -+ return this.x.fromRed(); -+}; -+ -+Point.prototype.getY = function getY() { -+ return this.y.fromRed(); -+}; -+ -+Point.prototype.mul = function mul(k) { -+ k = new BN(k, 16); -+ -+ if (this._hasDoubles(k)) -+ return this.curve._fixedNafMul(this, k); -+ else if (this.curve.endo) -+ return this.curve._endoWnafMulAdd([ this ], [ k ]); -+ else -+ return this.curve._wnafMul(this, k); -+}; -+ -+Point.prototype.mulAdd = function mulAdd(k1, p2, k2) { -+ var points = [ this, p2 ]; -+ var coeffs = [ k1, k2 ]; -+ if (this.curve.endo) -+ return this.curve._endoWnafMulAdd(points, coeffs); -+ else -+ return this.curve._wnafMulAdd(1, points, coeffs, 2); -+}; -+ -+Point.prototype.jmulAdd = function jmulAdd(k1, p2, k2) { -+ var points = [ this, p2 ]; -+ var coeffs = [ k1, k2 ]; -+ if (this.curve.endo) -+ return this.curve._endoWnafMulAdd(points, coeffs, true); -+ else -+ return this.curve._wnafMulAdd(1, points, coeffs, 2, true); -+}; -+ -+Point.prototype.eq = function eq(p) { -+ return this === p || -+ this.inf === p.inf && -+ (this.inf || this.x.cmp(p.x) === 0 && this.y.cmp(p.y) === 0); -+}; -+ -+Point.prototype.neg = function neg(_precompute) { -+ if (this.inf) -+ return this; -+ -+ var res = this.curve.point(this.x, this.y.redNeg()); -+ if (_precompute && this.precomputed) { -+ var pre = this.precomputed; -+ var negate = function(p) { -+ return p.neg(); -+ }; -+ res.precomputed = { -+ naf: pre.naf && { -+ wnd: pre.naf.wnd, -+ points: pre.naf.points.map(negate) -+ }, -+ doubles: pre.doubles && { -+ step: pre.doubles.step, -+ points: pre.doubles.points.map(negate) -+ } -+ }; -+ } -+ return res; -+}; -+ -+Point.prototype.toJ = function toJ() { -+ if (this.inf) -+ return this.curve.jpoint(null, null, null); -+ -+ var res = this.curve.jpoint(this.x, this.y, this.curve.one); -+ return res; -+}; -+ -+function JPoint(curve, x, y, z) { -+ Base.BasePoint.call(this, curve, 'jacobian'); -+ if (x === null && y === null && z === null) { -+ this.x = this.curve.one; -+ this.y = this.curve.one; -+ this.z = new BN(0); -+ } else { -+ this.x = new BN(x, 16); -+ this.y = new BN(y, 16); -+ this.z = new BN(z, 16); -+ } -+ if (!this.x.red) -+ this.x = this.x.toRed(this.curve.red); -+ if (!this.y.red) -+ this.y = this.y.toRed(this.curve.red); -+ if (!this.z.red) -+ this.z = this.z.toRed(this.curve.red); -+ -+ this.zOne = this.z === this.curve.one; -+} -+inherits(JPoint, Base.BasePoint); -+ -+ShortCurve.prototype.jpoint = function jpoint(x, y, z) { -+ return new JPoint(this, x, y, z); -+}; -+ -+JPoint.prototype.toP = function toP() { -+ if (this.isInfinity()) -+ return this.curve.point(null, null); -+ -+ var zinv = this.z.redInvm(); -+ var zinv2 = zinv.redSqr(); -+ var ax = this.x.redMul(zinv2); -+ var ay = this.y.redMul(zinv2).redMul(zinv); -+ -+ return this.curve.point(ax, ay); -+}; -+ -+JPoint.prototype.neg = function neg() { -+ return this.curve.jpoint(this.x, this.y.redNeg(), this.z); -+}; -+ -+JPoint.prototype.add = function add(p) { -+ // O + P = P -+ if (this.isInfinity()) -+ return p; -+ -+ // P + O = P -+ if (p.isInfinity()) -+ return this; -+ -+ // 12M + 4S + 7A -+ var pz2 = p.z.redSqr(); -+ var z2 = this.z.redSqr(); -+ var u1 = this.x.redMul(pz2); -+ var u2 = p.x.redMul(z2); -+ var s1 = this.y.redMul(pz2.redMul(p.z)); -+ var s2 = p.y.redMul(z2.redMul(this.z)); -+ -+ var h = u1.redSub(u2); -+ var r = s1.redSub(s2); -+ if (h.cmpn(0) === 0) { -+ if (r.cmpn(0) !== 0) -+ return this.curve.jpoint(null, null, null); -+ else -+ return this.dbl(); -+ } -+ -+ var h2 = h.redSqr(); -+ var h3 = h2.redMul(h); -+ var v = u1.redMul(h2); -+ -+ var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v); -+ var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3)); -+ var nz = this.z.redMul(p.z).redMul(h); -+ -+ return this.curve.jpoint(nx, ny, nz); -+}; -+ -+JPoint.prototype.mixedAdd = function mixedAdd(p) { -+ // O + P = P -+ if (this.isInfinity()) -+ return p.toJ(); -+ -+ // P + O = P -+ if (p.isInfinity()) -+ return this; -+ -+ // 8M + 3S + 7A -+ var z2 = this.z.redSqr(); -+ var u1 = this.x; -+ var u2 = p.x.redMul(z2); -+ var s1 = this.y; -+ var s2 = p.y.redMul(z2).redMul(this.z); -+ -+ var h = u1.redSub(u2); -+ var r = s1.redSub(s2); -+ if (h.cmpn(0) === 0) { -+ if (r.cmpn(0) !== 0) -+ return this.curve.jpoint(null, null, null); -+ else -+ return this.dbl(); -+ } -+ -+ var h2 = h.redSqr(); -+ var h3 = h2.redMul(h); -+ var v = u1.redMul(h2); -+ -+ var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v); -+ var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3)); -+ var nz = this.z.redMul(h); -+ -+ return this.curve.jpoint(nx, ny, nz); -+}; -+ -+JPoint.prototype.dblp = function dblp(pow) { -+ if (pow === 0) -+ return this; -+ if (this.isInfinity()) -+ return this; -+ if (!pow) -+ return this.dbl(); -+ -+ if (this.curve.zeroA || this.curve.threeA) { -+ var r = this; -+ for (var i = 0; i < pow; i++) -+ r = r.dbl(); -+ return r; -+ } -+ -+ // 1M + 2S + 1A + N * (4S + 5M + 8A) -+ // N = 1 => 6M + 6S + 9A -+ var a = this.curve.a; -+ var tinv = this.curve.tinv; -+ -+ var jx = this.x; -+ var jy = this.y; -+ var jz = this.z; -+ var jz4 = jz.redSqr().redSqr(); -+ -+ // Reuse results -+ var jyd = jy.redAdd(jy); -+ for (var i = 0; i < pow; i++) { -+ var jx2 = jx.redSqr(); -+ var jyd2 = jyd.redSqr(); -+ var jyd4 = jyd2.redSqr(); -+ var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4)); -+ -+ var t1 = jx.redMul(jyd2); -+ var nx = c.redSqr().redISub(t1.redAdd(t1)); -+ var t2 = t1.redISub(nx); -+ var dny = c.redMul(t2); -+ dny = dny.redIAdd(dny).redISub(jyd4); -+ var nz = jyd.redMul(jz); -+ if (i + 1 < pow) -+ jz4 = jz4.redMul(jyd4); -+ -+ jx = nx; -+ jz = nz; -+ jyd = dny; -+ } -+ -+ return this.curve.jpoint(jx, jyd.redMul(tinv), jz); -+}; -+ -+JPoint.prototype.dbl = function dbl() { -+ if (this.isInfinity()) -+ return this; -+ -+ if (this.curve.zeroA) -+ return this._zeroDbl(); -+ else if (this.curve.threeA) -+ return this._threeDbl(); -+ else -+ return this._dbl(); -+}; -+ -+JPoint.prototype._zeroDbl = function _zeroDbl() { -+ var nx; -+ var ny; -+ var nz; -+ // Z = 1 -+ if (this.zOne) { -+ // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html -+ // #doubling-mdbl-2007-bl -+ // 1M + 5S + 14A -+ -+ // XX = X1^2 -+ var xx = this.x.redSqr(); -+ // YY = Y1^2 -+ var yy = this.y.redSqr(); -+ // YYYY = YY^2 -+ var yyyy = yy.redSqr(); -+ // S = 2 * ((X1 + YY)^2 - XX - YYYY) -+ var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy); -+ s = s.redIAdd(s); -+ // M = 3 * XX + a; a = 0 -+ var m = xx.redAdd(xx).redIAdd(xx); -+ // T = M ^ 2 - 2*S -+ var t = m.redSqr().redISub(s).redISub(s); -+ -+ // 8 * YYYY -+ var yyyy8 = yyyy.redIAdd(yyyy); -+ yyyy8 = yyyy8.redIAdd(yyyy8); -+ yyyy8 = yyyy8.redIAdd(yyyy8); -+ -+ // X3 = T -+ nx = t; -+ // Y3 = M * (S - T) - 8 * YYYY -+ ny = m.redMul(s.redISub(t)).redISub(yyyy8); -+ // Z3 = 2*Y1 -+ nz = this.y.redAdd(this.y); -+ } else { -+ // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html -+ // #doubling-dbl-2009-l -+ // 2M + 5S + 13A -+ -+ // A = X1^2 -+ var a = this.x.redSqr(); -+ // B = Y1^2 -+ var b = this.y.redSqr(); -+ // C = B^2 -+ var c = b.redSqr(); -+ // D = 2 * ((X1 + B)^2 - A - C) -+ var d = this.x.redAdd(b).redSqr().redISub(a).redISub(c); -+ d = d.redIAdd(d); -+ // E = 3 * A -+ var e = a.redAdd(a).redIAdd(a); -+ // F = E^2 -+ var f = e.redSqr(); -+ -+ // 8 * C -+ var c8 = c.redIAdd(c); -+ c8 = c8.redIAdd(c8); -+ c8 = c8.redIAdd(c8); -+ -+ // X3 = F - 2 * D -+ nx = f.redISub(d).redISub(d); -+ // Y3 = E * (D - X3) - 8 * C -+ ny = e.redMul(d.redISub(nx)).redISub(c8); -+ // Z3 = 2 * Y1 * Z1 -+ nz = this.y.redMul(this.z); -+ nz = nz.redIAdd(nz); -+ } -+ -+ return this.curve.jpoint(nx, ny, nz); -+}; -+ -+JPoint.prototype._threeDbl = function _threeDbl() { -+ var nx; -+ var ny; -+ var nz; -+ // Z = 1 -+ if (this.zOne) { -+ // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html -+ // #doubling-mdbl-2007-bl -+ // 1M + 5S + 15A -+ -+ // XX = X1^2 -+ var xx = this.x.redSqr(); -+ // YY = Y1^2 -+ var yy = this.y.redSqr(); -+ // YYYY = YY^2 -+ var yyyy = yy.redSqr(); -+ // S = 2 * ((X1 + YY)^2 - XX - YYYY) -+ var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy); -+ s = s.redIAdd(s); -+ // M = 3 * XX + a -+ var m = xx.redAdd(xx).redIAdd(xx).redIAdd(this.curve.a); -+ // T = M^2 - 2 * S -+ var t = m.redSqr().redISub(s).redISub(s); -+ // X3 = T -+ nx = t; -+ // Y3 = M * (S - T) - 8 * YYYY -+ var yyyy8 = yyyy.redIAdd(yyyy); -+ yyyy8 = yyyy8.redIAdd(yyyy8); -+ yyyy8 = yyyy8.redIAdd(yyyy8); -+ ny = m.redMul(s.redISub(t)).redISub(yyyy8); -+ // Z3 = 2 * Y1 -+ nz = this.y.redAdd(this.y); -+ } else { -+ // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b -+ // 3M + 5S -+ -+ // delta = Z1^2 -+ var delta = this.z.redSqr(); -+ // gamma = Y1^2 -+ var gamma = this.y.redSqr(); -+ // beta = X1 * gamma -+ var beta = this.x.redMul(gamma); -+ // alpha = 3 * (X1 - delta) * (X1 + delta) -+ var alpha = this.x.redSub(delta).redMul(this.x.redAdd(delta)); -+ alpha = alpha.redAdd(alpha).redIAdd(alpha); -+ // X3 = alpha^2 - 8 * beta -+ var beta4 = beta.redIAdd(beta); -+ beta4 = beta4.redIAdd(beta4); -+ var beta8 = beta4.redAdd(beta4); -+ nx = alpha.redSqr().redISub(beta8); -+ // Z3 = (Y1 + Z1)^2 - gamma - delta -+ nz = this.y.redAdd(this.z).redSqr().redISub(gamma).redISub(delta); -+ // Y3 = alpha * (4 * beta - X3) - 8 * gamma^2 -+ var ggamma8 = gamma.redSqr(); -+ ggamma8 = ggamma8.redIAdd(ggamma8); -+ ggamma8 = ggamma8.redIAdd(ggamma8); -+ ggamma8 = ggamma8.redIAdd(ggamma8); -+ ny = alpha.redMul(beta4.redISub(nx)).redISub(ggamma8); -+ } -+ -+ return this.curve.jpoint(nx, ny, nz); -+}; -+ -+JPoint.prototype._dbl = function _dbl() { -+ var a = this.curve.a; -+ -+ // 4M + 6S + 10A -+ var jx = this.x; -+ var jy = this.y; -+ var jz = this.z; -+ var jz4 = jz.redSqr().redSqr(); -+ -+ var jx2 = jx.redSqr(); -+ var jy2 = jy.redSqr(); -+ -+ var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4)); -+ -+ var jxd4 = jx.redAdd(jx); -+ jxd4 = jxd4.redIAdd(jxd4); -+ var t1 = jxd4.redMul(jy2); -+ var nx = c.redSqr().redISub(t1.redAdd(t1)); -+ var t2 = t1.redISub(nx); -+ -+ var jyd8 = jy2.redSqr(); -+ jyd8 = jyd8.redIAdd(jyd8); -+ jyd8 = jyd8.redIAdd(jyd8); -+ jyd8 = jyd8.redIAdd(jyd8); -+ var ny = c.redMul(t2).redISub(jyd8); -+ var nz = jy.redAdd(jy).redMul(jz); -+ -+ return this.curve.jpoint(nx, ny, nz); -+}; -+ -+JPoint.prototype.trpl = function trpl() { -+ if (!this.curve.zeroA) -+ return this.dbl().add(this); -+ -+ // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#tripling-tpl-2007-bl -+ // 5M + 10S + ... -+ -+ // XX = X1^2 -+ var xx = this.x.redSqr(); -+ // YY = Y1^2 -+ var yy = this.y.redSqr(); -+ // ZZ = Z1^2 -+ var zz = this.z.redSqr(); -+ // YYYY = YY^2 -+ var yyyy = yy.redSqr(); -+ // M = 3 * XX + a * ZZ2; a = 0 -+ var m = xx.redAdd(xx).redIAdd(xx); -+ // MM = M^2 -+ var mm = m.redSqr(); -+ // E = 6 * ((X1 + YY)^2 - XX - YYYY) - MM -+ var e = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy); -+ e = e.redIAdd(e); -+ e = e.redAdd(e).redIAdd(e); -+ e = e.redISub(mm); -+ // EE = E^2 -+ var ee = e.redSqr(); -+ // T = 16*YYYY -+ var t = yyyy.redIAdd(yyyy); -+ t = t.redIAdd(t); -+ t = t.redIAdd(t); -+ t = t.redIAdd(t); -+ // U = (M + E)^2 - MM - EE - T -+ var u = m.redIAdd(e).redSqr().redISub(mm).redISub(ee).redISub(t); -+ // X3 = 4 * (X1 * EE - 4 * YY * U) -+ var yyu4 = yy.redMul(u); -+ yyu4 = yyu4.redIAdd(yyu4); -+ yyu4 = yyu4.redIAdd(yyu4); -+ var nx = this.x.redMul(ee).redISub(yyu4); -+ nx = nx.redIAdd(nx); -+ nx = nx.redIAdd(nx); -+ // Y3 = 8 * Y1 * (U * (T - U) - E * EE) -+ var ny = this.y.redMul(u.redMul(t.redISub(u)).redISub(e.redMul(ee))); -+ ny = ny.redIAdd(ny); -+ ny = ny.redIAdd(ny); -+ ny = ny.redIAdd(ny); -+ // Z3 = (Z1 + E)^2 - ZZ - EE -+ var nz = this.z.redAdd(e).redSqr().redISub(zz).redISub(ee); -+ -+ return this.curve.jpoint(nx, ny, nz); -+}; -+ -+JPoint.prototype.mul = function mul(k, kbase) { -+ k = new BN(k, kbase); -+ -+ return this.curve._wnafMul(this, k); -+}; -+ -+JPoint.prototype.eq = function eq(p) { -+ if (p.type === 'affine') -+ return this.eq(p.toJ()); -+ -+ if (this === p) -+ return true; -+ -+ // x1 * z2^2 == x2 * z1^2 -+ var z2 = this.z.redSqr(); -+ var pz2 = p.z.redSqr(); -+ if (this.x.redMul(pz2).redISub(p.x.redMul(z2)).cmpn(0) !== 0) -+ return false; -+ -+ // y1 * z2^3 == y2 * z1^3 -+ var z3 = z2.redMul(this.z); -+ var pz3 = pz2.redMul(p.z); -+ return this.y.redMul(pz3).redISub(p.y.redMul(z3)).cmpn(0) === 0; -+}; -+ -+JPoint.prototype.eqXToP = function eqXToP(x) { -+ var zs = this.z.redSqr(); -+ var rx = x.toRed(this.curve.red).redMul(zs); -+ if (this.x.cmp(rx) === 0) -+ return true; -+ -+ var xc = x.clone(); -+ var t = this.curve.redN.redMul(zs); -+ for (;;) { -+ xc.iadd(this.curve.n); -+ if (xc.cmp(this.curve.p) >= 0) -+ return false; -+ -+ rx.redIAdd(t); -+ if (this.x.cmp(rx) === 0) -+ return true; -+ } -+ return false; -+}; -+ -+JPoint.prototype.inspect = function inspect() { -+ if (this.isInfinity()) -+ return '<EC JPoint Infinity>'; -+ return '<EC JPoint x: ' + this.x.toString(16, 2) + -+ ' y: ' + this.y.toString(16, 2) + -+ ' z: ' + this.z.toString(16, 2) + '>'; -+}; -+ -+JPoint.prototype.isInfinity = function isInfinity() { -+ // XXX This code assumes that zero is always zero in red -+ return this.z.cmpn(0) === 0; -+}; -+ -+},{"../../elliptic":2,"../curve":5,"bn.js":1,"inherits":25}],8:[function(require,module,exports){ -+'use strict'; -+ -+var curves = exports; -+ -+var hash = require('hash.js'); -+var elliptic = require('../elliptic'); -+ -+var assert = elliptic.utils.assert; -+ -+function PresetCurve(options) { -+ if (options.type === 'short') -+ this.curve = new elliptic.curve.short(options); -+ else if (options.type === 'edwards') -+ this.curve = new elliptic.curve.edwards(options); -+ else -+ this.curve = new elliptic.curve.mont(options); -+ this.g = this.curve.g; -+ this.n = this.curve.n; -+ this.hash = options.hash; -+ -+ assert(this.g.validate(), 'Invalid curve'); -+ assert(this.g.mul(this.n).isInfinity(), 'Invalid curve, G*N != O'); -+} -+curves.PresetCurve = PresetCurve; -+ -+function defineCurve(name, options) { -+ Object.defineProperty(curves, name, { -+ configurable: true, -+ enumerable: true, -+ get: function() { -+ var curve = new PresetCurve(options); -+ Object.defineProperty(curves, name, { -+ configurable: true, -+ enumerable: true, -+ value: curve -+ }); -+ return curve; -+ } -+ }); -+} -+ -+defineCurve('p192', { -+ type: 'short', -+ prime: 'p192', -+ p: 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff', -+ a: 'ffffffff ffffffff ffffffff fffffffe ffffffff fffffffc', -+ b: '64210519 e59c80e7 0fa7e9ab 72243049 feb8deec c146b9b1', -+ n: 'ffffffff ffffffff ffffffff 99def836 146bc9b1 b4d22831', -+ hash: hash.sha256, -+ gRed: false, -+ g: [ -+ '188da80e b03090f6 7cbf20eb 43a18800 f4ff0afd 82ff1012', -+ '07192b95 ffc8da78 631011ed 6b24cdd5 73f977a1 1e794811' -+ ] -+}); -+ -+defineCurve('p224', { -+ type: 'short', -+ prime: 'p224', -+ p: 'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001', -+ a: 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff fffffffe', -+ b: 'b4050a85 0c04b3ab f5413256 5044b0b7 d7bfd8ba 270b3943 2355ffb4', -+ n: 'ffffffff ffffffff ffffffff ffff16a2 e0b8f03e 13dd2945 5c5c2a3d', -+ hash: hash.sha256, -+ gRed: false, -+ g: [ -+ 'b70e0cbd 6bb4bf7f 321390b9 4a03c1d3 56c21122 343280d6 115c1d21', -+ 'bd376388 b5f723fb 4c22dfe6 cd4375a0 5a074764 44d58199 85007e34' -+ ] -+}); -+ -+defineCurve('p256', { -+ type: 'short', -+ prime: null, -+ p: 'ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff ffffffff', -+ a: 'ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff fffffffc', -+ b: '5ac635d8 aa3a93e7 b3ebbd55 769886bc 651d06b0 cc53b0f6 3bce3c3e 27d2604b', -+ n: 'ffffffff 00000000 ffffffff ffffffff bce6faad a7179e84 f3b9cac2 fc632551', -+ hash: hash.sha256, -+ gRed: false, -+ g: [ -+ '6b17d1f2 e12c4247 f8bce6e5 63a440f2 77037d81 2deb33a0 f4a13945 d898c296', -+ '4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16 2bce3357 6b315ece cbb64068 37bf51f5' -+ ] -+}); -+ -+defineCurve('p384', { -+ type: 'short', -+ prime: null, -+ p: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' + -+ 'fffffffe ffffffff 00000000 00000000 ffffffff', -+ a: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' + -+ 'fffffffe ffffffff 00000000 00000000 fffffffc', -+ b: 'b3312fa7 e23ee7e4 988e056b e3f82d19 181d9c6e fe814112 0314088f ' + -+ '5013875a c656398d 8a2ed19d 2a85c8ed d3ec2aef', -+ n: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff c7634d81 ' + -+ 'f4372ddf 581a0db2 48b0a77a ecec196a ccc52973', -+ hash: hash.sha384, -+ gRed: false, -+ g: [ -+ 'aa87ca22 be8b0537 8eb1c71e f320ad74 6e1d3b62 8ba79b98 59f741e0 82542a38 ' + -+ '5502f25d bf55296c 3a545e38 72760ab7', -+ '3617de4a 96262c6f 5d9e98bf 9292dc29 f8f41dbd 289a147c e9da3113 b5f0b8c0 ' + -+ '0a60b1ce 1d7e819d 7a431d7c 90ea0e5f' -+ ] -+}); -+ -+defineCurve('p521', { -+ type: 'short', -+ prime: null, -+ p: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' + -+ 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' + -+ 'ffffffff ffffffff ffffffff ffffffff ffffffff', -+ a: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' + -+ 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' + -+ 'ffffffff ffffffff ffffffff ffffffff fffffffc', -+ b: '00000051 953eb961 8e1c9a1f 929a21a0 b68540ee a2da725b ' + -+ '99b315f3 b8b48991 8ef109e1 56193951 ec7e937b 1652c0bd ' + -+ '3bb1bf07 3573df88 3d2c34f1 ef451fd4 6b503f00', -+ n: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' + -+ 'ffffffff ffffffff fffffffa 51868783 bf2f966b 7fcc0148 ' + -+ 'f709a5d0 3bb5c9b8 899c47ae bb6fb71e 91386409', -+ hash: hash.sha512, -+ gRed: false, -+ g: [ -+ '000000c6 858e06b7 0404e9cd 9e3ecb66 2395b442 9c648139 ' + -+ '053fb521 f828af60 6b4d3dba a14b5e77 efe75928 fe1dc127 ' + -+ 'a2ffa8de 3348b3c1 856a429b f97e7e31 c2e5bd66', -+ '00000118 39296a78 9a3bc004 5c8a5fb4 2c7d1bd9 98f54449 ' + -+ '579b4468 17afbd17 273e662c 97ee7299 5ef42640 c550b901 ' + -+ '3fad0761 353c7086 a272c240 88be9476 9fd16650' -+ ] -+}); -+ -+defineCurve('curve25519', { -+ type: 'mont', -+ prime: 'p25519', -+ p: '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed', -+ a: '76d06', -+ b: '0', -+ n: '1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed', -+ hash: hash.sha256, -+ gRed: false, -+ g: [ -+ '9' -+ ] -+}); -+ -+defineCurve('ed25519', { -+ type: 'edwards', -+ prime: 'p25519', -+ p: '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed', -+ a: '-1', -+ c: '1', -+ // -121665 * (121666^(-1)) (mod P) -+ d: '52036cee2b6ffe73 8cc740797779e898 00700a4d4141d8ab 75eb4dca135978a3', -+ n: '1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed', -+ hash: hash.sha256, -+ gRed: false, -+ g: [ -+ '216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a', -+ -+ // 4/5 -+ '6666666666666666666666666666666666666666666666666666666666666658' -+ ] -+}); -+ -+var pre; -+try { -+ pre = require('./precomputed/secp256k1'); -+} catch (e) { -+ pre = undefined; -+} -+ -+defineCurve('secp256k1', { -+ type: 'short', -+ prime: 'k256', -+ p: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f', -+ a: '0', -+ b: '7', -+ n: 'ffffffff ffffffff ffffffff fffffffe baaedce6 af48a03b bfd25e8c d0364141', -+ h: '1', -+ hash: hash.sha256, -+ -+ // Precomputed endomorphism -+ beta: '7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee', -+ lambda: '5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72', -+ basis: [ -+ { -+ a: '3086d221a7d46bcde86c90e49284eb15', -+ b: '-e4437ed6010e88286f547fa90abfe4c3' -+ }, -+ { -+ a: '114ca50f7a8e2f3f657c1108d9d44cfd8', -+ b: '3086d221a7d46bcde86c90e49284eb15' -+ } -+ ], -+ -+ gRed: false, -+ g: [ -+ '79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798', -+ '483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8', -+ pre -+ ] -+}); -+ -+},{"../elliptic":2,"./precomputed/secp256k1":16,"hash.js":19}],9:[function(require,module,exports){ -+'use strict'; -+ -+var BN = require('bn.js'); -+var elliptic = require('../../elliptic'); -+var utils = elliptic.utils; -+var assert = utils.assert; -+ -+var KeyPair = require('./key'); -+var Signature = require('./signature'); -+ -+function EC(options) { -+ if (!(this instanceof EC)) -+ return new EC(options); -+ -+ // Shortcut `elliptic.ec(curve-name)` -+ if (typeof options === 'string') { -+ assert(elliptic.curves.hasOwnProperty(options), 'Unknown curve ' + options); -+ -+ options = elliptic.curves[options]; -+ } -+ -+ // Shortcut for `elliptic.ec(elliptic.curves.curveName)` -+ if (options instanceof elliptic.curves.PresetCurve) -+ options = { curve: options }; -+ -+ this.curve = options.curve.curve; -+ this.n = this.curve.n; -+ this.nh = this.n.ushrn(1); -+ this.g = this.curve.g; -+ -+ // Point on curve -+ this.g = options.curve.g; -+ this.g.precompute(options.curve.n.bitLength() + 1); -+ -+ // Hash for function for DRBG -+ this.hash = options.hash || options.curve.hash; -+} -+module.exports = EC; -+ -+EC.prototype.keyPair = function keyPair(options) { -+ return new KeyPair(this, options); -+}; -+ -+EC.prototype.keyFromPrivate = function keyFromPrivate(priv, enc) { -+ return KeyPair.fromPrivate(this, priv, enc); -+}; -+ -+EC.prototype.keyFromPublic = function keyFromPublic(pub, enc) { -+ return KeyPair.fromPublic(this, pub, enc); -+}; -+ -+EC.prototype.genKeyPair = function genKeyPair(options) { -+ if (!options) -+ options = {}; -+ -+ // Instantiate Hmac_DRBG -+ var drbg = new elliptic.hmacDRBG({ -+ hash: this.hash, -+ pers: options.pers, -+ entropy: options.entropy || elliptic.rand(this.hash.hmacStrength), -+ nonce: this.n.toArray() -+ }); -+ -+ var bytes = this.n.byteLength(); -+ var ns2 = this.n.sub(new BN(2)); -+ do { -+ var priv = new BN(drbg.generate(bytes)); -+ if (priv.cmp(ns2) > 0) -+ continue; -+ -+ priv.iaddn(1); -+ return this.keyFromPrivate(priv); -+ } while (true); -+}; -+ -+EC.prototype._truncateToN = function truncateToN(msg, truncOnly) { -+ var delta = msg.byteLength() * 8 - this.n.bitLength(); -+ if (delta > 0) -+ msg = msg.ushrn(delta); -+ if (!truncOnly && msg.cmp(this.n) >= 0) -+ return msg.sub(this.n); -+ else -+ return msg; -+}; -+ -+EC.prototype.sign = function sign(msg, key, enc, options) { -+ if (typeof enc === 'object') { -+ options = enc; -+ enc = null; -+ } -+ if (!options) -+ options = {}; -+ -+ key = this.keyFromPrivate(key, enc); -+ msg = this._truncateToN(new BN(msg, 16)); -+ -+ // Zero-extend key to provide enough entropy -+ var bytes = this.n.byteLength(); -+ var bkey = key.getPrivate().toArray('be', bytes); -+ -+ // Zero-extend nonce to have the same byte size as N -+ var nonce = msg.toArray('be', bytes); -+ -+ // Instantiate Hmac_DRBG -+ var drbg = new elliptic.hmacDRBG({ -+ hash: this.hash, -+ entropy: bkey, -+ nonce: nonce, -+ pers: options.pers, -+ persEnc: options.persEnc -+ }); -+ -+ // Number of bytes to generate -+ var ns1 = this.n.sub(new BN(1)); -+ -+ for (var iter = 0; true; iter++) { -+ var k = options.k ? -+ options.k(iter) : -+ new BN(drbg.generate(this.n.byteLength())); -+ k = this._truncateToN(k, true); -+ if (k.cmpn(1) <= 0 || k.cmp(ns1) >= 0) -+ continue; -+ -+ var kp = this.g.mul(k); -+ if (kp.isInfinity()) -+ continue; -+ -+ var kpX = kp.getX(); -+ var r = kpX.umod(this.n); -+ if (r.cmpn(0) === 0) -+ continue; -+ -+ var s = k.invm(this.n).mul(r.mul(key.getPrivate()).iadd(msg)); -+ s = s.umod(this.n); -+ if (s.cmpn(0) === 0) -+ continue; -+ -+ var recoveryParam = (kp.getY().isOdd() ? 1 : 0) | -+ (kpX.cmp(r) !== 0 ? 2 : 0); -+ -+ // Use complement of `s`, if it is > `n / 2` -+ if (options.canonical && s.cmp(this.nh) > 0) { -+ s = this.n.sub(s); -+ recoveryParam ^= 1; -+ } -+ -+ return new Signature({ r: r, s: s, recoveryParam: recoveryParam }); -+ } -+}; -+ -+EC.prototype.verify = function verify(msg, signature, key, enc) { -+ msg = this._truncateToN(new BN(msg, 16)); -+ key = this.keyFromPublic(key, enc); -+ signature = new Signature(signature, 'hex'); -+ -+ // Perform primitive values validation -+ var r = signature.r; -+ var s = signature.s; -+ if (r.cmpn(1) < 0 || r.cmp(this.n) >= 0) -+ return false; -+ if (s.cmpn(1) < 0 || s.cmp(this.n) >= 0) -+ return false; -+ -+ // Validate signature -+ var sinv = s.invm(this.n); -+ var u1 = sinv.mul(msg).umod(this.n); -+ var u2 = sinv.mul(r).umod(this.n); -+ -+ if (!this.curve._maxwellTrick) { -+ var p = this.g.mulAdd(u1, key.getPublic(), u2); -+ if (p.isInfinity()) -+ return false; -+ -+ return p.getX().umod(this.n).cmp(r) === 0; -+ } -+ -+ // NOTE: Greg Maxwell's trick, inspired by: -+ // https://git.io/vad3K -+ -+ var p = this.g.jmulAdd(u1, key.getPublic(), u2); -+ if (p.isInfinity()) -+ return false; -+ -+ // Compare `p.x` of Jacobian point with `r`, -+ // this will do `p.x == r * p.z^2` instead of multiplying `p.x` by the -+ // inverse of `p.z^2` -+ return p.eqXToP(r); -+}; -+ -+EC.prototype.recoverPubKey = function(msg, signature, j, enc) { -+ assert((3 & j) === j, 'The recovery param is more than two bits'); -+ signature = new Signature(signature, enc); -+ -+ var n = this.n; -+ var e = new BN(msg); -+ var r = signature.r; -+ var s = signature.s; -+ -+ // A set LSB signifies that the y-coordinate is odd -+ var isYOdd = j & 1; -+ var isSecondKey = j >> 1; -+ if (r.cmp(this.curve.p.umod(this.curve.n)) >= 0 && isSecondKey) -+ throw new Error('Unable to find sencond key candinate'); -+ -+ // 1.1. Let x = r + jn. -+ if (isSecondKey) -+ r = this.curve.pointFromX(r.add(this.curve.n), isYOdd); -+ else -+ r = this.curve.pointFromX(r, isYOdd); -+ -+ var rInv = signature.r.invm(n); -+ var s1 = n.sub(e).mul(rInv).umod(n); -+ var s2 = s.mul(rInv).umod(n); -+ -+ // 1.6.1 Compute Q = r^-1 (sR - eG) -+ // Q = r^-1 (sR + -eG) -+ return this.g.mulAdd(s1, r, s2); -+}; -+ -+EC.prototype.getKeyRecoveryParam = function(e, signature, Q, enc) { -+ signature = new Signature(signature, enc); -+ if (signature.recoveryParam !== null) -+ return signature.recoveryParam; -+ -+ for (var i = 0; i < 4; i++) { -+ var Qprime; -+ try { -+ Qprime = this.recoverPubKey(e, signature, i); -+ } catch (e) { -+ continue; -+ } -+ -+ if (Qprime.eq(Q)) -+ return i; -+ } -+ throw new Error('Unable to find valid recovery factor'); -+}; -+ -+},{"../../elliptic":2,"./key":10,"./signature":11,"bn.js":1}],10:[function(require,module,exports){ -+'use strict'; -+ -+var BN = require('bn.js'); -+ -+function KeyPair(ec, options) { -+ this.ec = ec; -+ this.priv = null; -+ this.pub = null; -+ -+ // KeyPair(ec, { priv: ..., pub: ... }) -+ if (options.priv) -+ this._importPrivate(options.priv, options.privEnc); -+ if (options.pub) -+ this._importPublic(options.pub, options.pubEnc); -+} -+module.exports = KeyPair; -+ -+KeyPair.fromPublic = function fromPublic(ec, pub, enc) { -+ if (pub instanceof KeyPair) -+ return pub; -+ -+ return new KeyPair(ec, { -+ pub: pub, -+ pubEnc: enc -+ }); -+}; -+ -+KeyPair.fromPrivate = function fromPrivate(ec, priv, enc) { -+ if (priv instanceof KeyPair) -+ return priv; -+ -+ return new KeyPair(ec, { -+ priv: priv, -+ privEnc: enc -+ }); -+}; -+ -+KeyPair.prototype.validate = function validate() { -+ var pub = this.getPublic(); -+ -+ if (pub.isInfinity()) -+ return { result: false, reason: 'Invalid public key' }; -+ if (!pub.validate()) -+ return { result: false, reason: 'Public key is not a point' }; -+ if (!pub.mul(this.ec.curve.n).isInfinity()) -+ return { result: false, reason: 'Public key * N != O' }; -+ -+ return { result: true, reason: null }; -+}; -+ -+KeyPair.prototype.getPublic = function getPublic(compact, enc) { -+ // compact is optional argument -+ if (typeof compact === 'string') { -+ enc = compact; -+ compact = null; -+ } -+ -+ if (!this.pub) -+ this.pub = this.ec.g.mul(this.priv); -+ -+ if (!enc) -+ return this.pub; -+ -+ return this.pub.encode(enc, compact); -+}; -+ -+KeyPair.prototype.getPrivate = function getPrivate(enc) { -+ if (enc === 'hex') -+ return this.priv.toString(16, 2); -+ else -+ return this.priv; -+}; -+ -+KeyPair.prototype._importPrivate = function _importPrivate(key, enc) { -+ this.priv = new BN(key, enc || 16); -+ -+ // Ensure that the priv won't be bigger than n, otherwise we may fail -+ // in fixed multiplication method -+ this.priv = this.priv.umod(this.ec.curve.n); -+}; -+ -+KeyPair.prototype._importPublic = function _importPublic(key, enc) { -+ if (key.x || key.y) { -+ this.pub = this.ec.curve.point(key.x, key.y); -+ return; -+ } -+ this.pub = this.ec.curve.decodePoint(key, enc); -+}; -+ -+// ECDH -+KeyPair.prototype.derive = function derive(pub) { -+ return pub.mul(this.priv).getX(); -+}; -+ -+// ECDSA -+KeyPair.prototype.sign = function sign(msg, enc, options) { -+ return this.ec.sign(msg, this, enc, options); -+}; -+ -+KeyPair.prototype.verify = function verify(msg, signature) { -+ return this.ec.verify(msg, signature, this); -+}; -+ -+KeyPair.prototype.inspect = function inspect() { -+ return '<Key priv: ' + (this.priv && this.priv.toString(16, 2)) + -+ ' pub: ' + (this.pub && this.pub.inspect()) + ' >'; -+}; -+ -+},{"bn.js":1}],11:[function(require,module,exports){ -+'use strict'; -+ -+var BN = require('bn.js'); -+ -+var elliptic = require('../../elliptic'); -+var utils = elliptic.utils; -+var assert = utils.assert; -+ -+function Signature(options, enc) { -+ if (options instanceof Signature) -+ return options; -+ -+ if (this._importDER(options, enc)) -+ return; -+ -+ assert(options.r && options.s, 'Signature without r or s'); -+ this.r = new BN(options.r, 16); -+ this.s = new BN(options.s, 16); -+ if (options.recoveryParam === undefined) -+ this.recoveryParam = null; -+ else -+ this.recoveryParam = options.recoveryParam; -+} -+module.exports = Signature; -+ -+function Position() { -+ this.place = 0; -+} -+ -+function getLength(buf, p) { -+ var initial = buf[p.place++]; -+ if (!(initial & 0x80)) { -+ return initial; -+ } -+ var octetLen = initial & 0xf; -+ var val = 0; -+ for (var i = 0, off = p.place; i < octetLen; i++, off++) { -+ val <<= 8; -+ val |= buf[off]; -+ } -+ p.place = off; -+ return val; -+} -+ -+function rmPadding(buf) { -+ var i = 0; -+ var len = buf.length - 1; -+ while (!buf[i] && !(buf[i + 1] & 0x80) && i < len) { -+ i++; -+ } -+ if (i === 0) { -+ return buf; -+ } -+ return buf.slice(i); -+} -+ -+Signature.prototype._importDER = function _importDER(data, enc) { -+ data = utils.toArray(data, enc); -+ var p = new Position(); -+ if (data[p.place++] !== 0x30) { -+ return false; -+ } -+ var len = getLength(data, p); -+ if ((len + p.place) !== data.length) { -+ return false; -+ } -+ if (data[p.place++] !== 0x02) { -+ return false; -+ } -+ var rlen = getLength(data, p); -+ var r = data.slice(p.place, rlen + p.place); -+ p.place += rlen; -+ if (data[p.place++] !== 0x02) { -+ return false; -+ } -+ var slen = getLength(data, p); -+ if (data.length !== slen + p.place) { -+ return false; -+ } -+ var s = data.slice(p.place, slen + p.place); -+ if (r[0] === 0 && (r[1] & 0x80)) { -+ r = r.slice(1); -+ } -+ if (s[0] === 0 && (s[1] & 0x80)) { -+ s = s.slice(1); -+ } -+ -+ this.r = new BN(r); -+ this.s = new BN(s); -+ this.recoveryParam = null; -+ -+ return true; -+}; -+ -+function constructLength(arr, len) { -+ if (len < 0x80) { -+ arr.push(len); -+ return; -+ } -+ var octets = 1 + (Math.log(len) / Math.LN2 >>> 3); -+ arr.push(octets | 0x80); -+ while (--octets) { -+ arr.push((len >>> (octets << 3)) & 0xff); -+ } -+ arr.push(len); -+} -+ -+Signature.prototype.toDER = function toDER(enc) { -+ var r = this.r.toArray(); -+ var s = this.s.toArray(); -+ -+ // Pad values -+ if (r[0] & 0x80) -+ r = [ 0 ].concat(r); -+ // Pad values -+ if (s[0] & 0x80) -+ s = [ 0 ].concat(s); -+ -+ r = rmPadding(r); -+ s = rmPadding(s); -+ -+ while (!s[0] && !(s[1] & 0x80)) { -+ s = s.slice(1); -+ } -+ var arr = [ 0x02 ]; -+ constructLength(arr, r.length); -+ arr = arr.concat(r); -+ arr.push(0x02); -+ constructLength(arr, s.length); -+ var backHalf = arr.concat(s); -+ var res = [ 0x30 ]; -+ constructLength(res, backHalf.length); -+ res = res.concat(backHalf); -+ return utils.encode(res, enc); -+}; -+ -+},{"../../elliptic":2,"bn.js":1}],12:[function(require,module,exports){ -+'use strict'; -+ -+var hash = require('hash.js'); -+var elliptic = require('../../elliptic'); -+var utils = elliptic.utils; -+var assert = utils.assert; -+var parseBytes = utils.parseBytes; -+var KeyPair = require('./key'); -+var Signature = require('./signature'); -+ -+function EDDSA(curve) { -+ assert(curve === 'ed25519', 'only tested with ed25519 so far'); -+ -+ if (!(this instanceof EDDSA)) -+ return new EDDSA(curve); -+ -+ var curve = elliptic.curves[curve].curve; -+ this.curve = curve; -+ this.g = curve.g; -+ this.g.precompute(curve.n.bitLength() + 1); -+ -+ this.pointClass = curve.point().constructor; -+ this.encodingLength = Math.ceil(curve.n.bitLength() / 8); -+ this.hash = hash.sha512; -+} -+ -+module.exports = EDDSA; -+ -+/** -+* @param {Array|String} message - message bytes -+* @param {Array|String|KeyPair} secret - secret bytes or a keypair -+* @returns {Signature} - signature -+*/ -+EDDSA.prototype.sign = function sign(message, secret) { -+ message = parseBytes(message); -+ var key = this.keyFromSecret(secret); -+ var r = this.hashInt(key.messagePrefix(), message); -+ var R = this.g.mul(r); -+ var Rencoded = this.encodePoint(R); -+ var s_ = this.hashInt(Rencoded, key.pubBytes(), message) -+ .mul(key.priv()); -+ var S = r.add(s_).umod(this.curve.n); -+ return this.makeSignature({ R: R, S: S, Rencoded: Rencoded }); -+}; -+ -+/** -+* @param {Array} message - message bytes -+* @param {Array|String|Signature} sig - sig bytes -+* @param {Array|String|Point|KeyPair} pub - public key -+* @returns {Boolean} - true if public key matches sig of message -+*/ -+EDDSA.prototype.verify = function verify(message, sig, pub) { -+ message = parseBytes(message); -+ sig = this.makeSignature(sig); -+ var key = this.keyFromPublic(pub); -+ var h = this.hashInt(sig.Rencoded(), key.pubBytes(), message); -+ var SG = this.g.mul(sig.S()); -+ var RplusAh = sig.R().add(key.pub().mul(h)); -+ return RplusAh.eq(SG); -+}; -+ -+EDDSA.prototype.hashInt = function hashInt() { -+ var hash = this.hash(); -+ for (var i = 0; i < arguments.length; i++) -+ hash.update(arguments[i]); -+ return utils.intFromLE(hash.digest()).umod(this.curve.n); -+}; -+ -+EDDSA.prototype.keyFromPublic = function keyFromPublic(pub) { -+ return KeyPair.fromPublic(this, pub); -+}; -+ -+EDDSA.prototype.keyFromSecret = function keyFromSecret(secret) { -+ return KeyPair.fromSecret(this, secret); -+}; -+ -+EDDSA.prototype.makeSignature = function makeSignature(sig) { -+ if (sig instanceof Signature) -+ return sig; -+ return new Signature(this, sig); -+}; -+ -+/** -+* * https://tools.ietf.org/html/draft-josefsson-eddsa-ed25519-03#section-5.2 -+* -+* EDDSA defines methods for encoding and decoding points and integers. These are -+* helper convenience methods, that pass along to utility functions implied -+* parameters. -+* -+*/ -+EDDSA.prototype.encodePoint = function encodePoint(point) { -+ var enc = point.getY().toArray('le', this.encodingLength); -+ enc[this.encodingLength - 1] |= point.getX().isOdd() ? 0x80 : 0; -+ return enc; -+}; -+ -+EDDSA.prototype.decodePoint = function decodePoint(bytes) { -+ bytes = utils.parseBytes(bytes); -+ -+ var lastIx = bytes.length - 1; -+ var normed = bytes.slice(0, lastIx).concat(bytes[lastIx] & ~0x80); -+ var xIsOdd = (bytes[lastIx] & 0x80) !== 0; -+ -+ var y = utils.intFromLE(normed); -+ return this.curve.pointFromY(y, xIsOdd); -+}; -+ -+EDDSA.prototype.encodeInt = function encodeInt(num) { -+ return num.toArray('le', this.encodingLength); -+}; -+ -+EDDSA.prototype.decodeInt = function decodeInt(bytes) { -+ return utils.intFromLE(bytes); -+}; -+ -+EDDSA.prototype.isPoint = function isPoint(val) { -+ return val instanceof this.pointClass; -+}; -+ -+},{"../../elliptic":2,"./key":13,"./signature":14,"hash.js":19}],13:[function(require,module,exports){ -+'use strict'; -+ -+var elliptic = require('../../elliptic'); -+var utils = elliptic.utils; -+var assert = utils.assert; -+var parseBytes = utils.parseBytes; -+var cachedProperty = utils.cachedProperty; -+ -+/** -+* @param {EDDSA} eddsa - instance -+* @param {Object} params - public/private key parameters -+* -+* @param {Array<Byte>} [params.secret] - secret seed bytes -+* @param {Point} [params.pub] - public key point (aka `A` in eddsa terms) -+* @param {Array<Byte>} [params.pub] - public key point encoded as bytes -+* -+*/ -+function KeyPair(eddsa, params) { -+ this.eddsa = eddsa; -+ this._secret = parseBytes(params.secret); -+ if (eddsa.isPoint(params.pub)) -+ this._pub = params.pub; -+ else -+ this._pubBytes = parseBytes(params.pub); -+} -+ -+KeyPair.fromPublic = function fromPublic(eddsa, pub) { -+ if (pub instanceof KeyPair) -+ return pub; -+ return new KeyPair(eddsa, { pub: pub }); -+}; -+ -+KeyPair.fromSecret = function fromSecret(eddsa, secret) { -+ if (secret instanceof KeyPair) -+ return secret; -+ return new KeyPair(eddsa, { secret: secret }); -+}; -+ -+KeyPair.prototype.secret = function secret() { -+ return this._secret; -+}; -+ -+cachedProperty(KeyPair, 'pubBytes', function pubBytes() { -+ return this.eddsa.encodePoint(this.pub()); -+}); -+ -+cachedProperty(KeyPair, 'pub', function pub() { -+ if (this._pubBytes) -+ return this.eddsa.decodePoint(this._pubBytes); -+ return this.eddsa.g.mul(this.priv()); -+}); -+ -+cachedProperty(KeyPair, 'privBytes', function privBytes() { -+ var eddsa = this.eddsa; -+ var hash = this.hash(); -+ var lastIx = eddsa.encodingLength - 1; -+ -+ var a = hash.slice(0, eddsa.encodingLength); -+ a[0] &= 248; -+ a[lastIx] &= 127; -+ a[lastIx] |= 64; -+ -+ return a; -+}); -+ -+cachedProperty(KeyPair, 'priv', function priv() { -+ return this.eddsa.decodeInt(this.privBytes()); -+}); -+ -+cachedProperty(KeyPair, 'hash', function hash() { -+ return this.eddsa.hash().update(this.secret()).digest(); -+}); -+ -+cachedProperty(KeyPair, 'messagePrefix', function messagePrefix() { -+ return this.hash().slice(this.eddsa.encodingLength); -+}); -+ -+KeyPair.prototype.sign = function sign(message) { -+ assert(this._secret, 'KeyPair can only verify'); -+ return this.eddsa.sign(message, this); -+}; -+ -+KeyPair.prototype.verify = function verify(message, sig) { -+ return this.eddsa.verify(message, sig, this); -+}; -+ -+KeyPair.prototype.getSecret = function getSecret(enc) { -+ assert(this._secret, 'KeyPair is public only'); -+ return utils.encode(this.secret(), enc); -+}; -+ -+KeyPair.prototype.getPublic = function getPublic(enc) { -+ return utils.encode(this.pubBytes(), enc); -+}; -+ -+module.exports = KeyPair; -+ -+},{"../../elliptic":2}],14:[function(require,module,exports){ -+'use strict'; -+ -+var BN = require('bn.js'); -+var elliptic = require('../../elliptic'); -+var utils = elliptic.utils; -+var assert = utils.assert; -+var cachedProperty = utils.cachedProperty; -+var parseBytes = utils.parseBytes; -+ -+/** -+* @param {EDDSA} eddsa - eddsa instance -+* @param {Array<Bytes>|Object} sig - -+* @param {Array<Bytes>|Point} [sig.R] - R point as Point or bytes -+* @param {Array<Bytes>|bn} [sig.S] - S scalar as bn or bytes -+* @param {Array<Bytes>} [sig.Rencoded] - R point encoded -+* @param {Array<Bytes>} [sig.Sencoded] - S scalar encoded -+*/ -+function Signature(eddsa, sig) { -+ this.eddsa = eddsa; -+ -+ if (typeof sig !== 'object') -+ sig = parseBytes(sig); -+ -+ if (Array.isArray(sig)) { -+ sig = { -+ R: sig.slice(0, eddsa.encodingLength), -+ S: sig.slice(eddsa.encodingLength) -+ }; -+ } -+ -+ assert(sig.R && sig.S, 'Signature without R or S'); -+ -+ if (eddsa.isPoint(sig.R)) -+ this._R = sig.R; -+ if (sig.S instanceof BN) -+ this._S = sig.S; -+ -+ this._Rencoded = Array.isArray(sig.R) ? sig.R : sig.Rencoded; -+ this._Sencoded = Array.isArray(sig.S) ? sig.S : sig.Sencoded; -+} -+ -+cachedProperty(Signature, 'S', function S() { -+ return this.eddsa.decodeInt(this.Sencoded()); -+}); -+ -+cachedProperty(Signature, 'R', function R() { -+ return this.eddsa.decodePoint(this.Rencoded()); -+}); -+ -+cachedProperty(Signature, 'Rencoded', function Rencoded() { -+ return this.eddsa.encodePoint(this.R()); -+}); -+ -+cachedProperty(Signature, 'Sencoded', function Sencoded() { -+ return this.eddsa.encodeInt(this.S()); -+}); -+ -+Signature.prototype.toBytes = function toBytes() { -+ return this.Rencoded().concat(this.Sencoded()); -+}; -+ -+Signature.prototype.toHex = function toHex() { -+ return utils.encode(this.toBytes(), 'hex').toUpperCase(); -+}; -+ -+module.exports = Signature; -+ -+},{"../../elliptic":2,"bn.js":1}],15:[function(require,module,exports){ -+'use strict'; -+ -+var hash = require('hash.js'); -+var elliptic = require('../elliptic'); -+var utils = elliptic.utils; -+var assert = utils.assert; -+ -+function HmacDRBG(options) { -+ if (!(this instanceof HmacDRBG)) -+ return new HmacDRBG(options); -+ this.hash = options.hash; -+ this.predResist = !!options.predResist; -+ -+ this.outLen = this.hash.outSize; -+ this.minEntropy = options.minEntropy || this.hash.hmacStrength; -+ -+ this.reseed = null; -+ this.reseedInterval = null; -+ this.K = null; -+ this.V = null; -+ -+ var entropy = utils.toArray(options.entropy, options.entropyEnc); -+ var nonce = utils.toArray(options.nonce, options.nonceEnc); -+ var pers = utils.toArray(options.pers, options.persEnc); -+ assert(entropy.length >= (this.minEntropy / 8), -+ 'Not enough entropy. Minimum is: ' + this.minEntropy + ' bits'); -+ this._init(entropy, nonce, pers); -+} -+module.exports = HmacDRBG; -+ -+HmacDRBG.prototype._init = function init(entropy, nonce, pers) { -+ var seed = entropy.concat(nonce).concat(pers); -+ -+ this.K = new Array(this.outLen / 8); -+ this.V = new Array(this.outLen / 8); -+ for (var i = 0; i < this.V.length; i++) { -+ this.K[i] = 0x00; -+ this.V[i] = 0x01; -+ } -+ -+ this._update(seed); -+ this.reseed = 1; -+ this.reseedInterval = 0x1000000000000; // 2^48 -+}; -+ -+HmacDRBG.prototype._hmac = function hmac() { -+ return new hash.hmac(this.hash, this.K); -+}; -+ -+HmacDRBG.prototype._update = function update(seed) { -+ var kmac = this._hmac() -+ .update(this.V) -+ .update([ 0x00 ]); -+ if (seed) -+ kmac = kmac.update(seed); -+ this.K = kmac.digest(); -+ this.V = this._hmac().update(this.V).digest(); -+ if (!seed) -+ return; -+ -+ this.K = this._hmac() -+ .update(this.V) -+ .update([ 0x01 ]) -+ .update(seed) -+ .digest(); -+ this.V = this._hmac().update(this.V).digest(); -+}; -+ -+HmacDRBG.prototype.reseed = function reseed(entropy, entropyEnc, add, addEnc) { -+ // Optional entropy enc -+ if (typeof entropyEnc !== 'string') { -+ addEnc = add; -+ add = entropyEnc; -+ entropyEnc = null; -+ } -+ -+ entropy = utils.toBuffer(entropy, entropyEnc); -+ add = utils.toBuffer(add, addEnc); -+ -+ assert(entropy.length >= (this.minEntropy / 8), -+ 'Not enough entropy. Minimum is: ' + this.minEntropy + ' bits'); -+ -+ this._update(entropy.concat(add || [])); -+ this.reseed = 1; -+}; -+ -+HmacDRBG.prototype.generate = function generate(len, enc, add, addEnc) { -+ if (this.reseed > this.reseedInterval) -+ throw new Error('Reseed is required'); -+ -+ // Optional encoding -+ if (typeof enc !== 'string') { -+ addEnc = add; -+ add = enc; -+ enc = null; -+ } -+ -+ // Optional additional data -+ if (add) { -+ add = utils.toArray(add, addEnc); -+ this._update(add); -+ } -+ -+ var temp = []; -+ while (temp.length < len) { -+ this.V = this._hmac().update(this.V).digest(); -+ temp = temp.concat(this.V); -+ } -+ -+ var res = temp.slice(0, len); -+ this._update(add); -+ this.reseed++; -+ return utils.encode(res, enc); -+}; -+ -+},{"../elliptic":2,"hash.js":19}],16:[function(require,module,exports){ -+module.exports = { -+ doubles: { -+ step: 4, -+ points: [ -+ [ -+ 'e60fce93b59e9ec53011aabc21c23e97b2a31369b87a5ae9c44ee89e2a6dec0a', -+ 'f7e3507399e595929db99f34f57937101296891e44d23f0be1f32cce69616821' -+ ], -+ [ -+ '8282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508', -+ '11f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf' -+ ], -+ [ -+ '175e159f728b865a72f99cc6c6fc846de0b93833fd2222ed73fce5b551e5b739', -+ 'd3506e0d9e3c79eba4ef97a51ff71f5eacb5955add24345c6efa6ffee9fed695' -+ ], -+ [ -+ '363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640', -+ '4e273adfc732221953b445397f3363145b9a89008199ecb62003c7f3bee9de9' -+ ], -+ [ -+ '8b4b5f165df3c2be8c6244b5b745638843e4a781a15bcd1b69f79a55dffdf80c', -+ '4aad0a6f68d308b4b3fbd7813ab0da04f9e336546162ee56b3eff0c65fd4fd36' -+ ], -+ [ -+ '723cbaa6e5db996d6bf771c00bd548c7b700dbffa6c0e77bcb6115925232fcda', -+ '96e867b5595cc498a921137488824d6e2660a0653779494801dc069d9eb39f5f' -+ ], -+ [ -+ 'eebfa4d493bebf98ba5feec812c2d3b50947961237a919839a533eca0e7dd7fa', -+ '5d9a8ca3970ef0f269ee7edaf178089d9ae4cdc3a711f712ddfd4fdae1de8999' -+ ], -+ [ -+ '100f44da696e71672791d0a09b7bde459f1215a29b3c03bfefd7835b39a48db0', -+ 'cdd9e13192a00b772ec8f3300c090666b7ff4a18ff5195ac0fbd5cd62bc65a09' -+ ], -+ [ -+ 'e1031be262c7ed1b1dc9227a4a04c017a77f8d4464f3b3852c8acde6e534fd2d', -+ '9d7061928940405e6bb6a4176597535af292dd419e1ced79a44f18f29456a00d' -+ ], -+ [ -+ 'feea6cae46d55b530ac2839f143bd7ec5cf8b266a41d6af52d5e688d9094696d', -+ 'e57c6b6c97dce1bab06e4e12bf3ecd5c981c8957cc41442d3155debf18090088' -+ ], -+ [ -+ 'da67a91d91049cdcb367be4be6ffca3cfeed657d808583de33fa978bc1ec6cb1', -+ '9bacaa35481642bc41f463f7ec9780e5dec7adc508f740a17e9ea8e27a68be1d' -+ ], -+ [ -+ '53904faa0b334cdda6e000935ef22151ec08d0f7bb11069f57545ccc1a37b7c0', -+ '5bc087d0bc80106d88c9eccac20d3c1c13999981e14434699dcb096b022771c8' -+ ], -+ [ -+ '8e7bcd0bd35983a7719cca7764ca906779b53a043a9b8bcaeff959f43ad86047', -+ '10b7770b2a3da4b3940310420ca9514579e88e2e47fd68b3ea10047e8460372a' -+ ], -+ [ -+ '385eed34c1cdff21e6d0818689b81bde71a7f4f18397e6690a841e1599c43862', -+ '283bebc3e8ea23f56701de19e9ebf4576b304eec2086dc8cc0458fe5542e5453' -+ ], -+ [ -+ '6f9d9b803ecf191637c73a4413dfa180fddf84a5947fbc9c606ed86c3fac3a7', -+ '7c80c68e603059ba69b8e2a30e45c4d47ea4dd2f5c281002d86890603a842160' -+ ], -+ [ -+ '3322d401243c4e2582a2147c104d6ecbf774d163db0f5e5313b7e0e742d0e6bd', -+ '56e70797e9664ef5bfb019bc4ddaf9b72805f63ea2873af624f3a2e96c28b2a0' -+ ], -+ [ -+ '85672c7d2de0b7da2bd1770d89665868741b3f9af7643397721d74d28134ab83', -+ '7c481b9b5b43b2eb6374049bfa62c2e5e77f17fcc5298f44c8e3094f790313a6' -+ ], -+ [ -+ '948bf809b1988a46b06c9f1919413b10f9226c60f668832ffd959af60c82a0a', -+ '53a562856dcb6646dc6b74c5d1c3418c6d4dff08c97cd2bed4cb7f88d8c8e589' -+ ], -+ [ -+ '6260ce7f461801c34f067ce0f02873a8f1b0e44dfc69752accecd819f38fd8e8', -+ 'bc2da82b6fa5b571a7f09049776a1ef7ecd292238051c198c1a84e95b2b4ae17' -+ ], -+ [ -+ 'e5037de0afc1d8d43d8348414bbf4103043ec8f575bfdc432953cc8d2037fa2d', -+ '4571534baa94d3b5f9f98d09fb990bddbd5f5b03ec481f10e0e5dc841d755bda' -+ ], -+ [ -+ 'e06372b0f4a207adf5ea905e8f1771b4e7e8dbd1c6a6c5b725866a0ae4fce725', -+ '7a908974bce18cfe12a27bb2ad5a488cd7484a7787104870b27034f94eee31dd' -+ ], -+ [ -+ '213c7a715cd5d45358d0bbf9dc0ce02204b10bdde2a3f58540ad6908d0559754', -+ '4b6dad0b5ae462507013ad06245ba190bb4850f5f36a7eeddff2c27534b458f2' -+ ], -+ [ -+ '4e7c272a7af4b34e8dbb9352a5419a87e2838c70adc62cddf0cc3a3b08fbd53c', -+ '17749c766c9d0b18e16fd09f6def681b530b9614bff7dd33e0b3941817dcaae6' -+ ], -+ [ -+ 'fea74e3dbe778b1b10f238ad61686aa5c76e3db2be43057632427e2840fb27b6', -+ '6e0568db9b0b13297cf674deccb6af93126b596b973f7b77701d3db7f23cb96f' -+ ], -+ [ -+ '76e64113f677cf0e10a2570d599968d31544e179b760432952c02a4417bdde39', -+ 'c90ddf8dee4e95cf577066d70681f0d35e2a33d2b56d2032b4b1752d1901ac01' -+ ], -+ [ -+ 'c738c56b03b2abe1e8281baa743f8f9a8f7cc643df26cbee3ab150242bcbb891', -+ '893fb578951ad2537f718f2eacbfbbbb82314eef7880cfe917e735d9699a84c3' -+ ], -+ [ -+ 'd895626548b65b81e264c7637c972877d1d72e5f3a925014372e9f6588f6c14b', -+ 'febfaa38f2bc7eae728ec60818c340eb03428d632bb067e179363ed75d7d991f' -+ ], -+ [ -+ 'b8da94032a957518eb0f6433571e8761ceffc73693e84edd49150a564f676e03', -+ '2804dfa44805a1e4d7c99cc9762808b092cc584d95ff3b511488e4e74efdf6e7' -+ ], -+ [ -+ 'e80fea14441fb33a7d8adab9475d7fab2019effb5156a792f1a11778e3c0df5d', -+ 'eed1de7f638e00771e89768ca3ca94472d155e80af322ea9fcb4291b6ac9ec78' -+ ], -+ [ -+ 'a301697bdfcd704313ba48e51d567543f2a182031efd6915ddc07bbcc4e16070', -+ '7370f91cfb67e4f5081809fa25d40f9b1735dbf7c0a11a130c0d1a041e177ea1' -+ ], -+ [ -+ '90ad85b389d6b936463f9d0512678de208cc330b11307fffab7ac63e3fb04ed4', -+ 'e507a3620a38261affdcbd9427222b839aefabe1582894d991d4d48cb6ef150' -+ ], -+ [ -+ '8f68b9d2f63b5f339239c1ad981f162ee88c5678723ea3351b7b444c9ec4c0da', -+ '662a9f2dba063986de1d90c2b6be215dbbea2cfe95510bfdf23cbf79501fff82' -+ ], -+ [ -+ 'e4f3fb0176af85d65ff99ff9198c36091f48e86503681e3e6686fd5053231e11', -+ '1e63633ad0ef4f1c1661a6d0ea02b7286cc7e74ec951d1c9822c38576feb73bc' -+ ], -+ [ -+ '8c00fa9b18ebf331eb961537a45a4266c7034f2f0d4e1d0716fb6eae20eae29e', -+ 'efa47267fea521a1a9dc343a3736c974c2fadafa81e36c54e7d2a4c66702414b' -+ ], -+ [ -+ 'e7a26ce69dd4829f3e10cec0a9e98ed3143d084f308b92c0997fddfc60cb3e41', -+ '2a758e300fa7984b471b006a1aafbb18d0a6b2c0420e83e20e8a9421cf2cfd51' -+ ], -+ [ -+ 'b6459e0ee3662ec8d23540c223bcbdc571cbcb967d79424f3cf29eb3de6b80ef', -+ '67c876d06f3e06de1dadf16e5661db3c4b3ae6d48e35b2ff30bf0b61a71ba45' -+ ], -+ [ -+ 'd68a80c8280bb840793234aa118f06231d6f1fc67e73c5a5deda0f5b496943e8', -+ 'db8ba9fff4b586d00c4b1f9177b0e28b5b0e7b8f7845295a294c84266b133120' -+ ], -+ [ -+ '324aed7df65c804252dc0270907a30b09612aeb973449cea4095980fc28d3d5d', -+ '648a365774b61f2ff130c0c35aec1f4f19213b0c7e332843967224af96ab7c84' -+ ], -+ [ -+ '4df9c14919cde61f6d51dfdbe5fee5dceec4143ba8d1ca888e8bd373fd054c96', -+ '35ec51092d8728050974c23a1d85d4b5d506cdc288490192ebac06cad10d5d' -+ ], -+ [ -+ '9c3919a84a474870faed8a9c1cc66021523489054d7f0308cbfc99c8ac1f98cd', -+ 'ddb84f0f4a4ddd57584f044bf260e641905326f76c64c8e6be7e5e03d4fc599d' -+ ], -+ [ -+ '6057170b1dd12fdf8de05f281d8e06bb91e1493a8b91d4cc5a21382120a959e5', -+ '9a1af0b26a6a4807add9a2daf71df262465152bc3ee24c65e899be932385a2a8' -+ ], -+ [ -+ 'a576df8e23a08411421439a4518da31880cef0fba7d4df12b1a6973eecb94266', -+ '40a6bf20e76640b2c92b97afe58cd82c432e10a7f514d9f3ee8be11ae1b28ec8' -+ ], -+ [ -+ '7778a78c28dec3e30a05fe9629de8c38bb30d1f5cf9a3a208f763889be58ad71', -+ '34626d9ab5a5b22ff7098e12f2ff580087b38411ff24ac563b513fc1fd9f43ac' -+ ], -+ [ -+ '928955ee637a84463729fd30e7afd2ed5f96274e5ad7e5cb09eda9c06d903ac', -+ 'c25621003d3f42a827b78a13093a95eeac3d26efa8a8d83fc5180e935bcd091f' -+ ], -+ [ -+ '85d0fef3ec6db109399064f3a0e3b2855645b4a907ad354527aae75163d82751', -+ '1f03648413a38c0be29d496e582cf5663e8751e96877331582c237a24eb1f962' -+ ], -+ [ -+ 'ff2b0dce97eece97c1c9b6041798b85dfdfb6d8882da20308f5404824526087e', -+ '493d13fef524ba188af4c4dc54d07936c7b7ed6fb90e2ceb2c951e01f0c29907' -+ ], -+ [ -+ '827fbbe4b1e880ea9ed2b2e6301b212b57f1ee148cd6dd28780e5e2cf856e241', -+ 'c60f9c923c727b0b71bef2c67d1d12687ff7a63186903166d605b68baec293ec' -+ ], -+ [ -+ 'eaa649f21f51bdbae7be4ae34ce6e5217a58fdce7f47f9aa7f3b58fa2120e2b3', -+ 'be3279ed5bbbb03ac69a80f89879aa5a01a6b965f13f7e59d47a5305ba5ad93d' -+ ], -+ [ -+ 'e4a42d43c5cf169d9391df6decf42ee541b6d8f0c9a137401e23632dda34d24f', -+ '4d9f92e716d1c73526fc99ccfb8ad34ce886eedfa8d8e4f13a7f7131deba9414' -+ ], -+ [ -+ '1ec80fef360cbdd954160fadab352b6b92b53576a88fea4947173b9d4300bf19', -+ 'aeefe93756b5340d2f3a4958a7abbf5e0146e77f6295a07b671cdc1cc107cefd' -+ ], -+ [ -+ '146a778c04670c2f91b00af4680dfa8bce3490717d58ba889ddb5928366642be', -+ 'b318e0ec3354028add669827f9d4b2870aaa971d2f7e5ed1d0b297483d83efd0' -+ ], -+ [ -+ 'fa50c0f61d22e5f07e3acebb1aa07b128d0012209a28b9776d76a8793180eef9', -+ '6b84c6922397eba9b72cd2872281a68a5e683293a57a213b38cd8d7d3f4f2811' -+ ], -+ [ -+ 'da1d61d0ca721a11b1a5bf6b7d88e8421a288ab5d5bba5220e53d32b5f067ec2', -+ '8157f55a7c99306c79c0766161c91e2966a73899d279b48a655fba0f1ad836f1' -+ ], -+ [ -+ 'a8e282ff0c9706907215ff98e8fd416615311de0446f1e062a73b0610d064e13', -+ '7f97355b8db81c09abfb7f3c5b2515888b679a3e50dd6bd6cef7c73111f4cc0c' -+ ], -+ [ -+ '174a53b9c9a285872d39e56e6913cab15d59b1fa512508c022f382de8319497c', -+ 'ccc9dc37abfc9c1657b4155f2c47f9e6646b3a1d8cb9854383da13ac079afa73' -+ ], -+ [ -+ '959396981943785c3d3e57edf5018cdbe039e730e4918b3d884fdff09475b7ba', -+ '2e7e552888c331dd8ba0386a4b9cd6849c653f64c8709385e9b8abf87524f2fd' -+ ], -+ [ -+ 'd2a63a50ae401e56d645a1153b109a8fcca0a43d561fba2dbb51340c9d82b151', -+ 'e82d86fb6443fcb7565aee58b2948220a70f750af484ca52d4142174dcf89405' -+ ], -+ [ -+ '64587e2335471eb890ee7896d7cfdc866bacbdbd3839317b3436f9b45617e073', -+ 'd99fcdd5bf6902e2ae96dd6447c299a185b90a39133aeab358299e5e9faf6589' -+ ], -+ [ -+ '8481bde0e4e4d885b3a546d3e549de042f0aa6cea250e7fd358d6c86dd45e458', -+ '38ee7b8cba5404dd84a25bf39cecb2ca900a79c42b262e556d64b1b59779057e' -+ ], -+ [ -+ '13464a57a78102aa62b6979ae817f4637ffcfed3c4b1ce30bcd6303f6caf666b', -+ '69be159004614580ef7e433453ccb0ca48f300a81d0942e13f495a907f6ecc27' -+ ], -+ [ -+ 'bc4a9df5b713fe2e9aef430bcc1dc97a0cd9ccede2f28588cada3a0d2d83f366', -+ 'd3a81ca6e785c06383937adf4b798caa6e8a9fbfa547b16d758d666581f33c1' -+ ], -+ [ -+ '8c28a97bf8298bc0d23d8c749452a32e694b65e30a9472a3954ab30fe5324caa', -+ '40a30463a3305193378fedf31f7cc0eb7ae784f0451cb9459e71dc73cbef9482' -+ ], -+ [ -+ '8ea9666139527a8c1dd94ce4f071fd23c8b350c5a4bb33748c4ba111faccae0', -+ '620efabbc8ee2782e24e7c0cfb95c5d735b783be9cf0f8e955af34a30e62b945' -+ ], -+ [ -+ 'dd3625faef5ba06074669716bbd3788d89bdde815959968092f76cc4eb9a9787', -+ '7a188fa3520e30d461da2501045731ca941461982883395937f68d00c644a573' -+ ], -+ [ -+ 'f710d79d9eb962297e4f6232b40e8f7feb2bc63814614d692c12de752408221e', -+ 'ea98e67232d3b3295d3b535532115ccac8612c721851617526ae47a9c77bfc82' -+ ] -+ ] -+ }, -+ naf: { -+ wnd: 7, -+ points: [ -+ [ -+ 'f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9', -+ '388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672' -+ ], -+ [ -+ '2f8bde4d1a07209355b4a7250a5c5128e88b84bddc619ab7cba8d569b240efe4', -+ 'd8ac222636e5e3d6d4dba9dda6c9c426f788271bab0d6840dca87d3aa6ac62d6' -+ ], -+ [ -+ '5cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc', -+ '6aebca40ba255960a3178d6d861a54dba813d0b813fde7b5a5082628087264da' -+ ], -+ [ -+ 'acd484e2f0c7f65309ad178a9f559abde09796974c57e714c35f110dfc27ccbe', -+ 'cc338921b0a7d9fd64380971763b61e9add888a4375f8e0f05cc262ac64f9c37' -+ ], -+ [ -+ '774ae7f858a9411e5ef4246b70c65aac5649980be5c17891bbec17895da008cb', -+ 'd984a032eb6b5e190243dd56d7b7b365372db1e2dff9d6a8301d74c9c953c61b' -+ ], -+ [ -+ 'f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8', -+ 'ab0902e8d880a89758212eb65cdaf473a1a06da521fa91f29b5cb52db03ed81' -+ ], -+ [ -+ 'd7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e', -+ '581e2872a86c72a683842ec228cc6defea40af2bd896d3a5c504dc9ff6a26b58' -+ ], -+ [ -+ 'defdea4cdb677750a420fee807eacf21eb9898ae79b9768766e4faa04a2d4a34', -+ '4211ab0694635168e997b0ead2a93daeced1f4a04a95c0f6cfb199f69e56eb77' -+ ], -+ [ -+ '2b4ea0a797a443d293ef5cff444f4979f06acfebd7e86d277475656138385b6c', -+ '85e89bc037945d93b343083b5a1c86131a01f60c50269763b570c854e5c09b7a' -+ ], -+ [ -+ '352bbf4a4cdd12564f93fa332ce333301d9ad40271f8107181340aef25be59d5', -+ '321eb4075348f534d59c18259dda3e1f4a1b3b2e71b1039c67bd3d8bcf81998c' -+ ], -+ [ -+ '2fa2104d6b38d11b0230010559879124e42ab8dfeff5ff29dc9cdadd4ecacc3f', -+ '2de1068295dd865b64569335bd5dd80181d70ecfc882648423ba76b532b7d67' -+ ], -+ [ -+ '9248279b09b4d68dab21a9b066edda83263c3d84e09572e269ca0cd7f5453714', -+ '73016f7bf234aade5d1aa71bdea2b1ff3fc0de2a887912ffe54a32ce97cb3402' -+ ], -+ [ -+ 'daed4f2be3a8bf278e70132fb0beb7522f570e144bf615c07e996d443dee8729', -+ 'a69dce4a7d6c98e8d4a1aca87ef8d7003f83c230f3afa726ab40e52290be1c55' -+ ], -+ [ -+ 'c44d12c7065d812e8acf28d7cbb19f9011ecd9e9fdf281b0e6a3b5e87d22e7db', -+ '2119a460ce326cdc76c45926c982fdac0e106e861edf61c5a039063f0e0e6482' -+ ], -+ [ -+ '6a245bf6dc698504c89a20cfded60853152b695336c28063b61c65cbd269e6b4', -+ 'e022cf42c2bd4a708b3f5126f16a24ad8b33ba48d0423b6efd5e6348100d8a82' -+ ], -+ [ -+ '1697ffa6fd9de627c077e3d2fe541084ce13300b0bec1146f95ae57f0d0bd6a5', -+ 'b9c398f186806f5d27561506e4557433a2cf15009e498ae7adee9d63d01b2396' -+ ], -+ [ -+ '605bdb019981718b986d0f07e834cb0d9deb8360ffb7f61df982345ef27a7479', -+ '2972d2de4f8d20681a78d93ec96fe23c26bfae84fb14db43b01e1e9056b8c49' -+ ], -+ [ -+ '62d14dab4150bf497402fdc45a215e10dcb01c354959b10cfe31c7e9d87ff33d', -+ '80fc06bd8cc5b01098088a1950eed0db01aa132967ab472235f5642483b25eaf' -+ ], -+ [ -+ '80c60ad0040f27dade5b4b06c408e56b2c50e9f56b9b8b425e555c2f86308b6f', -+ '1c38303f1cc5c30f26e66bad7fe72f70a65eed4cbe7024eb1aa01f56430bd57a' -+ ], -+ [ -+ '7a9375ad6167ad54aa74c6348cc54d344cc5dc9487d847049d5eabb0fa03c8fb', -+ 'd0e3fa9eca8726909559e0d79269046bdc59ea10c70ce2b02d499ec224dc7f7' -+ ], -+ [ -+ 'd528ecd9b696b54c907a9ed045447a79bb408ec39b68df504bb51f459bc3ffc9', -+ 'eecf41253136e5f99966f21881fd656ebc4345405c520dbc063465b521409933' -+ ], -+ [ -+ '49370a4b5f43412ea25f514e8ecdad05266115e4a7ecb1387231808f8b45963', -+ '758f3f41afd6ed428b3081b0512fd62a54c3f3afbb5b6764b653052a12949c9a' -+ ], -+ [ -+ '77f230936ee88cbbd73df930d64702ef881d811e0e1498e2f1c13eb1fc345d74', -+ '958ef42a7886b6400a08266e9ba1b37896c95330d97077cbbe8eb3c7671c60d6' -+ ], -+ [ -+ 'f2dac991cc4ce4b9ea44887e5c7c0bce58c80074ab9d4dbaeb28531b7739f530', -+ 'e0dedc9b3b2f8dad4da1f32dec2531df9eb5fbeb0598e4fd1a117dba703a3c37' -+ ], -+ [ -+ '463b3d9f662621fb1b4be8fbbe2520125a216cdfc9dae3debcba4850c690d45b', -+ '5ed430d78c296c3543114306dd8622d7c622e27c970a1de31cb377b01af7307e' -+ ], -+ [ -+ 'f16f804244e46e2a09232d4aff3b59976b98fac14328a2d1a32496b49998f247', -+ 'cedabd9b82203f7e13d206fcdf4e33d92a6c53c26e5cce26d6579962c4e31df6' -+ ], -+ [ -+ 'caf754272dc84563b0352b7a14311af55d245315ace27c65369e15f7151d41d1', -+ 'cb474660ef35f5f2a41b643fa5e460575f4fa9b7962232a5c32f908318a04476' -+ ], -+ [ -+ '2600ca4b282cb986f85d0f1709979d8b44a09c07cb86d7c124497bc86f082120', -+ '4119b88753c15bd6a693b03fcddbb45d5ac6be74ab5f0ef44b0be9475a7e4b40' -+ ], -+ [ -+ '7635ca72d7e8432c338ec53cd12220bc01c48685e24f7dc8c602a7746998e435', -+ '91b649609489d613d1d5e590f78e6d74ecfc061d57048bad9e76f302c5b9c61' -+ ], -+ [ -+ '754e3239f325570cdbbf4a87deee8a66b7f2b33479d468fbc1a50743bf56cc18', -+ '673fb86e5bda30fb3cd0ed304ea49a023ee33d0197a695d0c5d98093c536683' -+ ], -+ [ -+ 'e3e6bd1071a1e96aff57859c82d570f0330800661d1c952f9fe2694691d9b9e8', -+ '59c9e0bba394e76f40c0aa58379a3cb6a5a2283993e90c4167002af4920e37f5' -+ ], -+ [ -+ '186b483d056a033826ae73d88f732985c4ccb1f32ba35f4b4cc47fdcf04aa6eb', -+ '3b952d32c67cf77e2e17446e204180ab21fb8090895138b4a4a797f86e80888b' -+ ], -+ [ -+ 'df9d70a6b9876ce544c98561f4be4f725442e6d2b737d9c91a8321724ce0963f', -+ '55eb2dafd84d6ccd5f862b785dc39d4ab157222720ef9da217b8c45cf2ba2417' -+ ], -+ [ -+ '5edd5cc23c51e87a497ca815d5dce0f8ab52554f849ed8995de64c5f34ce7143', -+ 'efae9c8dbc14130661e8cec030c89ad0c13c66c0d17a2905cdc706ab7399a868' -+ ], -+ [ -+ '290798c2b6476830da12fe02287e9e777aa3fba1c355b17a722d362f84614fba', -+ 'e38da76dcd440621988d00bcf79af25d5b29c094db2a23146d003afd41943e7a' -+ ], -+ [ -+ 'af3c423a95d9f5b3054754efa150ac39cd29552fe360257362dfdecef4053b45', -+ 'f98a3fd831eb2b749a93b0e6f35cfb40c8cd5aa667a15581bc2feded498fd9c6' -+ ], -+ [ -+ '766dbb24d134e745cccaa28c99bf274906bb66b26dcf98df8d2fed50d884249a', -+ '744b1152eacbe5e38dcc887980da38b897584a65fa06cedd2c924f97cbac5996' -+ ], -+ [ -+ '59dbf46f8c94759ba21277c33784f41645f7b44f6c596a58ce92e666191abe3e', -+ 'c534ad44175fbc300f4ea6ce648309a042ce739a7919798cd85e216c4a307f6e' -+ ], -+ [ -+ 'f13ada95103c4537305e691e74e9a4a8dd647e711a95e73cb62dc6018cfd87b8', -+ 'e13817b44ee14de663bf4bc808341f326949e21a6a75c2570778419bdaf5733d' -+ ], -+ [ -+ '7754b4fa0e8aced06d4167a2c59cca4cda1869c06ebadfb6488550015a88522c', -+ '30e93e864e669d82224b967c3020b8fa8d1e4e350b6cbcc537a48b57841163a2' -+ ], -+ [ -+ '948dcadf5990e048aa3874d46abef9d701858f95de8041d2a6828c99e2262519', -+ 'e491a42537f6e597d5d28a3224b1bc25df9154efbd2ef1d2cbba2cae5347d57e' -+ ], -+ [ -+ '7962414450c76c1689c7b48f8202ec37fb224cf5ac0bfa1570328a8a3d7c77ab', -+ '100b610ec4ffb4760d5c1fc133ef6f6b12507a051f04ac5760afa5b29db83437' -+ ], -+ [ -+ '3514087834964b54b15b160644d915485a16977225b8847bb0dd085137ec47ca', -+ 'ef0afbb2056205448e1652c48e8127fc6039e77c15c2378b7e7d15a0de293311' -+ ], -+ [ -+ 'd3cc30ad6b483e4bc79ce2c9dd8bc54993e947eb8df787b442943d3f7b527eaf', -+ '8b378a22d827278d89c5e9be8f9508ae3c2ad46290358630afb34db04eede0a4' -+ ], -+ [ -+ '1624d84780732860ce1c78fcbfefe08b2b29823db913f6493975ba0ff4847610', -+ '68651cf9b6da903e0914448c6cd9d4ca896878f5282be4c8cc06e2a404078575' -+ ], -+ [ -+ '733ce80da955a8a26902c95633e62a985192474b5af207da6df7b4fd5fc61cd4', -+ 'f5435a2bd2badf7d485a4d8b8db9fcce3e1ef8e0201e4578c54673bc1dc5ea1d' -+ ], -+ [ -+ '15d9441254945064cf1a1c33bbd3b49f8966c5092171e699ef258dfab81c045c', -+ 'd56eb30b69463e7234f5137b73b84177434800bacebfc685fc37bbe9efe4070d' -+ ], -+ [ -+ 'a1d0fcf2ec9de675b612136e5ce70d271c21417c9d2b8aaaac138599d0717940', -+ 'edd77f50bcb5a3cab2e90737309667f2641462a54070f3d519212d39c197a629' -+ ], -+ [ -+ 'e22fbe15c0af8ccc5780c0735f84dbe9a790badee8245c06c7ca37331cb36980', -+ 'a855babad5cd60c88b430a69f53a1a7a38289154964799be43d06d77d31da06' -+ ], -+ [ -+ '311091dd9860e8e20ee13473c1155f5f69635e394704eaa74009452246cfa9b3', -+ '66db656f87d1f04fffd1f04788c06830871ec5a64feee685bd80f0b1286d8374' -+ ], -+ [ -+ '34c1fd04d301be89b31c0442d3e6ac24883928b45a9340781867d4232ec2dbdf', -+ '9414685e97b1b5954bd46f730174136d57f1ceeb487443dc5321857ba73abee' -+ ], -+ [ -+ 'f219ea5d6b54701c1c14de5b557eb42a8d13f3abbcd08affcc2a5e6b049b8d63', -+ '4cb95957e83d40b0f73af4544cccf6b1f4b08d3c07b27fb8d8c2962a400766d1' -+ ], -+ [ -+ 'd7b8740f74a8fbaab1f683db8f45de26543a5490bca627087236912469a0b448', -+ 'fa77968128d9c92ee1010f337ad4717eff15db5ed3c049b3411e0315eaa4593b' -+ ], -+ [ -+ '32d31c222f8f6f0ef86f7c98d3a3335ead5bcd32abdd94289fe4d3091aa824bf', -+ '5f3032f5892156e39ccd3d7915b9e1da2e6dac9e6f26e961118d14b8462e1661' -+ ], -+ [ -+ '7461f371914ab32671045a155d9831ea8793d77cd59592c4340f86cbc18347b5', -+ '8ec0ba238b96bec0cbdddcae0aa442542eee1ff50c986ea6b39847b3cc092ff6' -+ ], -+ [ -+ 'ee079adb1df1860074356a25aa38206a6d716b2c3e67453d287698bad7b2b2d6', -+ '8dc2412aafe3be5c4c5f37e0ecc5f9f6a446989af04c4e25ebaac479ec1c8c1e' -+ ], -+ [ -+ '16ec93e447ec83f0467b18302ee620f7e65de331874c9dc72bfd8616ba9da6b5', -+ '5e4631150e62fb40d0e8c2a7ca5804a39d58186a50e497139626778e25b0674d' -+ ], -+ [ -+ 'eaa5f980c245f6f038978290afa70b6bd8855897f98b6aa485b96065d537bd99', -+ 'f65f5d3e292c2e0819a528391c994624d784869d7e6ea67fb18041024edc07dc' -+ ], -+ [ -+ '78c9407544ac132692ee1910a02439958ae04877151342ea96c4b6b35a49f51', -+ 'f3e0319169eb9b85d5404795539a5e68fa1fbd583c064d2462b675f194a3ddb4' -+ ], -+ [ -+ '494f4be219a1a77016dcd838431aea0001cdc8ae7a6fc688726578d9702857a5', -+ '42242a969283a5f339ba7f075e36ba2af925ce30d767ed6e55f4b031880d562c' -+ ], -+ [ -+ 'a598a8030da6d86c6bc7f2f5144ea549d28211ea58faa70ebf4c1e665c1fe9b5', -+ '204b5d6f84822c307e4b4a7140737aec23fc63b65b35f86a10026dbd2d864e6b' -+ ], -+ [ -+ 'c41916365abb2b5d09192f5f2dbeafec208f020f12570a184dbadc3e58595997', -+ '4f14351d0087efa49d245b328984989d5caf9450f34bfc0ed16e96b58fa9913' -+ ], -+ [ -+ '841d6063a586fa475a724604da03bc5b92a2e0d2e0a36acfe4c73a5514742881', -+ '73867f59c0659e81904f9a1c7543698e62562d6744c169ce7a36de01a8d6154' -+ ], -+ [ -+ '5e95bb399a6971d376026947f89bde2f282b33810928be4ded112ac4d70e20d5', -+ '39f23f366809085beebfc71181313775a99c9aed7d8ba38b161384c746012865' -+ ], -+ [ -+ '36e4641a53948fd476c39f8a99fd974e5ec07564b5315d8bf99471bca0ef2f66', -+ 'd2424b1b1abe4eb8164227b085c9aa9456ea13493fd563e06fd51cf5694c78fc' -+ ], -+ [ -+ '336581ea7bfbbb290c191a2f507a41cf5643842170e914faeab27c2c579f726', -+ 'ead12168595fe1be99252129b6e56b3391f7ab1410cd1e0ef3dcdcabd2fda224' -+ ], -+ [ -+ '8ab89816dadfd6b6a1f2634fcf00ec8403781025ed6890c4849742706bd43ede', -+ '6fdcef09f2f6d0a044e654aef624136f503d459c3e89845858a47a9129cdd24e' -+ ], -+ [ -+ '1e33f1a746c9c5778133344d9299fcaa20b0938e8acff2544bb40284b8c5fb94', -+ '60660257dd11b3aa9c8ed618d24edff2306d320f1d03010e33a7d2057f3b3b6' -+ ], -+ [ -+ '85b7c1dcb3cec1b7ee7f30ded79dd20a0ed1f4cc18cbcfcfa410361fd8f08f31', -+ '3d98a9cdd026dd43f39048f25a8847f4fcafad1895d7a633c6fed3c35e999511' -+ ], -+ [ -+ '29df9fbd8d9e46509275f4b125d6d45d7fbe9a3b878a7af872a2800661ac5f51', -+ 'b4c4fe99c775a606e2d8862179139ffda61dc861c019e55cd2876eb2a27d84b' -+ ], -+ [ -+ 'a0b1cae06b0a847a3fea6e671aaf8adfdfe58ca2f768105c8082b2e449fce252', -+ 'ae434102edde0958ec4b19d917a6a28e6b72da1834aff0e650f049503a296cf2' -+ ], -+ [ -+ '4e8ceafb9b3e9a136dc7ff67e840295b499dfb3b2133e4ba113f2e4c0e121e5', -+ 'cf2174118c8b6d7a4b48f6d534ce5c79422c086a63460502b827ce62a326683c' -+ ], -+ [ -+ 'd24a44e047e19b6f5afb81c7ca2f69080a5076689a010919f42725c2b789a33b', -+ '6fb8d5591b466f8fc63db50f1c0f1c69013f996887b8244d2cdec417afea8fa3' -+ ], -+ [ -+ 'ea01606a7a6c9cdd249fdfcfacb99584001edd28abbab77b5104e98e8e3b35d4', -+ '322af4908c7312b0cfbfe369f7a7b3cdb7d4494bc2823700cfd652188a3ea98d' -+ ], -+ [ -+ 'af8addbf2b661c8a6c6328655eb96651252007d8c5ea31be4ad196de8ce2131f', -+ '6749e67c029b85f52a034eafd096836b2520818680e26ac8f3dfbcdb71749700' -+ ], -+ [ -+ 'e3ae1974566ca06cc516d47e0fb165a674a3dabcfca15e722f0e3450f45889', -+ '2aeabe7e4531510116217f07bf4d07300de97e4874f81f533420a72eeb0bd6a4' -+ ], -+ [ -+ '591ee355313d99721cf6993ffed1e3e301993ff3ed258802075ea8ced397e246', -+ 'b0ea558a113c30bea60fc4775460c7901ff0b053d25ca2bdeee98f1a4be5d196' -+ ], -+ [ -+ '11396d55fda54c49f19aa97318d8da61fa8584e47b084945077cf03255b52984', -+ '998c74a8cd45ac01289d5833a7beb4744ff536b01b257be4c5767bea93ea57a4' -+ ], -+ [ -+ '3c5d2a1ba39c5a1790000738c9e0c40b8dcdfd5468754b6405540157e017aa7a', -+ 'b2284279995a34e2f9d4de7396fc18b80f9b8b9fdd270f6661f79ca4c81bd257' -+ ], -+ [ -+ 'cc8704b8a60a0defa3a99a7299f2e9c3fbc395afb04ac078425ef8a1793cc030', -+ 'bdd46039feed17881d1e0862db347f8cf395b74fc4bcdc4e940b74e3ac1f1b13' -+ ], -+ [ -+ 'c533e4f7ea8555aacd9777ac5cad29b97dd4defccc53ee7ea204119b2889b197', -+ '6f0a256bc5efdf429a2fb6242f1a43a2d9b925bb4a4b3a26bb8e0f45eb596096' -+ ], -+ [ -+ 'c14f8f2ccb27d6f109f6d08d03cc96a69ba8c34eec07bbcf566d48e33da6593', -+ 'c359d6923bb398f7fd4473e16fe1c28475b740dd098075e6c0e8649113dc3a38' -+ ], -+ [ -+ 'a6cbc3046bc6a450bac24789fa17115a4c9739ed75f8f21ce441f72e0b90e6ef', -+ '21ae7f4680e889bb130619e2c0f95a360ceb573c70603139862afd617fa9b9f' -+ ], -+ [ -+ '347d6d9a02c48927ebfb86c1359b1caf130a3c0267d11ce6344b39f99d43cc38', -+ '60ea7f61a353524d1c987f6ecec92f086d565ab687870cb12689ff1e31c74448' -+ ], -+ [ -+ 'da6545d2181db8d983f7dcb375ef5866d47c67b1bf31c8cf855ef7437b72656a', -+ '49b96715ab6878a79e78f07ce5680c5d6673051b4935bd897fea824b77dc208a' -+ ], -+ [ -+ 'c40747cc9d012cb1a13b8148309c6de7ec25d6945d657146b9d5994b8feb1111', -+ '5ca560753be2a12fc6de6caf2cb489565db936156b9514e1bb5e83037e0fa2d4' -+ ], -+ [ -+ '4e42c8ec82c99798ccf3a610be870e78338c7f713348bd34c8203ef4037f3502', -+ '7571d74ee5e0fb92a7a8b33a07783341a5492144cc54bcc40a94473693606437' -+ ], -+ [ -+ '3775ab7089bc6af823aba2e1af70b236d251cadb0c86743287522a1b3b0dedea', -+ 'be52d107bcfa09d8bcb9736a828cfa7fac8db17bf7a76a2c42ad961409018cf7' -+ ], -+ [ -+ 'cee31cbf7e34ec379d94fb814d3d775ad954595d1314ba8846959e3e82f74e26', -+ '8fd64a14c06b589c26b947ae2bcf6bfa0149ef0be14ed4d80f448a01c43b1c6d' -+ ], -+ [ -+ 'b4f9eaea09b6917619f6ea6a4eb5464efddb58fd45b1ebefcdc1a01d08b47986', -+ '39e5c9925b5a54b07433a4f18c61726f8bb131c012ca542eb24a8ac07200682a' -+ ], -+ [ -+ 'd4263dfc3d2df923a0179a48966d30ce84e2515afc3dccc1b77907792ebcc60e', -+ '62dfaf07a0f78feb30e30d6295853ce189e127760ad6cf7fae164e122a208d54' -+ ], -+ [ -+ '48457524820fa65a4f8d35eb6930857c0032acc0a4a2de422233eeda897612c4', -+ '25a748ab367979d98733c38a1fa1c2e7dc6cc07db2d60a9ae7a76aaa49bd0f77' -+ ], -+ [ -+ 'dfeeef1881101f2cb11644f3a2afdfc2045e19919152923f367a1767c11cceda', -+ 'ecfb7056cf1de042f9420bab396793c0c390bde74b4bbdff16a83ae09a9a7517' -+ ], -+ [ -+ '6d7ef6b17543f8373c573f44e1f389835d89bcbc6062ced36c82df83b8fae859', -+ 'cd450ec335438986dfefa10c57fea9bcc521a0959b2d80bbf74b190dca712d10' -+ ], -+ [ -+ 'e75605d59102a5a2684500d3b991f2e3f3c88b93225547035af25af66e04541f', -+ 'f5c54754a8f71ee540b9b48728473e314f729ac5308b06938360990e2bfad125' -+ ], -+ [ -+ 'eb98660f4c4dfaa06a2be453d5020bc99a0c2e60abe388457dd43fefb1ed620c', -+ '6cb9a8876d9cb8520609af3add26cd20a0a7cd8a9411131ce85f44100099223e' -+ ], -+ [ -+ '13e87b027d8514d35939f2e6892b19922154596941888336dc3563e3b8dba942', -+ 'fef5a3c68059a6dec5d624114bf1e91aac2b9da568d6abeb2570d55646b8adf1' -+ ], -+ [ -+ 'ee163026e9fd6fe017c38f06a5be6fc125424b371ce2708e7bf4491691e5764a', -+ '1acb250f255dd61c43d94ccc670d0f58f49ae3fa15b96623e5430da0ad6c62b2' -+ ], -+ [ -+ 'b268f5ef9ad51e4d78de3a750c2dc89b1e626d43505867999932e5db33af3d80', -+ '5f310d4b3c99b9ebb19f77d41c1dee018cf0d34fd4191614003e945a1216e423' -+ ], -+ [ -+ 'ff07f3118a9df035e9fad85eb6c7bfe42b02f01ca99ceea3bf7ffdba93c4750d', -+ '438136d603e858a3a5c440c38eccbaddc1d2942114e2eddd4740d098ced1f0d8' -+ ], -+ [ -+ '8d8b9855c7c052a34146fd20ffb658bea4b9f69e0d825ebec16e8c3ce2b526a1', -+ 'cdb559eedc2d79f926baf44fb84ea4d44bcf50fee51d7ceb30e2e7f463036758' -+ ], -+ [ -+ '52db0b5384dfbf05bfa9d472d7ae26dfe4b851ceca91b1eba54263180da32b63', -+ 'c3b997d050ee5d423ebaf66a6db9f57b3180c902875679de924b69d84a7b375' -+ ], -+ [ -+ 'e62f9490d3d51da6395efd24e80919cc7d0f29c3f3fa48c6fff543becbd43352', -+ '6d89ad7ba4876b0b22c2ca280c682862f342c8591f1daf5170e07bfd9ccafa7d' -+ ], -+ [ -+ '7f30ea2476b399b4957509c88f77d0191afa2ff5cb7b14fd6d8e7d65aaab1193', -+ 'ca5ef7d4b231c94c3b15389a5f6311e9daff7bb67b103e9880ef4bff637acaec' -+ ], -+ [ -+ '5098ff1e1d9f14fb46a210fada6c903fef0fb7b4a1dd1d9ac60a0361800b7a00', -+ '9731141d81fc8f8084d37c6e7542006b3ee1b40d60dfe5362a5b132fd17ddc0' -+ ], -+ [ -+ '32b78c7de9ee512a72895be6b9cbefa6e2f3c4ccce445c96b9f2c81e2778ad58', -+ 'ee1849f513df71e32efc3896ee28260c73bb80547ae2275ba497237794c8753c' -+ ], -+ [ -+ 'e2cb74fddc8e9fbcd076eef2a7c72b0ce37d50f08269dfc074b581550547a4f7', -+ 'd3aa2ed71c9dd2247a62df062736eb0baddea9e36122d2be8641abcb005cc4a4' -+ ], -+ [ -+ '8438447566d4d7bedadc299496ab357426009a35f235cb141be0d99cd10ae3a8', -+ 'c4e1020916980a4da5d01ac5e6ad330734ef0d7906631c4f2390426b2edd791f' -+ ], -+ [ -+ '4162d488b89402039b584c6fc6c308870587d9c46f660b878ab65c82c711d67e', -+ '67163e903236289f776f22c25fb8a3afc1732f2b84b4e95dbda47ae5a0852649' -+ ], -+ [ -+ '3fad3fa84caf0f34f0f89bfd2dcf54fc175d767aec3e50684f3ba4a4bf5f683d', -+ 'cd1bc7cb6cc407bb2f0ca647c718a730cf71872e7d0d2a53fa20efcdfe61826' -+ ], -+ [ -+ '674f2600a3007a00568c1a7ce05d0816c1fb84bf1370798f1c69532faeb1a86b', -+ '299d21f9413f33b3edf43b257004580b70db57da0b182259e09eecc69e0d38a5' -+ ], -+ [ -+ 'd32f4da54ade74abb81b815ad1fb3b263d82d6c692714bcff87d29bd5ee9f08f', -+ 'f9429e738b8e53b968e99016c059707782e14f4535359d582fc416910b3eea87' -+ ], -+ [ -+ '30e4e670435385556e593657135845d36fbb6931f72b08cb1ed954f1e3ce3ff6', -+ '462f9bce619898638499350113bbc9b10a878d35da70740dc695a559eb88db7b' -+ ], -+ [ -+ 'be2062003c51cc3004682904330e4dee7f3dcd10b01e580bf1971b04d4cad297', -+ '62188bc49d61e5428573d48a74e1c655b1c61090905682a0d5558ed72dccb9bc' -+ ], -+ [ -+ '93144423ace3451ed29e0fb9ac2af211cb6e84a601df5993c419859fff5df04a', -+ '7c10dfb164c3425f5c71a3f9d7992038f1065224f72bb9d1d902a6d13037b47c' -+ ], -+ [ -+ 'b015f8044f5fcbdcf21ca26d6c34fb8197829205c7b7d2a7cb66418c157b112c', -+ 'ab8c1e086d04e813744a655b2df8d5f83b3cdc6faa3088c1d3aea1454e3a1d5f' -+ ], -+ [ -+ 'd5e9e1da649d97d89e4868117a465a3a4f8a18de57a140d36b3f2af341a21b52', -+ '4cb04437f391ed73111a13cc1d4dd0db1693465c2240480d8955e8592f27447a' -+ ], -+ [ -+ 'd3ae41047dd7ca065dbf8ed77b992439983005cd72e16d6f996a5316d36966bb', -+ 'bd1aeb21ad22ebb22a10f0303417c6d964f8cdd7df0aca614b10dc14d125ac46' -+ ], -+ [ -+ '463e2763d885f958fc66cdd22800f0a487197d0a82e377b49f80af87c897b065', -+ 'bfefacdb0e5d0fd7df3a311a94de062b26b80c61fbc97508b79992671ef7ca7f' -+ ], -+ [ -+ '7985fdfd127c0567c6f53ec1bb63ec3158e597c40bfe747c83cddfc910641917', -+ '603c12daf3d9862ef2b25fe1de289aed24ed291e0ec6708703a5bd567f32ed03' -+ ], -+ [ -+ '74a1ad6b5f76e39db2dd249410eac7f99e74c59cb83d2d0ed5ff1543da7703e9', -+ 'cc6157ef18c9c63cd6193d83631bbea0093e0968942e8c33d5737fd790e0db08' -+ ], -+ [ -+ '30682a50703375f602d416664ba19b7fc9bab42c72747463a71d0896b22f6da3', -+ '553e04f6b018b4fa6c8f39e7f311d3176290d0e0f19ca73f17714d9977a22ff8' -+ ], -+ [ -+ '9e2158f0d7c0d5f26c3791efefa79597654e7a2b2464f52b1ee6c1347769ef57', -+ '712fcdd1b9053f09003a3481fa7762e9ffd7c8ef35a38509e2fbf2629008373' -+ ], -+ [ -+ '176e26989a43c9cfeba4029c202538c28172e566e3c4fce7322857f3be327d66', -+ 'ed8cc9d04b29eb877d270b4878dc43c19aefd31f4eee09ee7b47834c1fa4b1c3' -+ ], -+ [ -+ '75d46efea3771e6e68abb89a13ad747ecf1892393dfc4f1b7004788c50374da8', -+ '9852390a99507679fd0b86fd2b39a868d7efc22151346e1a3ca4726586a6bed8' -+ ], -+ [ -+ '809a20c67d64900ffb698c4c825f6d5f2310fb0451c869345b7319f645605721', -+ '9e994980d9917e22b76b061927fa04143d096ccc54963e6a5ebfa5f3f8e286c1' -+ ], -+ [ -+ '1b38903a43f7f114ed4500b4eac7083fdefece1cf29c63528d563446f972c180', -+ '4036edc931a60ae889353f77fd53de4a2708b26b6f5da72ad3394119daf408f9' -+ ] -+ ] -+ } -+}; -+ -+},{}],17:[function(require,module,exports){ -+'use strict'; -+ -+var utils = exports; -+var BN = require('bn.js'); -+ -+utils.assert = function assert(val, msg) { -+ if (!val) -+ throw new Error(msg || 'Assertion failed'); -+}; -+ -+function toArray(msg, enc) { -+ if (Array.isArray(msg)) -+ return msg.slice(); -+ if (!msg) -+ return []; -+ var res = []; -+ if (typeof msg !== 'string') { -+ for (var i = 0; i < msg.length; i++) -+ res[i] = msg[i] | 0; -+ return res; -+ } -+ if (!enc) { -+ for (var i = 0; i < msg.length; i++) { -+ var c = msg.charCodeAt(i); -+ var hi = c >> 8; -+ var lo = c & 0xff; -+ if (hi) -+ res.push(hi, lo); -+ else -+ res.push(lo); -+ } -+ } else if (enc === 'hex') { -+ msg = msg.replace(/[^a-z0-9]+/ig, ''); -+ if (msg.length % 2 !== 0) -+ msg = '0' + msg; -+ for (var i = 0; i < msg.length; i += 2) -+ res.push(parseInt(msg[i] + msg[i + 1], 16)); -+ } -+ return res; -+} -+utils.toArray = toArray; -+ -+function zero2(word) { -+ if (word.length === 1) -+ return '0' + word; -+ else -+ return word; -+} -+utils.zero2 = zero2; -+ -+function toHex(msg) { -+ var res = ''; -+ for (var i = 0; i < msg.length; i++) -+ res += zero2(msg[i].toString(16)); -+ return res; -+} -+utils.toHex = toHex; -+ -+utils.encode = function encode(arr, enc) { -+ if (enc === 'hex') -+ return toHex(arr); -+ else -+ return arr; -+}; -+ -+// Represent num in a w-NAF form -+function getNAF(num, w) { -+ var naf = []; -+ var ws = 1 << (w + 1); -+ var k = num.clone(); -+ while (k.cmpn(1) >= 0) { -+ var z; -+ if (k.isOdd()) { -+ var mod = k.andln(ws - 1); -+ if (mod > (ws >> 1) - 1) -+ z = (ws >> 1) - mod; -+ else -+ z = mod; -+ k.isubn(z); -+ } else { -+ z = 0; -+ } -+ naf.push(z); -+ -+ // Optimization, shift by word if possible -+ var shift = (k.cmpn(0) !== 0 && k.andln(ws - 1) === 0) ? (w + 1) : 1; -+ for (var i = 1; i < shift; i++) -+ naf.push(0); -+ k.iushrn(shift); -+ } -+ -+ return naf; -+} -+utils.getNAF = getNAF; -+ -+// Represent k1, k2 in a Joint Sparse Form -+function getJSF(k1, k2) { -+ var jsf = [ -+ [], -+ [] -+ ]; -+ -+ k1 = k1.clone(); -+ k2 = k2.clone(); -+ var d1 = 0; -+ var d2 = 0; -+ while (k1.cmpn(-d1) > 0 || k2.cmpn(-d2) > 0) { -+ -+ // First phase -+ var m14 = (k1.andln(3) + d1) & 3; -+ var m24 = (k2.andln(3) + d2) & 3; -+ if (m14 === 3) -+ m14 = -1; -+ if (m24 === 3) -+ m24 = -1; -+ var u1; -+ if ((m14 & 1) === 0) { -+ u1 = 0; -+ } else { -+ var m8 = (k1.andln(7) + d1) & 7; -+ if ((m8 === 3 || m8 === 5) && m24 === 2) -+ u1 = -m14; -+ else -+ u1 = m14; -+ } -+ jsf[0].push(u1); -+ -+ var u2; -+ if ((m24 & 1) === 0) { -+ u2 = 0; -+ } else { -+ var m8 = (k2.andln(7) + d2) & 7; -+ if ((m8 === 3 || m8 === 5) && m14 === 2) -+ u2 = -m24; -+ else -+ u2 = m24; -+ } -+ jsf[1].push(u2); -+ -+ // Second phase -+ if (2 * d1 === u1 + 1) -+ d1 = 1 - d1; -+ if (2 * d2 === u2 + 1) -+ d2 = 1 - d2; -+ k1.iushrn(1); -+ k2.iushrn(1); -+ } -+ -+ return jsf; -+} -+utils.getJSF = getJSF; -+ -+function cachedProperty(obj, name, computer) { -+ var key = '_' + name; -+ obj.prototype[name] = function cachedProperty() { -+ return this[key] !== undefined ? this[key] : -+ this[key] = computer.call(this); -+ }; -+} -+utils.cachedProperty = cachedProperty; -+ -+function parseBytes(bytes) { -+ return typeof bytes === 'string' ? utils.toArray(bytes, 'hex') : -+ bytes; -+} -+utils.parseBytes = parseBytes; -+ -+function intFromLE(bytes) { -+ return new BN(bytes, 'hex', 'le'); -+} -+utils.intFromLE = intFromLE; -+ -+ -+},{"bn.js":1}],18:[function(require,module,exports){ -+var r; -+ -+module.exports = function rand(len) { -+ if (!r) -+ r = new Rand(null); -+ -+ return r.generate(len); -+}; -+ -+function Rand(rand) { -+ this.rand = rand; -+} -+module.exports.Rand = Rand; -+ -+Rand.prototype.generate = function generate(len) { -+ return this._rand(len); -+}; -+ -+if (typeof window === 'object') { -+ if (window.crypto && window.crypto.getRandomValues) { -+ // Modern browsers -+ Rand.prototype._rand = function _rand(n) { -+ var arr = new Uint8Array(n); -+ window.crypto.getRandomValues(arr); -+ return arr; -+ }; -+ } else if (window.msCrypto && window.msCrypto.getRandomValues) { -+ // IE -+ Rand.prototype._rand = function _rand(n) { -+ var arr = new Uint8Array(n); -+ window.msCrypto.getRandomValues(arr); -+ return arr; -+ }; -+ } else { -+ // Old junk -+ Rand.prototype._rand = function() { -+ throw new Error('Not implemented yet'); -+ }; -+ } -+} else { -+ // Node.js or Web worker -+ try { -+ var crypto = require('cry' + 'pto'); -+ -+ Rand.prototype._rand = function _rand(n) { -+ return crypto.randomBytes(n); -+ }; -+ } catch (e) { -+ // Emulate crypto API using randy -+ Rand.prototype._rand = function _rand(n) { -+ var res = new Uint8Array(n); -+ for (var i = 0; i < res.length; i++) -+ res[i] = this.rand.getByte(); -+ return res; -+ }; -+ } -+} -+ -+},{}],19:[function(require,module,exports){ -+var hash = exports; -+ -+hash.utils = require('./hash/utils'); -+hash.common = require('./hash/common'); -+hash.sha = require('./hash/sha'); -+hash.ripemd = require('./hash/ripemd'); -+hash.hmac = require('./hash/hmac'); -+ -+// Proxy hash functions to the main object -+hash.sha1 = hash.sha.sha1; -+hash.sha256 = hash.sha.sha256; -+hash.sha224 = hash.sha.sha224; -+hash.sha384 = hash.sha.sha384; -+hash.sha512 = hash.sha.sha512; -+hash.ripemd160 = hash.ripemd.ripemd160; -+ -+},{"./hash/common":20,"./hash/hmac":21,"./hash/ripemd":22,"./hash/sha":23,"./hash/utils":24}],20:[function(require,module,exports){ -+var hash = require('../hash'); -+var utils = hash.utils; -+var assert = utils.assert; -+ -+function BlockHash() { -+ this.pending = null; -+ this.pendingTotal = 0; -+ this.blockSize = this.constructor.blockSize; -+ this.outSize = this.constructor.outSize; -+ this.hmacStrength = this.constructor.hmacStrength; -+ this.padLength = this.constructor.padLength / 8; -+ this.endian = 'big'; -+ -+ this._delta8 = this.blockSize / 8; -+ this._delta32 = this.blockSize / 32; -+} -+exports.BlockHash = BlockHash; -+ -+BlockHash.prototype.update = function update(msg, enc) { -+ // Convert message to array, pad it, and join into 32bit blocks -+ msg = utils.toArray(msg, enc); -+ if (!this.pending) -+ this.pending = msg; -+ else -+ this.pending = this.pending.concat(msg); -+ this.pendingTotal += msg.length; -+ -+ // Enough data, try updating -+ if (this.pending.length >= this._delta8) { -+ msg = this.pending; -+ -+ // Process pending data in blocks -+ var r = msg.length % this._delta8; -+ this.pending = msg.slice(msg.length - r, msg.length); -+ if (this.pending.length === 0) -+ this.pending = null; -+ -+ msg = utils.join32(msg, 0, msg.length - r, this.endian); -+ for (var i = 0; i < msg.length; i += this._delta32) -+ this._update(msg, i, i + this._delta32); -+ } -+ -+ return this; -+}; -+ -+BlockHash.prototype.digest = function digest(enc) { -+ this.update(this._pad()); -+ assert(this.pending === null); -+ -+ return this._digest(enc); -+}; -+ -+BlockHash.prototype._pad = function pad() { -+ var len = this.pendingTotal; -+ var bytes = this._delta8; -+ var k = bytes - ((len + this.padLength) % bytes); -+ var res = new Array(k + this.padLength); -+ res[0] = 0x80; -+ for (var i = 1; i < k; i++) -+ res[i] = 0; -+ -+ // Append length -+ len <<= 3; -+ if (this.endian === 'big') { -+ for (var t = 8; t < this.padLength; t++) -+ res[i++] = 0; -+ -+ res[i++] = 0; -+ res[i++] = 0; -+ res[i++] = 0; -+ res[i++] = 0; -+ res[i++] = (len >>> 24) & 0xff; -+ res[i++] = (len >>> 16) & 0xff; -+ res[i++] = (len >>> 8) & 0xff; -+ res[i++] = len & 0xff; -+ } else { -+ res[i++] = len & 0xff; -+ res[i++] = (len >>> 8) & 0xff; -+ res[i++] = (len >>> 16) & 0xff; -+ res[i++] = (len >>> 24) & 0xff; -+ res[i++] = 0; -+ res[i++] = 0; -+ res[i++] = 0; -+ res[i++] = 0; -+ -+ for (var t = 8; t < this.padLength; t++) -+ res[i++] = 0; -+ } -+ -+ return res; -+}; -+ -+},{"../hash":19}],21:[function(require,module,exports){ -+var hmac = exports; -+ -+var hash = require('../hash'); -+var utils = hash.utils; -+var assert = utils.assert; -+ -+function Hmac(hash, key, enc) { -+ if (!(this instanceof Hmac)) -+ return new Hmac(hash, key, enc); -+ this.Hash = hash; -+ this.blockSize = hash.blockSize / 8; -+ this.outSize = hash.outSize / 8; -+ this.inner = null; -+ this.outer = null; -+ -+ this._init(utils.toArray(key, enc)); -+} -+module.exports = Hmac; -+ -+Hmac.prototype._init = function init(key) { -+ // Shorten key, if needed -+ if (key.length > this.blockSize) -+ key = new this.Hash().update(key).digest(); -+ assert(key.length <= this.blockSize); -+ -+ // Add padding to key -+ for (var i = key.length; i < this.blockSize; i++) -+ key.push(0); -+ -+ for (var i = 0; i < key.length; i++) -+ key[i] ^= 0x36; -+ this.inner = new this.Hash().update(key); -+ -+ // 0x36 ^ 0x5c = 0x6a -+ for (var i = 0; i < key.length; i++) -+ key[i] ^= 0x6a; -+ this.outer = new this.Hash().update(key); -+}; -+ -+Hmac.prototype.update = function update(msg, enc) { -+ this.inner.update(msg, enc); -+ return this; -+}; -+ -+Hmac.prototype.digest = function digest(enc) { -+ this.outer.update(this.inner.digest()); -+ return this.outer.digest(enc); -+}; -+ -+},{"../hash":19}],22:[function(require,module,exports){ -+var hash = require('../hash'); -+var utils = hash.utils; -+ -+var rotl32 = utils.rotl32; -+var sum32 = utils.sum32; -+var sum32_3 = utils.sum32_3; -+var sum32_4 = utils.sum32_4; -+var BlockHash = hash.common.BlockHash; -+ -+function RIPEMD160() { -+ if (!(this instanceof RIPEMD160)) -+ return new RIPEMD160(); -+ -+ BlockHash.call(this); -+ -+ this.h = [ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 ]; -+ this.endian = 'little'; -+} -+utils.inherits(RIPEMD160, BlockHash); -+exports.ripemd160 = RIPEMD160; -+ -+RIPEMD160.blockSize = 512; -+RIPEMD160.outSize = 160; -+RIPEMD160.hmacStrength = 192; -+RIPEMD160.padLength = 64; -+ -+RIPEMD160.prototype._update = function update(msg, start) { -+ var A = this.h[0]; -+ var B = this.h[1]; -+ var C = this.h[2]; -+ var D = this.h[3]; -+ var E = this.h[4]; -+ var Ah = A; -+ var Bh = B; -+ var Ch = C; -+ var Dh = D; -+ var Eh = E; -+ for (var j = 0; j < 80; j++) { -+ var T = sum32( -+ rotl32( -+ sum32_4(A, f(j, B, C, D), msg[r[j] + start], K(j)), -+ s[j]), -+ E); -+ A = E; -+ E = D; -+ D = rotl32(C, 10); -+ C = B; -+ B = T; -+ T = sum32( -+ rotl32( -+ sum32_4(Ah, f(79 - j, Bh, Ch, Dh), msg[rh[j] + start], Kh(j)), -+ sh[j]), -+ Eh); -+ Ah = Eh; -+ Eh = Dh; -+ Dh = rotl32(Ch, 10); -+ Ch = Bh; -+ Bh = T; -+ } -+ T = sum32_3(this.h[1], C, Dh); -+ this.h[1] = sum32_3(this.h[2], D, Eh); -+ this.h[2] = sum32_3(this.h[3], E, Ah); -+ this.h[3] = sum32_3(this.h[4], A, Bh); -+ this.h[4] = sum32_3(this.h[0], B, Ch); -+ this.h[0] = T; -+}; -+ -+RIPEMD160.prototype._digest = function digest(enc) { -+ if (enc === 'hex') -+ return utils.toHex32(this.h, 'little'); -+ else -+ return utils.split32(this.h, 'little'); -+}; -+ -+function f(j, x, y, z) { -+ if (j <= 15) -+ return x ^ y ^ z; -+ else if (j <= 31) -+ return (x & y) | ((~x) & z); -+ else if (j <= 47) -+ return (x | (~y)) ^ z; -+ else if (j <= 63) -+ return (x & z) | (y & (~z)); -+ else -+ return x ^ (y | (~z)); -+} -+ -+function K(j) { -+ if (j <= 15) -+ return 0x00000000; -+ else if (j <= 31) -+ return 0x5a827999; -+ else if (j <= 47) -+ return 0x6ed9eba1; -+ else if (j <= 63) -+ return 0x8f1bbcdc; -+ else -+ return 0xa953fd4e; -+} -+ -+function Kh(j) { -+ if (j <= 15) -+ return 0x50a28be6; -+ else if (j <= 31) -+ return 0x5c4dd124; -+ else if (j <= 47) -+ return 0x6d703ef3; -+ else if (j <= 63) -+ return 0x7a6d76e9; -+ else -+ return 0x00000000; -+} -+ -+var r = [ -+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -+ 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, -+ 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, -+ 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, -+ 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13 -+]; -+ -+var rh = [ -+ 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, -+ 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, -+ 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, -+ 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, -+ 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11 -+]; -+ -+var s = [ -+ 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, -+ 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, -+ 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, -+ 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, -+ 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 -+]; -+ -+var sh = [ -+ 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, -+ 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, -+ 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, -+ 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, -+ 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 -+]; -+ -+},{"../hash":19}],23:[function(require,module,exports){ -+var hash = require('../hash'); -+var utils = hash.utils; -+var assert = utils.assert; -+ -+var rotr32 = utils.rotr32; -+var rotl32 = utils.rotl32; -+var sum32 = utils.sum32; -+var sum32_4 = utils.sum32_4; -+var sum32_5 = utils.sum32_5; -+var rotr64_hi = utils.rotr64_hi; -+var rotr64_lo = utils.rotr64_lo; -+var shr64_hi = utils.shr64_hi; -+var shr64_lo = utils.shr64_lo; -+var sum64 = utils.sum64; -+var sum64_hi = utils.sum64_hi; -+var sum64_lo = utils.sum64_lo; -+var sum64_4_hi = utils.sum64_4_hi; -+var sum64_4_lo = utils.sum64_4_lo; -+var sum64_5_hi = utils.sum64_5_hi; -+var sum64_5_lo = utils.sum64_5_lo; -+var BlockHash = hash.common.BlockHash; -+ -+var sha256_K = [ -+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, -+ 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, -+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, -+ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, -+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, -+ 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, -+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, -+ 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, -+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, -+ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, -+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, -+ 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, -+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, -+ 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, -+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, -+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 -+]; -+ -+var sha512_K = [ -+ 0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd, -+ 0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc, -+ 0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019, -+ 0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118, -+ 0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe, -+ 0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2, -+ 0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1, -+ 0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694, -+ 0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3, -+ 0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65, -+ 0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483, -+ 0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5, -+ 0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210, -+ 0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4, -+ 0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725, -+ 0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70, -+ 0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926, -+ 0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df, -+ 0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8, -+ 0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b, -+ 0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001, -+ 0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30, -+ 0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910, -+ 0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8, -+ 0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53, -+ 0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8, -+ 0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb, -+ 0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3, -+ 0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60, -+ 0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec, -+ 0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9, -+ 0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b, -+ 0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207, -+ 0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178, -+ 0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6, -+ 0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b, -+ 0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493, -+ 0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c, -+ 0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a, -+ 0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817 -+]; -+ -+var sha1_K = [ -+ 0x5A827999, 0x6ED9EBA1, -+ 0x8F1BBCDC, 0xCA62C1D6 -+]; -+ -+function SHA256() { -+ if (!(this instanceof SHA256)) -+ return new SHA256(); -+ -+ BlockHash.call(this); -+ this.h = [ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, -+ 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 ]; -+ this.k = sha256_K; -+ this.W = new Array(64); -+} -+utils.inherits(SHA256, BlockHash); -+exports.sha256 = SHA256; -+ -+SHA256.blockSize = 512; -+SHA256.outSize = 256; -+SHA256.hmacStrength = 192; -+SHA256.padLength = 64; -+ -+SHA256.prototype._update = function _update(msg, start) { -+ var W = this.W; -+ -+ for (var i = 0; i < 16; i++) -+ W[i] = msg[start + i]; -+ for (; i < W.length; i++) -+ W[i] = sum32_4(g1_256(W[i - 2]), W[i - 7], g0_256(W[i - 15]), W[i - 16]); -+ -+ var a = this.h[0]; -+ var b = this.h[1]; -+ var c = this.h[2]; -+ var d = this.h[3]; -+ var e = this.h[4]; -+ var f = this.h[5]; -+ var g = this.h[6]; -+ var h = this.h[7]; -+ -+ assert(this.k.length === W.length); -+ for (var i = 0; i < W.length; i++) { -+ var T1 = sum32_5(h, s1_256(e), ch32(e, f, g), this.k[i], W[i]); -+ var T2 = sum32(s0_256(a), maj32(a, b, c)); -+ h = g; -+ g = f; -+ f = e; -+ e = sum32(d, T1); -+ d = c; -+ c = b; -+ b = a; -+ a = sum32(T1, T2); -+ } -+ -+ this.h[0] = sum32(this.h[0], a); -+ this.h[1] = sum32(this.h[1], b); -+ this.h[2] = sum32(this.h[2], c); -+ this.h[3] = sum32(this.h[3], d); -+ this.h[4] = sum32(this.h[4], e); -+ this.h[5] = sum32(this.h[5], f); -+ this.h[6] = sum32(this.h[6], g); -+ this.h[7] = sum32(this.h[7], h); -+}; -+ -+SHA256.prototype._digest = function digest(enc) { -+ if (enc === 'hex') -+ return utils.toHex32(this.h, 'big'); -+ else -+ return utils.split32(this.h, 'big'); -+}; -+ -+function SHA224() { -+ if (!(this instanceof SHA224)) -+ return new SHA224(); -+ -+ SHA256.call(this); -+ this.h = [ 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, -+ 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 ]; -+} -+utils.inherits(SHA224, SHA256); -+exports.sha224 = SHA224; -+ -+SHA224.blockSize = 512; -+SHA224.outSize = 224; -+SHA224.hmacStrength = 192; -+SHA224.padLength = 64; -+ -+SHA224.prototype._digest = function digest(enc) { -+ // Just truncate output -+ if (enc === 'hex') -+ return utils.toHex32(this.h.slice(0, 7), 'big'); -+ else -+ return utils.split32(this.h.slice(0, 7), 'big'); -+}; -+ -+function SHA512() { -+ if (!(this instanceof SHA512)) -+ return new SHA512(); -+ -+ BlockHash.call(this); -+ this.h = [ 0x6a09e667, 0xf3bcc908, -+ 0xbb67ae85, 0x84caa73b, -+ 0x3c6ef372, 0xfe94f82b, -+ 0xa54ff53a, 0x5f1d36f1, -+ 0x510e527f, 0xade682d1, -+ 0x9b05688c, 0x2b3e6c1f, -+ 0x1f83d9ab, 0xfb41bd6b, -+ 0x5be0cd19, 0x137e2179 ]; -+ this.k = sha512_K; -+ this.W = new Array(160); -+} -+utils.inherits(SHA512, BlockHash); -+exports.sha512 = SHA512; -+ -+SHA512.blockSize = 1024; -+SHA512.outSize = 512; -+SHA512.hmacStrength = 192; -+SHA512.padLength = 128; -+ -+SHA512.prototype._prepareBlock = function _prepareBlock(msg, start) { -+ var W = this.W; -+ -+ // 32 x 32bit words -+ for (var i = 0; i < 32; i++) -+ W[i] = msg[start + i]; -+ for (; i < W.length; i += 2) { -+ var c0_hi = g1_512_hi(W[i - 4], W[i - 3]); // i - 2 -+ var c0_lo = g1_512_lo(W[i - 4], W[i - 3]); -+ var c1_hi = W[i - 14]; // i - 7 -+ var c1_lo = W[i - 13]; -+ var c2_hi = g0_512_hi(W[i - 30], W[i - 29]); // i - 15 -+ var c2_lo = g0_512_lo(W[i - 30], W[i - 29]); -+ var c3_hi = W[i - 32]; // i - 16 -+ var c3_lo = W[i - 31]; -+ -+ W[i] = sum64_4_hi(c0_hi, c0_lo, -+ c1_hi, c1_lo, -+ c2_hi, c2_lo, -+ c3_hi, c3_lo); -+ W[i + 1] = sum64_4_lo(c0_hi, c0_lo, -+ c1_hi, c1_lo, -+ c2_hi, c2_lo, -+ c3_hi, c3_lo); -+ } -+}; -+ -+SHA512.prototype._update = function _update(msg, start) { -+ this._prepareBlock(msg, start); -+ -+ var W = this.W; -+ -+ var ah = this.h[0]; -+ var al = this.h[1]; -+ var bh = this.h[2]; -+ var bl = this.h[3]; -+ var ch = this.h[4]; -+ var cl = this.h[5]; -+ var dh = this.h[6]; -+ var dl = this.h[7]; -+ var eh = this.h[8]; -+ var el = this.h[9]; -+ var fh = this.h[10]; -+ var fl = this.h[11]; -+ var gh = this.h[12]; -+ var gl = this.h[13]; -+ var hh = this.h[14]; -+ var hl = this.h[15]; -+ -+ assert(this.k.length === W.length); -+ for (var i = 0; i < W.length; i += 2) { -+ var c0_hi = hh; -+ var c0_lo = hl; -+ var c1_hi = s1_512_hi(eh, el); -+ var c1_lo = s1_512_lo(eh, el); -+ var c2_hi = ch64_hi(eh, el, fh, fl, gh, gl); -+ var c2_lo = ch64_lo(eh, el, fh, fl, gh, gl); -+ var c3_hi = this.k[i]; -+ var c3_lo = this.k[i + 1]; -+ var c4_hi = W[i]; -+ var c4_lo = W[i + 1]; -+ -+ var T1_hi = sum64_5_hi(c0_hi, c0_lo, -+ c1_hi, c1_lo, -+ c2_hi, c2_lo, -+ c3_hi, c3_lo, -+ c4_hi, c4_lo); -+ var T1_lo = sum64_5_lo(c0_hi, c0_lo, -+ c1_hi, c1_lo, -+ c2_hi, c2_lo, -+ c3_hi, c3_lo, -+ c4_hi, c4_lo); -+ -+ var c0_hi = s0_512_hi(ah, al); -+ var c0_lo = s0_512_lo(ah, al); -+ var c1_hi = maj64_hi(ah, al, bh, bl, ch, cl); -+ var c1_lo = maj64_lo(ah, al, bh, bl, ch, cl); -+ -+ var T2_hi = sum64_hi(c0_hi, c0_lo, c1_hi, c1_lo); -+ var T2_lo = sum64_lo(c0_hi, c0_lo, c1_hi, c1_lo); -+ -+ hh = gh; -+ hl = gl; -+ -+ gh = fh; -+ gl = fl; -+ -+ fh = eh; -+ fl = el; -+ -+ eh = sum64_hi(dh, dl, T1_hi, T1_lo); -+ el = sum64_lo(dl, dl, T1_hi, T1_lo); -+ -+ dh = ch; -+ dl = cl; -+ -+ ch = bh; -+ cl = bl; -+ -+ bh = ah; -+ bl = al; -+ -+ ah = sum64_hi(T1_hi, T1_lo, T2_hi, T2_lo); -+ al = sum64_lo(T1_hi, T1_lo, T2_hi, T2_lo); -+ } -+ -+ sum64(this.h, 0, ah, al); -+ sum64(this.h, 2, bh, bl); -+ sum64(this.h, 4, ch, cl); -+ sum64(this.h, 6, dh, dl); -+ sum64(this.h, 8, eh, el); -+ sum64(this.h, 10, fh, fl); -+ sum64(this.h, 12, gh, gl); -+ sum64(this.h, 14, hh, hl); -+}; -+ -+SHA512.prototype._digest = function digest(enc) { -+ if (enc === 'hex') -+ return utils.toHex32(this.h, 'big'); -+ else -+ return utils.split32(this.h, 'big'); -+}; -+ -+function SHA384() { -+ if (!(this instanceof SHA384)) -+ return new SHA384(); -+ -+ SHA512.call(this); -+ this.h = [ 0xcbbb9d5d, 0xc1059ed8, -+ 0x629a292a, 0x367cd507, -+ 0x9159015a, 0x3070dd17, -+ 0x152fecd8, 0xf70e5939, -+ 0x67332667, 0xffc00b31, -+ 0x8eb44a87, 0x68581511, -+ 0xdb0c2e0d, 0x64f98fa7, -+ 0x47b5481d, 0xbefa4fa4 ]; -+} -+utils.inherits(SHA384, SHA512); -+exports.sha384 = SHA384; -+ -+SHA384.blockSize = 1024; -+SHA384.outSize = 384; -+SHA384.hmacStrength = 192; -+SHA384.padLength = 128; -+ -+SHA384.prototype._digest = function digest(enc) { -+ if (enc === 'hex') -+ return utils.toHex32(this.h.slice(0, 12), 'big'); -+ else -+ return utils.split32(this.h.slice(0, 12), 'big'); -+}; -+ -+function SHA1() { -+ if (!(this instanceof SHA1)) -+ return new SHA1(); -+ -+ BlockHash.call(this); -+ this.h = [ 0x67452301, 0xefcdab89, 0x98badcfe, -+ 0x10325476, 0xc3d2e1f0 ]; -+ this.W = new Array(80); -+} -+ -+utils.inherits(SHA1, BlockHash); -+exports.sha1 = SHA1; -+ -+SHA1.blockSize = 512; -+SHA1.outSize = 160; -+SHA1.hmacStrength = 80; -+SHA1.padLength = 64; -+ -+SHA1.prototype._update = function _update(msg, start) { -+ var W = this.W; -+ -+ for (var i = 0; i < 16; i++) -+ W[i] = msg[start + i]; -+ -+ for(; i < W.length; i++) -+ W[i] = rotl32(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1); -+ -+ var a = this.h[0]; -+ var b = this.h[1]; -+ var c = this.h[2]; -+ var d = this.h[3]; -+ var e = this.h[4]; -+ -+ for (var i = 0; i < W.length; i++) { -+ var s = ~~(i / 20); -+ var t = sum32_5(rotl32(a, 5), ft_1(s, b, c, d), e, W[i], sha1_K[s]); -+ e = d; -+ d = c; -+ c = rotl32(b, 30); -+ b = a; -+ a = t; -+ } -+ -+ this.h[0] = sum32(this.h[0], a); -+ this.h[1] = sum32(this.h[1], b); -+ this.h[2] = sum32(this.h[2], c); -+ this.h[3] = sum32(this.h[3], d); -+ this.h[4] = sum32(this.h[4], e); -+}; -+ -+SHA1.prototype._digest = function digest(enc) { -+ if (enc === 'hex') -+ return utils.toHex32(this.h, 'big'); -+ else -+ return utils.split32(this.h, 'big'); -+}; -+ -+function ch32(x, y, z) { -+ return (x & y) ^ ((~x) & z); -+} -+ -+function maj32(x, y, z) { -+ return (x & y) ^ (x & z) ^ (y & z); -+} -+ -+function p32(x, y, z) { -+ return x ^ y ^ z; -+} -+ -+function s0_256(x) { -+ return rotr32(x, 2) ^ rotr32(x, 13) ^ rotr32(x, 22); -+} -+ -+function s1_256(x) { -+ return rotr32(x, 6) ^ rotr32(x, 11) ^ rotr32(x, 25); -+} -+ -+function g0_256(x) { -+ return rotr32(x, 7) ^ rotr32(x, 18) ^ (x >>> 3); -+} -+ -+function g1_256(x) { -+ return rotr32(x, 17) ^ rotr32(x, 19) ^ (x >>> 10); -+} -+ -+function ft_1(s, x, y, z) { -+ if (s === 0) -+ return ch32(x, y, z); -+ if (s === 1 || s === 3) -+ return p32(x, y, z); -+ if (s === 2) -+ return maj32(x, y, z); -+} -+ -+function ch64_hi(xh, xl, yh, yl, zh, zl) { -+ var r = (xh & yh) ^ ((~xh) & zh); -+ if (r < 0) -+ r += 0x100000000; -+ return r; -+} -+ -+function ch64_lo(xh, xl, yh, yl, zh, zl) { -+ var r = (xl & yl) ^ ((~xl) & zl); -+ if (r < 0) -+ r += 0x100000000; -+ return r; -+} -+ -+function maj64_hi(xh, xl, yh, yl, zh, zl) { -+ var r = (xh & yh) ^ (xh & zh) ^ (yh & zh); -+ if (r < 0) -+ r += 0x100000000; -+ return r; -+} -+ -+function maj64_lo(xh, xl, yh, yl, zh, zl) { -+ var r = (xl & yl) ^ (xl & zl) ^ (yl & zl); -+ if (r < 0) -+ r += 0x100000000; -+ return r; -+} -+ -+function s0_512_hi(xh, xl) { -+ var c0_hi = rotr64_hi(xh, xl, 28); -+ var c1_hi = rotr64_hi(xl, xh, 2); // 34 -+ var c2_hi = rotr64_hi(xl, xh, 7); // 39 -+ -+ var r = c0_hi ^ c1_hi ^ c2_hi; -+ if (r < 0) -+ r += 0x100000000; -+ return r; -+} -+ -+function s0_512_lo(xh, xl) { -+ var c0_lo = rotr64_lo(xh, xl, 28); -+ var c1_lo = rotr64_lo(xl, xh, 2); // 34 -+ var c2_lo = rotr64_lo(xl, xh, 7); // 39 -+ -+ var r = c0_lo ^ c1_lo ^ c2_lo; -+ if (r < 0) -+ r += 0x100000000; -+ return r; -+} -+ -+function s1_512_hi(xh, xl) { -+ var c0_hi = rotr64_hi(xh, xl, 14); -+ var c1_hi = rotr64_hi(xh, xl, 18); -+ var c2_hi = rotr64_hi(xl, xh, 9); // 41 -+ -+ var r = c0_hi ^ c1_hi ^ c2_hi; -+ if (r < 0) -+ r += 0x100000000; -+ return r; -+} -+ -+function s1_512_lo(xh, xl) { -+ var c0_lo = rotr64_lo(xh, xl, 14); -+ var c1_lo = rotr64_lo(xh, xl, 18); -+ var c2_lo = rotr64_lo(xl, xh, 9); // 41 -+ -+ var r = c0_lo ^ c1_lo ^ c2_lo; -+ if (r < 0) -+ r += 0x100000000; -+ return r; -+} -+ -+function g0_512_hi(xh, xl) { -+ var c0_hi = rotr64_hi(xh, xl, 1); -+ var c1_hi = rotr64_hi(xh, xl, 8); -+ var c2_hi = shr64_hi(xh, xl, 7); -+ -+ var r = c0_hi ^ c1_hi ^ c2_hi; -+ if (r < 0) -+ r += 0x100000000; -+ return r; -+} -+ -+function g0_512_lo(xh, xl) { -+ var c0_lo = rotr64_lo(xh, xl, 1); -+ var c1_lo = rotr64_lo(xh, xl, 8); -+ var c2_lo = shr64_lo(xh, xl, 7); -+ -+ var r = c0_lo ^ c1_lo ^ c2_lo; -+ if (r < 0) -+ r += 0x100000000; -+ return r; -+} -+ -+function g1_512_hi(xh, xl) { -+ var c0_hi = rotr64_hi(xh, xl, 19); -+ var c1_hi = rotr64_hi(xl, xh, 29); // 61 -+ var c2_hi = shr64_hi(xh, xl, 6); -+ -+ var r = c0_hi ^ c1_hi ^ c2_hi; -+ if (r < 0) -+ r += 0x100000000; -+ return r; -+} -+ -+function g1_512_lo(xh, xl) { -+ var c0_lo = rotr64_lo(xh, xl, 19); -+ var c1_lo = rotr64_lo(xl, xh, 29); // 61 -+ var c2_lo = shr64_lo(xh, xl, 6); -+ -+ var r = c0_lo ^ c1_lo ^ c2_lo; -+ if (r < 0) -+ r += 0x100000000; -+ return r; -+} -+ -+},{"../hash":19}],24:[function(require,module,exports){ -+var utils = exports; -+var inherits = require('inherits'); -+ -+function toArray(msg, enc) { -+ if (Array.isArray(msg)) -+ return msg.slice(); -+ if (!msg) -+ return []; -+ var res = []; -+ if (typeof msg === 'string') { -+ if (!enc) { -+ for (var i = 0; i < msg.length; i++) { -+ var c = msg.charCodeAt(i); -+ var hi = c >> 8; -+ var lo = c & 0xff; -+ if (hi) -+ res.push(hi, lo); -+ else -+ res.push(lo); -+ } -+ } else if (enc === 'hex') { -+ msg = msg.replace(/[^a-z0-9]+/ig, ''); -+ if (msg.length % 2 !== 0) -+ msg = '0' + msg; -+ for (var i = 0; i < msg.length; i += 2) -+ res.push(parseInt(msg[i] + msg[i + 1], 16)); -+ } -+ } else { -+ for (var i = 0; i < msg.length; i++) -+ res[i] = msg[i] | 0; -+ } -+ return res; -+} -+utils.toArray = toArray; -+ -+function toHex(msg) { -+ var res = ''; -+ for (var i = 0; i < msg.length; i++) -+ res += zero2(msg[i].toString(16)); -+ return res; -+} -+utils.toHex = toHex; -+ -+function htonl(w) { -+ var res = (w >>> 24) | -+ ((w >>> 8) & 0xff00) | -+ ((w << 8) & 0xff0000) | -+ ((w & 0xff) << 24); -+ return res >>> 0; -+} -+utils.htonl = htonl; -+ -+function toHex32(msg, endian) { -+ var res = ''; -+ for (var i = 0; i < msg.length; i++) { -+ var w = msg[i]; -+ if (endian === 'little') -+ w = htonl(w); -+ res += zero8(w.toString(16)); -+ } -+ return res; -+} -+utils.toHex32 = toHex32; -+ -+function zero2(word) { -+ if (word.length === 1) -+ return '0' + word; -+ else -+ return word; -+} -+utils.zero2 = zero2; -+ -+function zero8(word) { -+ if (word.length === 7) -+ return '0' + word; -+ else if (word.length === 6) -+ return '00' + word; -+ else if (word.length === 5) -+ return '000' + word; -+ else if (word.length === 4) -+ return '0000' + word; -+ else if (word.length === 3) -+ return '00000' + word; -+ else if (word.length === 2) -+ return '000000' + word; -+ else if (word.length === 1) -+ return '0000000' + word; -+ else -+ return word; -+} -+utils.zero8 = zero8; -+ -+function join32(msg, start, end, endian) { -+ var len = end - start; -+ assert(len % 4 === 0); -+ var res = new Array(len / 4); -+ for (var i = 0, k = start; i < res.length; i++, k += 4) { -+ var w; -+ if (endian === 'big') -+ w = (msg[k] << 24) | (msg[k + 1] << 16) | (msg[k + 2] << 8) | msg[k + 3]; -+ else -+ w = (msg[k + 3] << 24) | (msg[k + 2] << 16) | (msg[k + 1] << 8) | msg[k]; -+ res[i] = w >>> 0; -+ } -+ return res; -+} -+utils.join32 = join32; -+ -+function split32(msg, endian) { -+ var res = new Array(msg.length * 4); -+ for (var i = 0, k = 0; i < msg.length; i++, k += 4) { -+ var m = msg[i]; -+ if (endian === 'big') { -+ res[k] = m >>> 24; -+ res[k + 1] = (m >>> 16) & 0xff; -+ res[k + 2] = (m >>> 8) & 0xff; -+ res[k + 3] = m & 0xff; -+ } else { -+ res[k + 3] = m >>> 24; -+ res[k + 2] = (m >>> 16) & 0xff; -+ res[k + 1] = (m >>> 8) & 0xff; -+ res[k] = m & 0xff; -+ } -+ } -+ return res; -+} -+utils.split32 = split32; -+ -+function rotr32(w, b) { -+ return (w >>> b) | (w << (32 - b)); -+} -+utils.rotr32 = rotr32; -+ -+function rotl32(w, b) { -+ return (w << b) | (w >>> (32 - b)); -+} -+utils.rotl32 = rotl32; -+ -+function sum32(a, b) { -+ return (a + b) >>> 0; -+} -+utils.sum32 = sum32; -+ -+function sum32_3(a, b, c) { -+ return (a + b + c) >>> 0; -+} -+utils.sum32_3 = sum32_3; -+ -+function sum32_4(a, b, c, d) { -+ return (a + b + c + d) >>> 0; -+} -+utils.sum32_4 = sum32_4; -+ -+function sum32_5(a, b, c, d, e) { -+ return (a + b + c + d + e) >>> 0; -+} -+utils.sum32_5 = sum32_5; -+ -+function assert(cond, msg) { -+ if (!cond) -+ throw new Error(msg || 'Assertion failed'); -+} -+utils.assert = assert; -+ -+utils.inherits = inherits; -+ -+function sum64(buf, pos, ah, al) { -+ var bh = buf[pos]; -+ var bl = buf[pos + 1]; -+ -+ var lo = (al + bl) >>> 0; -+ var hi = (lo < al ? 1 : 0) + ah + bh; -+ buf[pos] = hi >>> 0; -+ buf[pos + 1] = lo; -+} -+exports.sum64 = sum64; -+ -+function sum64_hi(ah, al, bh, bl) { -+ var lo = (al + bl) >>> 0; -+ var hi = (lo < al ? 1 : 0) + ah + bh; -+ return hi >>> 0; -+}; -+exports.sum64_hi = sum64_hi; -+ -+function sum64_lo(ah, al, bh, bl) { -+ var lo = al + bl; -+ return lo >>> 0; -+}; -+exports.sum64_lo = sum64_lo; -+ -+function sum64_4_hi(ah, al, bh, bl, ch, cl, dh, dl) { -+ var carry = 0; -+ var lo = al; -+ lo = (lo + bl) >>> 0; -+ carry += lo < al ? 1 : 0; -+ lo = (lo + cl) >>> 0; -+ carry += lo < cl ? 1 : 0; -+ lo = (lo + dl) >>> 0; -+ carry += lo < dl ? 1 : 0; -+ -+ var hi = ah + bh + ch + dh + carry; -+ return hi >>> 0; -+}; -+exports.sum64_4_hi = sum64_4_hi; -+ -+function sum64_4_lo(ah, al, bh, bl, ch, cl, dh, dl) { -+ var lo = al + bl + cl + dl; -+ return lo >>> 0; -+}; -+exports.sum64_4_lo = sum64_4_lo; -+ -+function sum64_5_hi(ah, al, bh, bl, ch, cl, dh, dl, eh, el) { -+ var carry = 0; -+ var lo = al; -+ lo = (lo + bl) >>> 0; -+ carry += lo < al ? 1 : 0; -+ lo = (lo + cl) >>> 0; -+ carry += lo < cl ? 1 : 0; -+ lo = (lo + dl) >>> 0; -+ carry += lo < dl ? 1 : 0; -+ lo = (lo + el) >>> 0; -+ carry += lo < el ? 1 : 0; -+ -+ var hi = ah + bh + ch + dh + eh + carry; -+ return hi >>> 0; -+}; -+exports.sum64_5_hi = sum64_5_hi; -+ -+function sum64_5_lo(ah, al, bh, bl, ch, cl, dh, dl, eh, el) { -+ var lo = al + bl + cl + dl + el; -+ -+ return lo >>> 0; -+}; -+exports.sum64_5_lo = sum64_5_lo; -+ -+function rotr64_hi(ah, al, num) { -+ var r = (al << (32 - num)) | (ah >>> num); -+ return r >>> 0; -+}; -+exports.rotr64_hi = rotr64_hi; -+ -+function rotr64_lo(ah, al, num) { -+ var r = (ah << (32 - num)) | (al >>> num); -+ return r >>> 0; -+}; -+exports.rotr64_lo = rotr64_lo; -+ -+function shr64_hi(ah, al, num) { -+ return ah >>> num; -+}; -+exports.shr64_hi = shr64_hi; -+ -+function shr64_lo(ah, al, num) { -+ var r = (ah << (32 - num)) | (al >>> num); -+ return r >>> 0; -+}; -+exports.shr64_lo = shr64_lo; -+ -+},{"inherits":25}],25:[function(require,module,exports){ -+if (typeof Object.create === 'function') { -+ // implementation from standard node.js 'util' module -+ module.exports = function inherits(ctor, superCtor) { -+ ctor.super_ = superCtor -+ ctor.prototype = Object.create(superCtor.prototype, { -+ constructor: { -+ value: ctor, -+ enumerable: false, -+ writable: true, -+ configurable: true -+ } -+ }); -+ }; -+} else { -+ // old school shim for old browsers -+ module.exports = function inherits(ctor, superCtor) { -+ ctor.super_ = superCtor -+ var TempCtor = function () {} -+ TempCtor.prototype = superCtor.prototype -+ ctor.prototype = new TempCtor() -+ ctor.prototype.constructor = ctor -+ } -+} -+ -+},{}],26:[function(require,module,exports){ -+module.exports={ -+ "name": "elliptic", -+ "version": "6.3.2", -+ "description": "EC cryptography", -+ "main": "lib/elliptic.js", -+ "files": [ -+ "lib" -+ ], -+ "scripts": { -+ "jscs": "jscs benchmarks/*.js lib/*.js lib/**/*.js lib/**/**/*.js test/index.js", -+ "jshint": "jscs benchmarks/*.js lib/*.js lib/**/*.js lib/**/**/*.js test/index.js", -+ "lint": "npm run jscs && npm run jshint", -+ "unit": "istanbul test _mocha --reporter=spec test/index.js", -+ "test": "npm run lint && npm run unit", -+ "version": "grunt dist && git add dist/" -+ }, -+ "repository": { -+ "type": "git", -+ "url": "git@github.com:indutny/elliptic" -+ }, -+ "keywords": [ -+ "EC", -+ "Elliptic", -+ "curve", -+ "Cryptography" -+ ], -+ "author": "Fedor Indutny fedor@indutny.com", -+ "license": "MIT", -+ "bugs": { -+ "url": "https://github.com/indutny/elliptic/issues" -+ }, -+ "homepage": "https://github.com/indutny/elliptic", -+ "devDependencies": { -+ "brfs": "^1.4.3", -+ "coveralls": "^2.11.3", -+ "grunt": "^0.4.5", -+ "grunt-browserify": "^5.0.0", -+ "grunt-contrib-connect": "^1.0.0", -+ "grunt-contrib-copy": "^1.0.0", -+ "grunt-contrib-uglify": "^1.0.1", -+ "grunt-mocha-istanbul": "^3.0.1", -+ "grunt-saucelabs": "^8.6.2", -+ "istanbul": "^0.4.2", -+ "jscs": "^2.9.0", -+ "jshint": "^2.6.0", -+ "mocha": "^2.1.0" -+ }, -+ "dependencies": { -+ "bn.js": "^4.4.0", -+ "brorand": "^1.0.1", -+ "hash.js": "^1.0.0", -+ "inherits": "^2.0.1" -+ } -+} -+ -+},{}]},{},[2])(2) -+}); -+ -+// End of the imported code from elliptic.js. -+ -+// Create the exported symbol for the JavaScript module. -+var elliptic = window.elliptic; -\ No newline at end of file -diff --git a/chat/protocols/irc/ircSASL.jsm b/chat/protocols/irc/ircSASL.jsm -index 561f055e0..8a2bd70aa 100644 ---- a/chat/protocols/irc/ircSASL.jsm -+++ b/chat/protocols/irc/ircSASL.jsm -@@ -14,6 +14,43 @@ var Cu = Components.utils; - - Cu.import("resource:///modules/ircHandlers.jsm"); - Cu.import("resource:///modules/ircUtils.jsm"); -+Cu.import("resource:///modules/elliptic.jsm"); -+ -+/** -+ -+ ECDSA-NIST256P-CHALLENGE -+ -+ Paste the following code snippit in the Firefox web console to generate a -+ private key (logged as hex string) and the irc command to execute to set -+ the public key on the server. -+ -+ crypto.subtle.generateKey({ name: "ECDSA", namedCurve: "P-256" }, true, ["sign"]) -+ .then((kp) => { -+ crypto.subtle.exportKey("jwk", kp.privateKey).then((o) => { -+ // convert from base64url to hex string -+ let d = o.d; -+ let padLen = (4 - (d.length % 4)) % 4; -+ d = d.padEnd(d.length + padLen, "=") -+ .replace(/-/g, "+") -+ .replace(/_/g, "/"); -+ let str = atob(d); -+ let a = Array.prototype.map.call(str, (x) => x.charCodeAt(0)); -+ let h = a.reduce((prev, next) => prev + next.toString(16), ""); -+ console.log(h); -+ }); -+ crypto.subtle.exportKey("raw", kp.publicKey).then((ab) => { -+ let v = new Uint8Array(ab); -+ let u = v.slice(0, 33); // +1 here for the compressed point -+ u[0] = 2 + (v[v.length - 1] & 1); -+ let s = String.fromCharCode.apply(null, u); -+ console.log("/msg nickserv set property pubkey", btoa(s)); -+ }); -+ }); -+ -+ Then, copy the private key to the preference `messenger.account.accountN.ecdsa` -+ in the config editor. -+ -+*/ - - var ircSASL = { - name: "SASL AUTHENTICATE", -@@ -22,23 +59,41 @@ var ircSASL = { - - commands: { - "AUTHENTICATE": function(aMessage) { -- // Expect an empty response, if something different is received abort. -- if (aMessage.params[0] != "+") { -+ let ecdsa = this.imAccount.wrappedJSObject.prefBranch.getCharPref("ecdsa"); -+ let hasECDSA = !!ecdsa.length; -+ -+ if (aMessage.params[0] === "+") { -+ // An authentication identity, authorization identity and password are -+ // used, separated by null. -+ let data = [this._requestedNickname, this._requestedNickname]; -+ if (!hasECDSA) data.push(this.imAccount.password); -+ // btoa for Unicode, see https://developer.mozilla.org/en-US/docs/DOM/window.btoa -+ let base64Data = btoa(unescape(encodeURIComponent(data.join("\0")))); -+ this.sendMessage("AUTHENTICATE", base64Data); -+ return true; -+ } else if (hasECDSA) { -+ let challenge = aMessage.params[0]; -+ -+ let EC = elliptic.ec; -+ let ec = new EC('p256'); -+ let key = ec.keyFromPrivate(ecdsa, 'hex'); -+ -+ let str = atob(challenge); -+ let arr = Array.prototype.map.call(str, (x) => x.charCodeAt(0)); -+ -+ let signature = key.sign(arr); -+ let der = String.fromCharCode.apply(null, signature.toDER()); -+ let response = btoa(der); -+ -+ this.sendMessage("AUTHENTICATE", response); -+ return true; -+ } else { -+ // Expect an empty response, if something different is received abort. - this.sendMessage("AUTHENTICATE", "*"); - this.WARN("Aborting SASL authentication, unexpected message " + - "received:\n" + aMessage.rawMessage); - return true; - } -- -- // An authentication identity, authorization identity and password are -- // used, separated by null. -- let data = [this._requestedNickname, this._requestedNickname, -- this.imAccount.password].join("\0"); -- // btoa for Unicode, see https://developer.mozilla.org/en-US/docs/DOM/window.btoa -- let base64Data = btoa(unescape(encodeURIComponent(data))); -- this.sendMessage("AUTHENTICATE", base64Data, -- "AUTHENTICATE <base64 encoded nick, user and password not logged>"); -- return true; - }, - - "900": function(aMessage) { -@@ -130,7 +185,10 @@ var capSASL = { - - commands: { - "sasl": function(aMessage) { -- if (aMessage.cap.subcommand == "LS" && this.imAccount.password) { -+ let ecdsa = this.imAccount.wrappedJSObject.prefBranch.getCharPref("ecdsa"); -+ let hasECDSA = !!ecdsa.length; -+ -+ if (aMessage.cap.subcommand == "LS" && (this.imAccount.password || hasECDSA)) { - // If it supports SASL, let the server know we're requiring SASL. - this.sendMessage("CAP", ["REQ", "sasl"]); - this.addCAP("sasl"); -@@ -138,7 +196,8 @@ var capSASL = { - else if (aMessage.cap.subcommand == "ACK") { - // The server acknowledges our choice to use SASL, send the first - // message. -- this.sendMessage("AUTHENTICATE", "PLAIN"); -+ this.sendMessage("AUTHENTICATE", -+ hasECDSA ? "ECDSA-NIST256P-CHALLENGE" : "PLAIN"); - } - - return true; -diff --git a/chat/protocols/irc/moz.build b/chat/protocols/irc/moz.build -index bc2539687..e46815dfe 100644 ---- a/chat/protocols/irc/moz.build -+++ b/chat/protocols/irc/moz.build -@@ -11,6 +11,7 @@ EXTRA_COMPONENTS += [ - ] - - EXTRA_JS_MODULES += [ -+ 'elliptic.jsm', - 'ircBase.jsm', - 'ircCAP.jsm', - 'ircCommands.jsm', --- -2.11.0 - diff --git a/projects/instantbird/0022-Bug-1313137-msg-is-not-defined-error-in-irc.js-chang.patch b/projects/instantbird/0022-Bug-1313137-msg-is-not-defined-error-in-irc.js-chang.patch deleted file mode 100644 index 3aeac23..0000000 --- a/projects/instantbird/0022-Bug-1313137-msg-is-not-defined-error-in-irc.js-chang.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 64ee29ad8a94480af037f35ade04810ca0e1031d Mon Sep 17 00:00:00 2001 -From: aleth aleth@instantbird.org -Date: Wed, 26 Oct 2016 20:16:58 +0200 -Subject: [PATCH 22/27] Bug 1313137 - "msg is not defined" error in - irc.js:changeBuddyNick. r=clokep - ---HG-- -extra : rebase_source : 5752a69059ecd48b947809ef12de177ccab8528f ---- - chat/protocols/irc/irc.js | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/chat/protocols/irc/irc.js b/chat/protocols/irc/irc.js -index c2167a5ec..b58c2c2eb 100644 ---- a/chat/protocols/irc/irc.js -+++ b/chat/protocols/irc/irc.js -@@ -1289,7 +1289,8 @@ ircAccount.prototype = { - this.conversations.set(aNewNick, conversation); - - conversation.updateNick(aNewNick); -- conversation.writeMessage(aOldNick, msg, {system: true}); -+ conversation.writeMessage(aOldNick, _conv("nickSet", aOldNick, aNewNick), -+ {system: true}); - } - }, - --- -2.11.0 - diff --git a/projects/instantbird/0022-Bug-954368-Contact-list-entries-should-adapt-their-h.patch b/projects/instantbird/0022-Bug-954368-Contact-list-entries-should-adapt-their-h.patch new file mode 100644 index 0000000..6fa776c --- /dev/null +++ b/projects/instantbird/0022-Bug-954368-Contact-list-entries-should-adapt-their-h.patch @@ -0,0 +1,322 @@ +From 10c0e491625782ea5c2a99bfacbafa8a65406094 Mon Sep 17 00:00:00 2001 +From: aleth aleth@instantbird.org +Date: Thu, 12 May 2016 15:10:43 +0200 +Subject: [PATCH 22/26] Bug 954368 - Contact list entries should adapt their + height to the actual font size. r=florian + +--HG-- +extra : rebase_source : 9820f3a68794f98260f3ac406772da6d176d02ec +--- + chat/themes/imtooltip.css | 1 + + im/content/blist.css | 38 ++++++++++++--- + im/content/blist.js | 7 +++ + im/content/blist.xul | 4 ++ + im/content/contact.xml | 57 +++++++++++----------- + im/content/conv.xml | 10 ++-- + .../en-US/chrome/instantbird/instantbird.dtd | 6 +++ + im/themes/blist.css | 22 ++++----- + 8 files changed, 92 insertions(+), 53 deletions(-) + +diff --git a/chat/themes/imtooltip.css b/chat/themes/imtooltip.css +index c4525beb5..630da3983 100644 +--- a/chat/themes/imtooltip.css ++++ b/chat/themes/imtooltip.css +@@ -31,6 +31,7 @@ + + .tooltipBuddies { + margin-left: -3px; ++ --blist-item-height: 20px; /* 16px icon plus padding */ + } + + .tooltipDisplayName { +diff --git a/im/content/blist.css b/im/content/blist.css +index d47e4f356..15b61b103 100644 +--- a/im/content/blist.css ++++ b/im/content/blist.css +@@ -30,15 +30,28 @@ group { + -moz-box-align: center; + } + +-/* The height is required for the animation to work. The skin can +- * specify an additionnal min-height value if there are things of +- * constant size (icons + padding) */ +-contact, +-buddy, ++/* The height is required for the animation to work. */ + group { + height: 1em; + } + ++conv, ++contact, ++buddy { ++ /* Variable set from blist.js. This is necessary as CSS transitions don't ++ work with height: auto. ++ Usually 16+2+2px for the protocol icon, padding top and bottom. */ ++ height: var(--blist-item-height); ++} ++ ++contact[open], ++contact[aliasing], ++#buddylistbox:focus > contact[selected] { ++ /* This is fine because height transitions in this state are on the ++ buddies, and there is no transition on selection (it's instant). */ ++ height: auto; ++} ++ + /* Possible values of the |state| attribute: + - not set: the binding is not initialized yet, + - showing: during the expand animation, +@@ -51,23 +64,24 @@ contact:not([state]), + buddy:not([state]) { + height: 0; + } ++ + contact[state="showing"], + buddy[state="showing"] { + /* Should match the transition effect for contact/buddy collapsing so + that reordering doesn't make the whole list jump. */ +- -moz-transition: height .2s ease-in; ++ transition: height .2s ease-in; + } + + contact[state="fading"] { + opacity: 0; +- -moz-transition: opacity .4s ease-in 1s; ++ transition: opacity .4s ease-in 1s; + } + + contact[state="collapsing"], + buddy[state="collapsing"], + group[collapsing="true"] { + height: 0; +- -moz-transition: height .2s ease-in; ++ transition: height .2s ease-in; + } + + contact[state="collapsing"] *, +@@ -78,6 +92,14 @@ group[collapsing="true"] * { + display: none; + } + ++#dummyContact { ++ height: auto; ++} ++ ++#dummylistbox { ++ visibility: hidden; ++} ++ + tooltip[type="im"] { + -moz-binding: url("chrome://chat/content/imtooltip.xml#tooltip"); + } +diff --git a/im/content/blist.js b/im/content/blist.js +index 9ec10e25c..ce76ffcd7 100644 +--- a/im/content/blist.js ++++ b/im/content/blist.js +@@ -820,6 +820,13 @@ var buddyList = { + .setAttribute("checked", "true"); + } + ++ // Find the correct height of a contact list item. This can vary depending ++ // on the platform font and font size. ++ let dummyContact = document.getElementById("dummyContact"); ++ let contactHeight = dummyContact.getBoundingClientRect().height; ++ document.getElementById("buddyListMsg") ++ .style.setProperty("--blist-item-height", contactHeight + "px"); ++ + let blistBox = document.getElementById("buddylistbox"); + blistBox.removeGroup = function(aGroupElt) { + let index = buddyList._displayedGroups.indexOf(aGroupElt); +diff --git a/im/content/blist.xul b/im/content/blist.xul +index f29a48b99..71ee2c9ef 100644 +--- a/im/content/blist.xul ++++ b/im/content/blist.xul +@@ -224,6 +224,10 @@ + onfocus="buddyList.buddylistboxFocus();" + onselect="buddyList.listboxSelect(event);" + tooltip="imTooltip"/> ++ <richlistbox id="dummylistbox"> ++ <contact id="dummyContact" displayname="&dummyContact.label;" ++ state="visible" status="unknown"/> ++ </richlistbox> + <spacer id="listSpacer" flex="1" + onclick='document.getElementById("buddylistbox").focus();'/> + </notificationbox> +diff --git a/im/content/contact.xml b/im/content/contact.xml +index 5fc36dd6e..f2b464182 100644 +--- a/im/content/contact.xml ++++ b/im/content/contact.xml +@@ -16,11 +16,11 @@ + + <binding id="contact" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem"> + <content> +- <xul:stack class="prplBuddyIcon" mousethrough="always"> +- <xul:image class="protoIcon" xbl:inherits="src=iconPrpl,status"/> +- <xul:image class="statusIcon" xbl:inherits="status"/> +- </xul:stack> +- <xul:hbox flex="1" class="contact-hbox" mousethrough="always"> ++ <xul:hbox flex="1" class="contact-hbox" mousethrough="always" align="center"> ++ <xul:stack class="prplBuddyIcon" mousethrough="always"> ++ <xul:image class="protoIcon" xbl:inherits="src=iconPrpl,status"/> ++ <xul:image class="statusIcon" xbl:inherits="status"/> ++ </xul:stack> + <xul:label crop="end" flex="1" mousethrough="always" + anonid="displayname" class="contactDisplayName blistDisplayName" + xbl:inherits="value=displayname,status"/> +@@ -529,30 +529,29 @@ + + <binding id="contact-big" extends="chrome://instantbird/content/contact.xml#contact"> + <content> +- <xul:hbox flex="1" mousethrough="always"> +- <xul:stack class="prplBuddyIcon" mousethrough="always"> +- <xul:image class="protoIcon" xbl:inherits="src=iconPrpl,status"/> +- <xul:image class="statusIcon" xbl:inherits="status"/> +- </xul:stack> +- <xul:vbox flex="1" class="contact-vbox" mousethrough="always"> +- <xul:hbox class="contact-hbox" mousethrough="always"> +- <xul:label crop="end" flex="1" mousethrough="always" +- anonid="displayname" class="contactDisplayName blistDisplayName" +- xbl:inherits="value=displayname,status"/> +- <xul:button anonid="startChatBubble" class="startChatBubble" +- tooltiptext="&openConversationCmd.label;"/> +- </xul:hbox> +- <xul:hbox class="contact-hbox" mousethrough="always"> +- <xul:label crop="end" flex="1" mousethrough="always" +- anonid="statusText" class="contactStatusText" +- xbl:inherits="value=statusText"/> +- <xul:button anonid="expander" class="expander-down" +- tooltiptextexpand="&expandContactTooltip;" +- tooltiptextcollapse="&collapseContactTooltip;" +- tooltiptext="&expandContactTooltip;"/> +- </xul:hbox> +- </xul:vbox> +- </xul:hbox> ++ <xul:vbox flex="1" class="contact-vbox" mousethrough="always"> ++ <xul:hbox flex="1" class="contact-hbox" mousethrough="always" align="center"> ++ <xul:stack class="prplBuddyIcon" mousethrough="always"> ++ <xul:image class="protoIcon" xbl:inherits="src=iconPrpl,status"/> ++ <xul:image class="statusIcon" xbl:inherits="status"/> ++ </xul:stack> ++ <xul:label crop="end" flex="1" mousethrough="always" ++ anonid="displayname" class="contactDisplayName blistDisplayName" ++ xbl:inherits="value=displayname,status"/> ++ <xul:button anonid="startChatBubble" class="startChatBubble" ++ tooltiptext="&openConversationCmd.label;"/> ++ </xul:hbox> ++ ++ <xul:hbox flex="1" class="contact-hbox" mousethrough="always" align="center"> ++ <xul:label crop="end" flex="1" mousethrough="always" ++ anonid="statusText" class="contactStatusText contactIconSpace" ++ xbl:inherits="value=statusText"/> ++ <xul:button anonid="expander" class="expander-down" ++ tooltiptextexpand="&expandContactTooltip;" ++ tooltiptextcollapse="&collapseContactTooltip;" ++ tooltiptext="&expandContactTooltip;"/> ++ </xul:hbox> ++ </xul:vbox> + <xul:vbox anonid="contactBuddies" class="contactBuddies"> + <children/> + </xul:vbox> +diff --git a/im/content/conv.xml b/im/content/conv.xml +index 96a33af64..c41da6fb4 100644 +--- a/im/content/conv.xml ++++ b/im/content/conv.xml +@@ -16,11 +16,11 @@ + + <binding id="conv" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem"> + <content> +- <xul:stack class="prplBuddyIcon" mousethrough="always"> +- <xul:image class="protoIcon" xbl:inherits="src=iconPrpl,status"/> +- <xul:image class="statusIcon" xbl:inherits="status"/> +- </xul:stack> +- <xul:hbox flex="1" class="conv-hbox" mousethrough="always"> ++ <xul:hbox flex="1" class="conv-hbox" mousethrough="always" align="center"> ++ <xul:stack class="prplBuddyIcon" mousethrough="always"> ++ <xul:image class="protoIcon" xbl:inherits="src=iconPrpl,status"/> ++ <xul:image class="statusIcon" xbl:inherits="status"/> ++ </xul:stack> + <xul:label crop="end" flex="1" mousethrough="always" + anonid="displayname" class="convDisplayName blistDisplayName" + xbl:inherits="value=displayname,status"/> +diff --git a/im/locales/en-US/chrome/instantbird/instantbird.dtd b/im/locales/en-US/chrome/instantbird/instantbird.dtd +index 80b894862..fce965bb1 100644 +--- a/im/locales/en-US/chrome/instantbird/instantbird.dtd ++++ b/im/locales/en-US/chrome/instantbird/instantbird.dtd +@@ -95,6 +95,12 @@ + <!ENTITY userIcon.label "Change your icon"> + <!ENTITY contactsHeader.label "Contacts"> + <!ENTITY convsHeader.label "Conversations on hold"> ++<!-- LOCALIZATION NOTE (dummyContact.label): ++ This string is not displayed anywhere, but it is used to calculate ++ the height of an item in the contact list. Therefore you should ++ set it to a string which contains characters that cover all ++ vertical sizes that occur in your language. --> ++<!ENTITY dummyContact.label "SgFyWp"> + + <!ENTITY openConversationCmd.label "Start a conversation"> + <!ENTITY openConversationCmd.accesskey "c"> +diff --git a/im/themes/blist.css b/im/themes/blist.css +index 992267405..c033b51bc 100644 +--- a/im/themes/blist.css ++++ b/im/themes/blist.css +@@ -100,14 +100,7 @@ group { + padding: 0 2px; + } + +-conv, +-contact, +-buddy { +- height: 20px; /* 16+2+2px for the protocol icon, padding top and bottom */ +-} +- + /* The vertical padding directly on the binding would not be animated. */ +-.prplBuddyIcon, + group>* { + padding-top: 2px; + padding-bottom: 2px; +@@ -153,21 +146,28 @@ contact[droptarget] > buddy[dummy] { + margin: 0; + } + ++.contactDisplayName, + .buddyDisplayName { + -moz-margin-start: 2px; + } + ++/* Used for the second line of a contact-big to add space on the left ++ where the .prplBuddyIcon sits on the first line. */ ++.contactIconSpace { ++ /* .prplBuddyIcon width+margins (16+3+3) + .contactStatusText margin (2) */ ++ margin-inline-start: 24px; ++} ++ + .contact-hbox, + .conv-hbox { + margin: 2px 0; +- -moz-margin-start: 2px; + min-height: 16px; + overflow-x: hidden; + } + + /* Avoid a strange jumping bug when hovering and the startChatBubble appears */ + .contact-vbox { +- min-height: 40px; ++ min-height: calc(var(--blist-item-height) * 2); + } + + .hideGroupButton, +@@ -240,8 +240,8 @@ contact[droptarget] > buddy[dummy] { + .startChatBubble, + .expander-up, + .expander-down { +- width: 16px; +- height: 16px; ++ max-width: 16px; ++ max-height: 16px; + min-height: 16px; + min-width: 16px; + } +-- +2.11.0 + diff --git a/projects/instantbird/0023-Bug-1187281-Only-show-close-button-on-Windows.patch b/projects/instantbird/0023-Bug-1187281-Only-show-close-button-on-Windows.patch new file mode 100644 index 0000000..15fb272 --- /dev/null +++ b/projects/instantbird/0023-Bug-1187281-Only-show-close-button-on-Windows.patch @@ -0,0 +1,25 @@ +From df5943c2501769059a5ada93a5352f27f99f764b Mon Sep 17 00:00:00 2001 +From: Arlo Breault arlolra@gmail.com +Date: Sat, 5 Nov 2016 14:55:20 -0700 +Subject: [PATCH 23/26] Bug 1187281 - Only show "close" button on Windows + +--- + im/content/accounts.xul | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/im/content/accounts.xul b/im/content/accounts.xul +index f3f1c6bbb..d683562cb 100644 +--- a/im/content/accounts.xul ++++ b/im/content/accounts.xul +@@ -142,6 +142,8 @@ + <windowdragbox id="bottombuttons" align="center"> + <button id="newaccount" command="cmd_new"/> + <spacer flex="1"/> ++#ifdef XP_WIN + <button id="close" command="cmd_close"/> ++#endif + </windowdragbox> + </window> +-- +2.11.0 + diff --git a/projects/instantbird/0023-Bug-954368-Contact-list-entries-should-adapt-their-h.patch b/projects/instantbird/0023-Bug-954368-Contact-list-entries-should-adapt-their-h.patch deleted file mode 100644 index 970e181..0000000 --- a/projects/instantbird/0023-Bug-954368-Contact-list-entries-should-adapt-their-h.patch +++ /dev/null @@ -1,322 +0,0 @@ -From a9a6176b88f5c1d55a82058181c2c2f0684743ff Mon Sep 17 00:00:00 2001 -From: aleth aleth@instantbird.org -Date: Thu, 12 May 2016 15:10:43 +0200 -Subject: [PATCH 23/27] Bug 954368 - Contact list entries should adapt their - height to the actual font size. r=florian - ---HG-- -extra : rebase_source : 9820f3a68794f98260f3ac406772da6d176d02ec ---- - chat/themes/imtooltip.css | 1 + - im/content/blist.css | 38 ++++++++++++--- - im/content/blist.js | 7 +++ - im/content/blist.xul | 4 ++ - im/content/contact.xml | 57 +++++++++++----------- - im/content/conv.xml | 10 ++-- - .../en-US/chrome/instantbird/instantbird.dtd | 6 +++ - im/themes/blist.css | 22 ++++----- - 8 files changed, 92 insertions(+), 53 deletions(-) - -diff --git a/chat/themes/imtooltip.css b/chat/themes/imtooltip.css -index c4525beb5..630da3983 100644 ---- a/chat/themes/imtooltip.css -+++ b/chat/themes/imtooltip.css -@@ -31,6 +31,7 @@ - - .tooltipBuddies { - margin-left: -3px; -+ --blist-item-height: 20px; /* 16px icon plus padding */ - } - - .tooltipDisplayName { -diff --git a/im/content/blist.css b/im/content/blist.css -index d47e4f356..15b61b103 100644 ---- a/im/content/blist.css -+++ b/im/content/blist.css -@@ -30,15 +30,28 @@ group { - -moz-box-align: center; - } - --/* The height is required for the animation to work. The skin can -- * specify an additionnal min-height value if there are things of -- * constant size (icons + padding) */ --contact, --buddy, -+/* The height is required for the animation to work. */ - group { - height: 1em; - } - -+conv, -+contact, -+buddy { -+ /* Variable set from blist.js. This is necessary as CSS transitions don't -+ work with height: auto. -+ Usually 16+2+2px for the protocol icon, padding top and bottom. */ -+ height: var(--blist-item-height); -+} -+ -+contact[open], -+contact[aliasing], -+#buddylistbox:focus > contact[selected] { -+ /* This is fine because height transitions in this state are on the -+ buddies, and there is no transition on selection (it's instant). */ -+ height: auto; -+} -+ - /* Possible values of the |state| attribute: - - not set: the binding is not initialized yet, - - showing: during the expand animation, -@@ -51,23 +64,24 @@ contact:not([state]), - buddy:not([state]) { - height: 0; - } -+ - contact[state="showing"], - buddy[state="showing"] { - /* Should match the transition effect for contact/buddy collapsing so - that reordering doesn't make the whole list jump. */ -- -moz-transition: height .2s ease-in; -+ transition: height .2s ease-in; - } - - contact[state="fading"] { - opacity: 0; -- -moz-transition: opacity .4s ease-in 1s; -+ transition: opacity .4s ease-in 1s; - } - - contact[state="collapsing"], - buddy[state="collapsing"], - group[collapsing="true"] { - height: 0; -- -moz-transition: height .2s ease-in; -+ transition: height .2s ease-in; - } - - contact[state="collapsing"] *, -@@ -78,6 +92,14 @@ group[collapsing="true"] * { - display: none; - } - -+#dummyContact { -+ height: auto; -+} -+ -+#dummylistbox { -+ visibility: hidden; -+} -+ - tooltip[type="im"] { - -moz-binding: url("chrome://chat/content/imtooltip.xml#tooltip"); - } -diff --git a/im/content/blist.js b/im/content/blist.js -index 9ec10e25c..ce76ffcd7 100644 ---- a/im/content/blist.js -+++ b/im/content/blist.js -@@ -820,6 +820,13 @@ var buddyList = { - .setAttribute("checked", "true"); - } - -+ // Find the correct height of a contact list item. This can vary depending -+ // on the platform font and font size. -+ let dummyContact = document.getElementById("dummyContact"); -+ let contactHeight = dummyContact.getBoundingClientRect().height; -+ document.getElementById("buddyListMsg") -+ .style.setProperty("--blist-item-height", contactHeight + "px"); -+ - let blistBox = document.getElementById("buddylistbox"); - blistBox.removeGroup = function(aGroupElt) { - let index = buddyList._displayedGroups.indexOf(aGroupElt); -diff --git a/im/content/blist.xul b/im/content/blist.xul -index f29a48b99..71ee2c9ef 100644 ---- a/im/content/blist.xul -+++ b/im/content/blist.xul -@@ -224,6 +224,10 @@ - onfocus="buddyList.buddylistboxFocus();" - onselect="buddyList.listboxSelect(event);" - tooltip="imTooltip"/> -+ <richlistbox id="dummylistbox"> -+ <contact id="dummyContact" displayname="&dummyContact.label;" -+ state="visible" status="unknown"/> -+ </richlistbox> - <spacer id="listSpacer" flex="1" - onclick='document.getElementById("buddylistbox").focus();'/> - </notificationbox> -diff --git a/im/content/contact.xml b/im/content/contact.xml -index 5fc36dd6e..f2b464182 100644 ---- a/im/content/contact.xml -+++ b/im/content/contact.xml -@@ -16,11 +16,11 @@ - - <binding id="contact" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem"> - <content> -- <xul:stack class="prplBuddyIcon" mousethrough="always"> -- <xul:image class="protoIcon" xbl:inherits="src=iconPrpl,status"/> -- <xul:image class="statusIcon" xbl:inherits="status"/> -- </xul:stack> -- <xul:hbox flex="1" class="contact-hbox" mousethrough="always"> -+ <xul:hbox flex="1" class="contact-hbox" mousethrough="always" align="center"> -+ <xul:stack class="prplBuddyIcon" mousethrough="always"> -+ <xul:image class="protoIcon" xbl:inherits="src=iconPrpl,status"/> -+ <xul:image class="statusIcon" xbl:inherits="status"/> -+ </xul:stack> - <xul:label crop="end" flex="1" mousethrough="always" - anonid="displayname" class="contactDisplayName blistDisplayName" - xbl:inherits="value=displayname,status"/> -@@ -529,30 +529,29 @@ - - <binding id="contact-big" extends="chrome://instantbird/content/contact.xml#contact"> - <content> -- <xul:hbox flex="1" mousethrough="always"> -- <xul:stack class="prplBuddyIcon" mousethrough="always"> -- <xul:image class="protoIcon" xbl:inherits="src=iconPrpl,status"/> -- <xul:image class="statusIcon" xbl:inherits="status"/> -- </xul:stack> -- <xul:vbox flex="1" class="contact-vbox" mousethrough="always"> -- <xul:hbox class="contact-hbox" mousethrough="always"> -- <xul:label crop="end" flex="1" mousethrough="always" -- anonid="displayname" class="contactDisplayName blistDisplayName" -- xbl:inherits="value=displayname,status"/> -- <xul:button anonid="startChatBubble" class="startChatBubble" -- tooltiptext="&openConversationCmd.label;"/> -- </xul:hbox> -- <xul:hbox class="contact-hbox" mousethrough="always"> -- <xul:label crop="end" flex="1" mousethrough="always" -- anonid="statusText" class="contactStatusText" -- xbl:inherits="value=statusText"/> -- <xul:button anonid="expander" class="expander-down" -- tooltiptextexpand="&expandContactTooltip;" -- tooltiptextcollapse="&collapseContactTooltip;" -- tooltiptext="&expandContactTooltip;"/> -- </xul:hbox> -- </xul:vbox> -- </xul:hbox> -+ <xul:vbox flex="1" class="contact-vbox" mousethrough="always"> -+ <xul:hbox flex="1" class="contact-hbox" mousethrough="always" align="center"> -+ <xul:stack class="prplBuddyIcon" mousethrough="always"> -+ <xul:image class="protoIcon" xbl:inherits="src=iconPrpl,status"/> -+ <xul:image class="statusIcon" xbl:inherits="status"/> -+ </xul:stack> -+ <xul:label crop="end" flex="1" mousethrough="always" -+ anonid="displayname" class="contactDisplayName blistDisplayName" -+ xbl:inherits="value=displayname,status"/> -+ <xul:button anonid="startChatBubble" class="startChatBubble" -+ tooltiptext="&openConversationCmd.label;"/> -+ </xul:hbox> -+ -+ <xul:hbox flex="1" class="contact-hbox" mousethrough="always" align="center"> -+ <xul:label crop="end" flex="1" mousethrough="always" -+ anonid="statusText" class="contactStatusText contactIconSpace" -+ xbl:inherits="value=statusText"/> -+ <xul:button anonid="expander" class="expander-down" -+ tooltiptextexpand="&expandContactTooltip;" -+ tooltiptextcollapse="&collapseContactTooltip;" -+ tooltiptext="&expandContactTooltip;"/> -+ </xul:hbox> -+ </xul:vbox> - <xul:vbox anonid="contactBuddies" class="contactBuddies"> - <children/> - </xul:vbox> -diff --git a/im/content/conv.xml b/im/content/conv.xml -index 96a33af64..c41da6fb4 100644 ---- a/im/content/conv.xml -+++ b/im/content/conv.xml -@@ -16,11 +16,11 @@ - - <binding id="conv" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem"> - <content> -- <xul:stack class="prplBuddyIcon" mousethrough="always"> -- <xul:image class="protoIcon" xbl:inherits="src=iconPrpl,status"/> -- <xul:image class="statusIcon" xbl:inherits="status"/> -- </xul:stack> -- <xul:hbox flex="1" class="conv-hbox" mousethrough="always"> -+ <xul:hbox flex="1" class="conv-hbox" mousethrough="always" align="center"> -+ <xul:stack class="prplBuddyIcon" mousethrough="always"> -+ <xul:image class="protoIcon" xbl:inherits="src=iconPrpl,status"/> -+ <xul:image class="statusIcon" xbl:inherits="status"/> -+ </xul:stack> - <xul:label crop="end" flex="1" mousethrough="always" - anonid="displayname" class="convDisplayName blistDisplayName" - xbl:inherits="value=displayname,status"/> -diff --git a/im/locales/en-US/chrome/instantbird/instantbird.dtd b/im/locales/en-US/chrome/instantbird/instantbird.dtd -index 80b894862..fce965bb1 100644 ---- a/im/locales/en-US/chrome/instantbird/instantbird.dtd -+++ b/im/locales/en-US/chrome/instantbird/instantbird.dtd -@@ -95,6 +95,12 @@ - <!ENTITY userIcon.label "Change your icon"> - <!ENTITY contactsHeader.label "Contacts"> - <!ENTITY convsHeader.label "Conversations on hold"> -+<!-- LOCALIZATION NOTE (dummyContact.label): -+ This string is not displayed anywhere, but it is used to calculate -+ the height of an item in the contact list. Therefore you should -+ set it to a string which contains characters that cover all -+ vertical sizes that occur in your language. --> -+<!ENTITY dummyContact.label "SgFyWp"> - - <!ENTITY openConversationCmd.label "Start a conversation"> - <!ENTITY openConversationCmd.accesskey "c"> -diff --git a/im/themes/blist.css b/im/themes/blist.css -index 992267405..c033b51bc 100644 ---- a/im/themes/blist.css -+++ b/im/themes/blist.css -@@ -100,14 +100,7 @@ group { - padding: 0 2px; - } - --conv, --contact, --buddy { -- height: 20px; /* 16+2+2px for the protocol icon, padding top and bottom */ --} -- - /* The vertical padding directly on the binding would not be animated. */ --.prplBuddyIcon, - group>* { - padding-top: 2px; - padding-bottom: 2px; -@@ -153,21 +146,28 @@ contact[droptarget] > buddy[dummy] { - margin: 0; - } - -+.contactDisplayName, - .buddyDisplayName { - -moz-margin-start: 2px; - } - -+/* Used for the second line of a contact-big to add space on the left -+ where the .prplBuddyIcon sits on the first line. */ -+.contactIconSpace { -+ /* .prplBuddyIcon width+margins (16+3+3) + .contactStatusText margin (2) */ -+ margin-inline-start: 24px; -+} -+ - .contact-hbox, - .conv-hbox { - margin: 2px 0; -- -moz-margin-start: 2px; - min-height: 16px; - overflow-x: hidden; - } - - /* Avoid a strange jumping bug when hovering and the startChatBubble appears */ - .contact-vbox { -- min-height: 40px; -+ min-height: calc(var(--blist-item-height) * 2); - } - - .hideGroupButton, -@@ -240,8 +240,8 @@ contact[droptarget] > buddy[dummy] { - .startChatBubble, - .expander-up, - .expander-down { -- width: 16px; -- height: 16px; -+ max-width: 16px; -+ max-height: 16px; - min-height: 16px; - min-width: 16px; - } --- -2.11.0 - diff --git a/projects/instantbird/0024-Bug-1187281-Only-show-close-button-on-Windows.patch b/projects/instantbird/0024-Bug-1187281-Only-show-close-button-on-Windows.patch deleted file mode 100644 index 4c2516c..0000000 --- a/projects/instantbird/0024-Bug-1187281-Only-show-close-button-on-Windows.patch +++ /dev/null @@ -1,25 +0,0 @@ -From c8130e504c68957e03541d522429bad31c5c5d21 Mon Sep 17 00:00:00 2001 -From: Arlo Breault arlolra@gmail.com -Date: Sat, 5 Nov 2016 14:55:20 -0700 -Subject: [PATCH 24/27] Bug 1187281 - Only show "close" button on Windows - ---- - im/content/accounts.xul | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/im/content/accounts.xul b/im/content/accounts.xul -index f3f1c6bbb..d683562cb 100644 ---- a/im/content/accounts.xul -+++ b/im/content/accounts.xul -@@ -142,6 +142,8 @@ - <windowdragbox id="bottombuttons" align="center"> - <button id="newaccount" command="cmd_new"/> - <spacer flex="1"/> -+#ifdef XP_WIN - <button id="close" command="cmd_close"/> -+#endif - </windowdragbox> - </window> --- -2.11.0 - diff --git a/projects/instantbird/0024-Bug-1316000-Remove-old-Yahoo-Messenger-support.-r-al.patch b/projects/instantbird/0024-Bug-1316000-Remove-old-Yahoo-Messenger-support.-r-al.patch new file mode 100644 index 0000000..0a5fbb4 --- /dev/null +++ b/projects/instantbird/0024-Bug-1316000-Remove-old-Yahoo-Messenger-support.-r-al.patch @@ -0,0 +1,2398 @@ +From 300fcb344de6111a6f96ebda90fe8f70a8534e00 Mon Sep 17 00:00:00 2001 +From: Patrick Cloke clokep@gmail.com +Date: Wed, 9 Nov 2016 09:03:49 -0800 +Subject: [PATCH 24/26] Bug 1316000 - Remove old Yahoo! Messenger support. + r=aleth + +--- + chat/chat-prefs.js | 2 + + chat/locales/en-US/facebook.properties | 3 +- + chat/locales/en-US/yahoo.properties | 34 +- + chat/protocols/facebook/facebook.js | 13 +- + chat/protocols/yahoo/moz.build | 6 - + chat/protocols/yahoo/test/test_yahooAccount.js | 98 -- + chat/protocols/yahoo/test/test_yahooLoginHelper.js | 89 -- + chat/protocols/yahoo/test/test_yahoopacket.js | 217 ---- + chat/protocols/yahoo/test/xpcshell.ini | 7 - + chat/protocols/yahoo/yahoo-session.jsm | 1156 -------------------- + chat/protocols/yahoo/yahoo.js | 552 +--------- + im/content/conversation.xml | 3 +- + .../chrome/instantbird/accountWizard.properties | 3 +- + im/test/xpcshell.ini | 1 - + mail/components/im/content/imconversation.xml | 3 +- + 15 files changed, 18 insertions(+), 2169 deletions(-) + delete mode 100644 chat/protocols/yahoo/test/test_yahooAccount.js + delete mode 100644 chat/protocols/yahoo/test/test_yahooLoginHelper.js + delete mode 100644 chat/protocols/yahoo/test/test_yahoopacket.js + delete mode 100644 chat/protocols/yahoo/test/xpcshell.ini + delete mode 100644 chat/protocols/yahoo/yahoo-session.jsm + +diff --git a/chat/chat-prefs.js b/chat/chat-prefs.js +index fb769163d..60b9c1e8c 100644 +--- a/chat/chat-prefs.js ++++ b/chat/chat-prefs.js +@@ -84,6 +84,8 @@ pref("chat.irc.automaticList", true); + pref("chat.prpls.prpl-skype.disable", true); + // Disable Facebook as the XMPP gateway no longer exists. + pref("chat.prpls.prpl-facebook.disable", true); ++// Disable Yahoo Messenger as legacy Yahoo was shut down. ++pref("chat.prpls.prpl-yahoo.disable", true); + + // loglevel is the minimum severity level that a libpurple message + // must have to be reported in the Error Console. +diff --git a/chat/locales/en-US/facebook.properties b/chat/locales/en-US/facebook.properties +index aaf7cdc9c..2e00cbcb2 100644 +--- a/chat/locales/en-US/facebook.properties ++++ b/chat/locales/en-US/facebook.properties +@@ -2,6 +2,5 @@ + # 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/. + +-connection.error.useUsernameNotEmailAddress=Please use your Facebook username, not an email address +- + facebook.chat.name=Facebook Chat ++facebook.disabled=Facebook Chat is no longer supported due to Facebook disabling their XMPP gateway. +diff --git a/chat/locales/en-US/yahoo.properties b/chat/locales/en-US/yahoo.properties +index 727faa6ee..89ee0093c 100644 +--- a/chat/locales/en-US/yahoo.properties ++++ b/chat/locales/en-US/yahoo.properties +@@ -2,36 +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/. + +-login.error.badCredentials=Username or password is incorrect. +-login.error.accountLockedFailed=Account locked due to too many failed login attempts. +-login.error.accountLockedGeneral=Account locked due to too many login attempts. +-login.error.accountDeactivated=Account has been deactivated. +-login.error.usernameNotExist=The username does not exist. +-# The %S will be an error code returned by the server. +-login.error.unknown=Unknown error: %S +-network.error.http=HTTP connection error. +- +-conference.invite.message=Join my conference. +- +-# Some options are commented out because they aren't used. We do the same thing +-# to their description strings. +-options.pagerPort=Port +-options.transferHost=File transfer server +-options.transferPort=File transfer port +-options.chatEncoding=Encoding +-options.ignoreInvites=Ignore conference invitations +- +-# In this message, %S is replaced with the username of the user who left. +-system.message.conferenceLogoff=%S has left the conference. +-system.message.conferenceLogon=%S has joined the conference. +- +-# LOCALZIATION NOTE (command.*): +-# These are the help messages for each command, the %S is the command name +-# Each command first gives the parameter it accepts and then a description of +-# the command. +-command.help.invite2=%S <user1>[,<user2>,...] [<invite message>]: invite one or more users into this conference chat. +-command.help.conference=%S: Create a new conference room in which you can later invite other users. +- +-# LOCALIZATION NOTE (command.feedback.invite): +-# %S is the user, or comma separated list of users, invited to the conference. +-command.feedback.invite=You have invited %S to the conference. ++yahoo.disabled=Yahoo Messenger is no longer supported due to Yahoo disabling their legacy protocol. +diff --git a/chat/protocols/facebook/facebook.js b/chat/protocols/facebook/facebook.js +index 7b5b3b86e..9d90eacdb 100644 +--- a/chat/protocols/facebook/facebook.js ++++ b/chat/protocols/facebook/facebook.js +@@ -6,33 +6,26 @@ var {interfaces: Ci, utils: Cu} = Components; + + Cu.import("resource:///modules/imXPCOMUtils.jsm"); + Cu.import("resource:///modules/jsProtoHelper.jsm"); +-Cu.import("resource:///modules/xmpp.jsm"); +-Cu.import("resource:///modules/xmpp-session.jsm"); + + XPCOMUtils.defineLazyGetter(this, "_", () => + l10nHelper("chrome://chat/locale/facebook.properties") + ); +-XPCOMUtils.defineLazyGetter(this, "_irc", () => +- l10nHelper("chrome://chat/locale/irc.properties") +-); + + function FacebookAccount(aProtoInstance, aImAccount) { + this._init(aProtoInstance, aImAccount); + } + FacebookAccount.prototype = { +- __proto__: XMPPAccountPrototype, +- get canJoinChat() { return false; }, ++ __proto__: GenericAccountPrototype, + connect: function() { + this.WARN("As Facebook deprecated its XMPP gateway, it is currently not " + + "possible to connect to Facebook Chat. See bug 1141674."); + this.reportDisconnecting(Ci.prplIAccount.ERROR_OTHER_ERROR, +- _irc("error.unavailable", _("facebook.chat.name"))); ++ _("facebook.disabled")); + this.reportDisconnected(); + } + }; + +-function FacebookProtocol() { +-} ++function FacebookProtocol() {} + FacebookProtocol.prototype = { + __proto__: GenericProtocolPrototype, + get normalizedName() { return "facebook"; }, +diff --git a/chat/protocols/yahoo/moz.build b/chat/protocols/yahoo/moz.build +index f14434732..ea378535a 100644 +--- a/chat/protocols/yahoo/moz.build ++++ b/chat/protocols/yahoo/moz.build +@@ -3,15 +3,9 @@ + # 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/. + +-XPCSHELL_TESTS_MANIFESTS += ['test/xpcshell.ini'] +- + EXTRA_COMPONENTS += [ + 'yahoo.js', + 'yahoo.manifest', + ] + +-EXTRA_JS_MODULES += [ +- 'yahoo-session.jsm', +-] +- + JAR_MANIFESTS += ['jar.mn'] +diff --git a/chat/protocols/yahoo/test/test_yahooAccount.js b/chat/protocols/yahoo/test/test_yahooAccount.js +deleted file mode 100644 +index 51df00bb9..000000000 +--- a/chat/protocols/yahoo/test/test_yahooAccount.js ++++ /dev/null +@@ -1,98 +0,0 @@ +-/* Any copyright is dedicated to the Public Domain. +- * http://creativecommons.org/publicdomain/zero/1.0/ */ +- +-Components.utils.import("resource://gre/modules/Services.jsm"); +-var yahoo = {}; +-Services.scriptloader.loadSubScript("resource:///components/yahoo.js", yahoo); +- +-function run_test() +-{ +- add_test(test_cleanUsername); +- add_test(test_fixFontSize); +- run_next_test(); +-} +- +-// Test the stripping of @yahoo.* domains from usernames. +-function test_cleanUsername() +-{ +- // These are just a few of the many possible domains. +- let domains = ["yahoo.com.ar", "yahoo.com.au", "yahoo.com", "yahoo.co.jp", +- "yahoo.it", "yahoo.cn", "yahoo.co.in"]; +- let userId = "user"; +- +- // We must provide a mimimal fake implementation of a protocol object, to keep +- // the YahooAccount constructor happy. +- let fakeProtocol = { +- id: "fake-proto", +- options: { +- local_charset: "UTF-8" +- }, +- _getOptionDefault: function(aOption) { return this.options[aOption]; } +- }; +- let fakeImAccount = {}; +- +- for each(let domain in domains) { +- fakeImAccount.name = userId + "@" + domain; +- let yahooAccount = new yahoo.YahooAccount(fakeProtocol, fakeImAccount); +- do_check_eq(userId, yahooAccount.cleanUsername); +- } +- run_next_test(); +-} +- +-// Test the _fixFontSize() method and ensure that it correctly fixes font sizes +-// in <font> tags while keeping any mention of size= in conversation untouched. +-function test_fixFontSize() +-{ +- // This is an array of two-element arrays. Each inner two-element array +- // contains a message with a badly formed font size as the first element, +- // and a message with a well-formed font size as the second element. We test +- // to ensure that the badly formed message is converted to the well-formed +- // one. +- let testMessages = [ +- // Single font tag. +- ["<font face="Arial" size="12">Test message 1", +- "<font face="Arial" size="3">Test message 1"], +- // Single font tag with size="<digit>" in innner message. +- ["<font face="Arial" size="9">size="30" is a big size.</font>", +- "<font face="Arial" size="2">size="30" is a big size.</font>"], +- // Single font tag with no face attribute. +- ["<font size="12">This message has no font face attribute.", +- "<font size="3">This message has no font face attribute."], +- // Single font tag with no size attribute. +- ["<font face="Arial">This message has no font size attribute.", +- "<font face="Arial">This message has no font size attribute."], +- // Single font tag with rearranged attribute order. +- ["<font size="9" face="Arial">size="30" is a big size.</font>", +- "<font size="2" face="Arial">size="30" is a big size.</font>"], +- // Multiple font tags. +- ["<font face="Arial" size="12">Hello. <font face="Consolas" size="40">World", +- "<font face="Arial" size="3">Hello. <font face="Consolas" size="7">World"] +- ]; +- +- let fakeProtocol = { +- id: "fake-proto", +- options: { +- local_charset: "UTF-8" +- }, +- _getOptionDefault: function(aOption) { return this.options[aOption]; } +- }; +- let fakeImAccount = {name: "test-user"}; +- // We create a fake conversation object so we can obtain the cleaned up +- // message from the conv.writeMessage() call. +- let messagePair; +- let fakeConversation = { +- writeMessage: function(aName, aMessage, aProperties) { +- do_check_eq(aMessage, messagePair[1]); // Compare to the good message. +- }, +- updateTyping: function(aStatus, aName) { } +- }; +- +- let yahooAccount = new yahoo.YahooAccount(fakeProtocol, fakeImAccount); +- yahooAccount._conversations.set("test-user", fakeConversation); +- for each(let pair in testMessages) { +- messagePair = pair; +- // Send in the badly formed message. +- yahooAccount.receiveMessage("test-user", messagePair[0]); +- } +- run_next_test(); +-} +diff --git a/chat/protocols/yahoo/test/test_yahooLoginHelper.js b/chat/protocols/yahoo/test/test_yahooLoginHelper.js +deleted file mode 100644 +index e4d8bc1b8..000000000 +--- a/chat/protocols/yahoo/test/test_yahooLoginHelper.js ++++ /dev/null +@@ -1,89 +0,0 @@ +-/* Any copyright is dedicated to the Public Domain. +- * http://creativecommons.org/publicdomain/zero/1.0/ */ +- +-Components.utils.import("resource:///modules/ArrayBufferUtils.jsm"); +-Components.utils.import("resource://gre/modules/Services.jsm"); +-Components.utils.import("resource:///modules/yahoo-session.jsm"); +-var yahoo = {}; +-Services.scriptloader.loadSubScript("resource:///modules/yahoo-session.jsm", yahoo); +- +-// Preset test values. +-var kUsername = "testUser"; +-var kPassword = "instantbird"; +-var kPagerIp = "123.456.78.9"; +-var kCrumb = "MG-Z/jNG+Q=="; +-var kChallengeString = "AEF08DBAC33F9EEDABCFEA=="; +-var kYCookie = "OTJmMTQyOTU1ZGQ4MDA3Y2I2ODljMTU5"; +-var kTCookie = "NTdlZmIzY2Q4ODI3ZTc3NTIxYTk1MDhm"; +-var kToken = "MThmMzg3OWM3ODcxMW"; +- +-var kPagerAddressResponse = "COLO_CAPACITY=1\r\nCS_IP_ADDRESS=" + kPagerIp; +-var kTokenResponse = "0\r\n" + kToken + "\r\npartnerid=dummyValue"; +-var kCookieResponse = "0\r\ncrumb=" + kCrumb + "\r\nY=" + kYCookie + +- "\r\nT=" + kTCookie + "\r\ncookievalidfor=86400"; +- +-/* In each test, we override the function that would normally be called next in +- * the login process. We do this so that we can intercept the login process, +- * preventing calls to real Yahoo! servers, and do equality testing. */ +-function run_test() +-{ +- add_test(test_pagerAddress); +- add_test(test_challengeString); +- add_test(test_loginToken); +- add_test(test_cookies); +- run_next_test(); +-} +- +-function test_pagerAddress() +-{ +- let helper = new yahoo.YahooLoginHelper({}, {}); +- +- helper._getChallengeString = function() { +- do_check_eq(kPagerIp, helper._session.pagerAddress); +- run_next_test(); +- }; +- +- helper._onPagerAddressResponse(kPagerAddressResponse, null); +-} +- +-function test_challengeString() +-{ +- let helper = new yahoo.YahooLoginHelper({}, {}); +- +- helper._getLoginToken = function() { +- do_check_eq(kChallengeString, helper._challengeString); +- run_next_test(); +- }; +- +- let response = new yahoo.YahooPacket(yahoo.kPacketType.AuthResponse, 0, 0); +- response.addValue(1, helper._username); +- response.addValue(94, kChallengeString); +- response.addValue(13, 0); +- helper._onChallengeStringResponse(response.toArrayBuffer()); +-} +- +-function test_loginToken() +-{ +- let helper = new yahoo.YahooLoginHelper({}, {}); +- +- helper._getCookies = function() { +- do_check_eq(kToken, helper._loginToken); +- run_next_test(); +- }; +- +- helper._onLoginTokenResponse(kTokenResponse, null); +-} +- +-function test_cookies() +-{ +- let helper = new yahoo.YahooLoginHelper({}, {}); +- +- helper._sendPagerAuthResponse = function() { +- do_check_eq(kCrumb, helper._crumb); +- do_check_eq(kYCookie, helper._session.yCookie); +- do_check_eq(kTCookie, helper._session.tCookie); +- run_next_test(); +- }; +- +- helper._onLoginCookiesResponse(kCookieResponse, null); +-} +diff --git a/chat/protocols/yahoo/test/test_yahoopacket.js b/chat/protocols/yahoo/test/test_yahoopacket.js +deleted file mode 100644 +index 7908c4429..000000000 +--- a/chat/protocols/yahoo/test/test_yahoopacket.js ++++ /dev/null +@@ -1,217 +0,0 @@ +-/* Any copyright is dedicated to the Public Domain. +- * http://creativecommons.org/publicdomain/zero/1.0/ */ +- +-Components.utils.import("resource:///modules/ArrayBufferUtils.jsm"); +-Components.utils.import("resource://gre/modules/Services.jsm"); +-Components.utils.import("resource:///modules/yahoo-session.jsm"); +-var yahoo = {}; +-Services.scriptloader.loadSubScript("resource:///modules/yahoo-session.jsm", yahoo); +- +-var kPacketIdBytes = StringToBytes(yahoo.kPacketIdentfier); +-var kHelloKey = 1; +-var kHelloValue = "Hello"; +-var kWorldKey = 20; +-var kWorldValue = "World"; +-var kNumberKey = 4; +-var kNumberValue = 32; +-var kParamsKey = 60; +-var kParam1Value = "param1"; +-var kParam2Value = "param2"; +-var kPacketDataString = "1\xC0\x80Hello\xC0\x8020\xC0\x80World\xC0\x80" + +- "4\xC0\x8032\xC0\x8060\xC0\x80param1\xC0\x80" + +- "60\xC0\x80param2\xC0\x80"; +- +-function run_test() +-{ +- add_test(test_headerCreation); +- add_test(test_fullPacketCreation); +- add_test(test_packetDecoding); +- add_test(test_extractPackets); +- add_test(test_malformedPacketExtraction); +- +- run_next_test(); +-} +- +-function test_headerCreation() +-{ +- let packetLength = 0; +- // Random numbers. +- let serviceNumber = 0x57; +- let status = 0x04; +- let sessionId = 0x57842390; +- +- let packet = new yahoo.YahooPacket(serviceNumber, status, sessionId); +- let buf = packet.toArrayBuffer(); +- let view = new DataView(buf); +- +- // Ensure that the first 4 bytes contain the YMSG identifier. +- for (let i = 0; i < kPacketIdBytes.length; ++i) +- do_check_eq(kPacketIdBytes[i], view.getUint8(i)); +- +- do_check_eq(yahoo.kProtocolVersion, view.getUint16(4)); +- do_check_eq(yahoo.kVendorId, view.getUint16(6)); +- do_check_eq(packetLength, view.getUint16(8)); +- do_check_eq(serviceNumber, view.getUint16(10)); +- do_check_eq(status, view.getUint32(12)); +- do_check_eq(sessionId, view.getUint32(16)); +- +- run_next_test(); +-} +- +-function test_fullPacketCreation() +-{ +- packetLength = kPacketDataString.length; +- // Random numbers. +- let serviceNumber = 0x55; +- let status = 0x02; +- let sessionId = 0x12567800; +- +- let packet = new yahoo.YahooPacket(serviceNumber, status, sessionId); +- packet.addValue(kHelloKey, kHelloValue); +- packet.addValue(kWorldKey, kWorldValue); +- packet.addValue(kNumberKey, kNumberValue); +- packet.addValues(kParamsKey, [kParam1Value, kParam2Value]); +- let buf = packet.toArrayBuffer(); +- let view = new DataView(buf); +- +- // Header check. +- +- // Ensure that the first 4 bytes contain the YMSG identifier. +- for (let i = 0; i < kPacketIdBytes.length; ++i) +- do_check_eq(kPacketIdBytes[i], view.getUint8(i)); +- +- do_check_eq(yahoo.kProtocolVersion, view.getUint16(4)); +- do_check_eq(yahoo.kVendorId, view.getUint16(6)); +- do_check_eq(packetLength, view.getUint16(8)); +- do_check_eq(serviceNumber, view.getUint16(10)); +- do_check_eq(status, view.getUint32(12)); +- do_check_eq(sessionId, view.getUint32(16)); +- +- // Packet data check. +- let dataBytes = StringToBytes(kPacketDataString); +- for (let i = 0; i < dataBytes.length; ++i) +- do_check_eq(dataBytes[i], view.getUint8(yahoo.kPacketHeaderSize + i)); +- run_next_test() +-} +- +-function test_packetDecoding() +-{ +- let packetLength = kPacketDataString.length; +- // Random numbers. +- let serviceNumber = 0x20; +- let status = 0x06; +- let sessionId = 0x13319AB2; +- +- let buf = new ArrayBuffer(yahoo.kPacketHeaderSize + packetLength); +- let view = new DataView(buf); +- +- for (let i = 0; i < kPacketIdBytes.length; ++i) +- view.setUint8(i, kPacketIdBytes[i]); +- +- view.setUint16(4, yahoo.kProtocolVersion); +- view.setUint16(6, yahoo.kVendorId); +- view.setUint16(8, packetLength); +- view.setUint16(10, serviceNumber); +- view.setUint32(12, status); +- view.setUint32(16, sessionId); +- +- let dataBuf = BytesToArrayBuffer(StringToBytes(kPacketDataString)); +- copyBytes(buf, dataBuf, 20); +- +- // Now we decode and test. +- let packet = new yahoo.YahooPacket(); +- packet.fromArrayBuffer(buf); +- +- // Test header information. +- do_check_eq(serviceNumber, packet.service); +- do_check_eq(status, packet.status); +- do_check_eq(sessionId, packet.sessionId); +- +- // Test the getting of single packet data values. +- do_check_eq(kHelloValue, packet.getValue(kHelloKey)); +- do_check_eq(kWorldValue, packet.getValue(kWorldKey)); +- do_check_eq(kNumberValue, packet.getValue(kNumberKey)); +- +- // Test the getting of multiple values with a single key. +- let multiValue = packet.getValues(kParamsKey); +- do_check_eq(2, multiValue.length); +- do_check_eq(kParam1Value, multiValue[0]); +- do_check_eq(kParam2Value, multiValue[1]); +- +- // Test if certain keys are non-existant. +- do_check_true(packet.hasKey(kHelloKey)); +- do_check_false(packet.hasKey(500)); // There is no key 500. +- +- run_next_test(); +-} +- +-function test_extractPackets() +-{ +- // Some constants for each packet. +- const kP1Service = 0x47; +- const kP1Status = 0; +- const kP1SessionId = 0x12345678; +- // Used for testing packet verification. +- const kP1FuzzerKey = 42; +- const kP1FuzzerValue = "I am using the YMSG protocol!"; +- +- const kP2Service = 0x57; +- const kP2Status = 5; +- const kP2SessionId = 0x87654321; +- +- // First, create two packets and obtain their buffers. +- let packet1 = new yahoo.YahooPacket(kP1Service, kP1Status, kP1SessionId); +- packet1.addValue(kHelloKey, kHelloValue); +- packet1.addValue(kP1FuzzerKey, kP1FuzzerValue); +- let packet1Buffer = packet1.toArrayBuffer(); +- +- let packet2 = new yahoo.YahooPacket(kP2Service, kP2Status, kP2SessionId); +- packet2.addValue(kWorldKey, kWorldValue); +- let packet2Buffer = packet2.toArrayBuffer(); +- +- // Create one full buffer with both packets inside. +- let fullBuffer = new ArrayBuffer(packet1Buffer.byteLength + +- packet2Buffer.byteLength); +- copyBytes(fullBuffer, packet1Buffer); +- copyBytes(fullBuffer, packet2Buffer, packet1Buffer.byteLength); +- +- // Now, run the packets through the extractPackets() method. +- let [extractedPackets, bytesHandled] = +- yahoo.YahooPacket.extractPackets(fullBuffer); +- do_check_eq(2, extractedPackets.length); +- +- // Packet 1 checks. +- let p1 = extractedPackets[0]; +- do_check_eq(kP1Service, p1.service); +- do_check_eq(kP1Status, p1.status); +- do_check_eq(kP1SessionId, p1.sessionId); +- do_check_true(p1.hasKey(kHelloKey)); +- do_check_eq(kHelloValue, p1.getValue(kHelloKey)); +- +- // Packet 2 checks. +- let p2 = extractedPackets[1]; +- do_check_eq(kP2Service, p2.service); +- do_check_eq(kP2Status, p2.status); +- do_check_eq(kP2SessionId, p2.sessionId); +- do_check_true(p2.hasKey(kWorldKey)); +- do_check_eq(kWorldValue, p2.getValue(kWorldKey)); +- +- // Check if all the bytes were handled. +- do_check_eq(fullBuffer.byteLength, bytesHandled); +- +- run_next_test(); +-} +- +-function test_malformedPacketExtraction() +-{ +- const kInvalidPacketData = "MSYG1\xC0\x80Hello\xC0\x8020\xC0\x80World\xC0\x80"; +- let buffer = BytesToArrayBuffer(StringToBytes(kInvalidPacketData)); +- let malformed = false; +- try { +- yahoo.YahooPacket.extractPackets(buffer); +- } catch(e) { +- malformed = true; +- } +- do_check_true(malformed); +- run_next_test(); +-} +diff --git a/chat/protocols/yahoo/test/xpcshell.ini b/chat/protocols/yahoo/test/xpcshell.ini +deleted file mode 100644 +index f4b464e61..000000000 +--- a/chat/protocols/yahoo/test/xpcshell.ini ++++ /dev/null +@@ -1,7 +0,0 @@ +-[DEFAULT] +-head = +-tail = +- +-[test_yahooAccount.js] +-[test_yahooLoginHelper.js] +-[test_yahoopacket.js] +diff --git a/chat/protocols/yahoo/yahoo-session.jsm b/chat/protocols/yahoo/yahoo-session.jsm +deleted file mode 100644 +index cc9612036..000000000 +--- a/chat/protocols/yahoo/yahoo-session.jsm ++++ /dev/null +@@ -1,1156 +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/. */ +- +-this.EXPORTED_SYMBOLS = ["YahooSession"]; +- +-var {classes: Cc, interfaces: Ci, utils: Cu} = Components; +- +-Cu.import("resource://gre/modules/FileUtils.jsm"); +-Cu.import("resource://gre/modules/Http.jsm"); +-Cu.import("resource://gre/modules/NetUtil.jsm"); +-Cu.import("resource:///modules/ArrayBufferUtils.jsm"); +-Cu.import("resource:///modules/imServices.jsm"); +-Cu.import("resource:///modules/imXPCOMUtils.jsm"); +-Cu.import("resource:///modules/socket.jsm"); +- +-XPCOMUtils.defineLazyGetter(this, "_", () => +- l10nHelper("chrome://chat/locale/yahoo.properties") +-); +- +-XPCOMUtils.defineLazyServiceGetter(this, "imgTools", +- "@mozilla.org/image/tools;1", "imgITools"); +- +-var kProtocolVersion = 16; +-var kVendorId = 0; +- +-var kPacketDataDelimiter = "\xC0\x80"; +-var kPacketIdentifier = "YMSG"; +-var kPacketHeaderSize = 20; +-var kProfileIconWidth = 96; +- +-// These constants are used by the icon uploading code since the Yahoo! file +-// transfer server is used for user icon uploads. +-var kFileTransferHost = "filetransfer.msg.yahoo.com"; +-var kFileTransferPort = 80; +- +-var kPacketType = { +- // Sent by a client when logging off of the Yahoo! network. +- Logoff: 0x02, +- // Sent by a client when a message is sent to a buddy. +- Message: 0x06, +- // Sent to the pager server once per hour. +- Ping: 0x12, +- // Used for inviting others to a conference. +- ConfInvite: 0x18, +- // Used as a notification when you or someone else joins a conference room. +- ConfLogon: 0x19, +- // Used as a notification when you or someone else leaves a conference room. +- ConfLogoff: 0x1b, +- // This is sent by the client when additional users are invited to the +- // conference, but it can be sent as the first invite as well. +- ConfAddInvite: 0x1c, +- // Broadcast to all users in a conference room when someone posts a message. +- ConfMessage: 0x1d, +- // Used for typing notifications. +- Notify: 0x4b, +- // These two are used during initial authentication with the pager server. +- AuthResponse: 0x54, +- Auth: 0x57, +- // Buddy list controls. +- AddBuddy: 0x83, +- RemoveBuddy: 0x84, +- // This is sent when you reject a Yahoo! user's buddy request. +- BuddyReqReject: 0x86, +- // Sent to the server once every minute, telling it here are still alive. +- KeepAlive: 0x8A, +- // This is sent when we request a buddy icon. +- Picture: 0xbe, +- // This is sent after a profile picture has been successfully uploaded. +- PictureUpload: 0xc2, +- // This is sent whenever a buddy changes their status. +- StatusUpdate: 0xc6, +- // This is sent when we update our icon. +- AvatarUpdate: 0xc7, +- // This is sent when someone wishes to become your buddy. +- BuddyAuth: 0xd6, +- // Holds the initial status of all buddies when a user first logs in. +- StatusInitial: 0xf0, +- // Contains the buddy list sent from the server. +- List: 0xf1, +- // Sent back to the pager server after each received message. Sending this +- // prevents echoed messages when chatting with the official Yahoo! client. +- MessageAck: 0xfb +-}; +- +-var kPacketStatuses = { +- ServerAck: 0x1, +- Typing: 0x16 +-}; +- +-// Each Yahoo! error code is mapped to a two-element array. The first element +-// contains the last part of the name of its localized string. This is appended +-// to "login.error." to obtain the string. The second element is the +-// Instantbird error that is given to the error handler. +-var kLoginStatusErrors = { +- "1212" : ["badCredentials", +- Ci.prplIAccount.ERROR_AUTHENTICATION_FAILED], +- "1213" : ["accountLockedFailed", +- Ci.prplIAccount.ERROR_AUTHENTICATION_FAILED], +- "1218" : ["accountDeactivated", +- Ci.prplIAccount.ERROR_AUTHENTICATION_FAILED], +- "1235" : ["usernameNotExist", +- Ci.prplIAccount.ERROR_INVALID_USERNAME], +- "1236" : ["accountLockedGeneral", +- Ci.prplIAccount.ERROR_AUTHENTICATION_FAILED] +-}; +- +-// These are the status codes that buddies can send us. +-var kBuddyStatuses = { +- // Available. +- "0" : Ci.imIStatusInfo.STATUS_AVAILABLE, +- // Be right back. +- "1" : Ci.imIStatusInfo.STATUS_AWAY, +- // Busy. +- "2" : Ci.imIStatusInfo.STATUS_UNAVAILABLE, +- // Not at home. +- "3" : Ci.imIStatusInfo.STATUS_AWAY, +- // Not at desk. +- "4" : Ci.imIStatusInfo.STATUS_AWAY, +- // Not in office. +- "5" : Ci.imIStatusInfo.STATUS_AWAY, +- // On phone. +- "6" : Ci.imIStatusInfo.STATUS_AWAY, +- // On vacation. +- "7" : Ci.imIStatusInfo.STATUS_AWAY, +- // Out to lunch. +- "8" : Ci.imIStatusInfo.STATUS_AWAY, +- // Stepped out. +- "9" : Ci.imIStatusInfo.STATUS_AWAY, +- // Invisible. +- "12" : Ci.imIStatusInfo.STATUS_INVISIBLE, +- // Custom status. +- "99" : Ci.imIStatusInfo.STATUS_AWAY, +- // Idle. +- "999" : Ci.imIStatusInfo.STATUS_IDLE +-}; +- +-/* The purpose of the YahooSession object is to serve as a gateway between the +- * protocol plug-in and the Yahoo! Messenger servers. Anytime an object outside +- * of this file wishes to communicate with the servers, it should do it through +- * one of the methods provided by YahooSession. By centralizing such network +- * access, we can easily catch errors, and ensure that communication is handled +- * correctly. */ +-function YahooSession(aAccount) +-{ +- this._account = aAccount; +- this.binaryMode = true; +-} +-YahooSession.prototype = { +- __proto__: Socket, +- _account: null, +- _socket: null, +- _username: null, +- // This is the IPv4 address to the pager server which is the gateway into the +- // Yahoo! Messenger network. +- pagerAddress: null, +- // The session ID is obtained during the login process and is maintained +- // throughout the session. This helps the pager server identify the client. +- sessionId: null, +- // The T and Y cookies obtained by the YahooLoginHelper during login. +- tCookie: null, +- yCookie: null, +- +- // Public methods. +- login: function() { +- this._account.reportConnecting(); +- new YahooLoginHelper(this).login(this._account); +- }, +- +- sendPacket: function(aPacket) { +- this.sendBinaryData(aPacket.toArrayBuffer(), aPacket.toString()); +- }, +- +- addBuddyToServer: function(aBuddy) { +- let packet = new YahooPacket(kPacketType.AddBuddy, 0, this.sessionId); +- // We leave this invite message empty. Any message placed here will +- // annoyingly be sent to the invitee when they accept the invite. +- packet.addValue(14, ""); +- packet.addValue(65, aBuddy.tag.name); +- packet.addValue(97, "1"); // UTF-8 encoding. +- packet.addValue(1, this._account.cleanUsername); +- // The purpose of these two values are unknown. +- packet.addValue(302, "319"); +- packet.addValue(300, "319"); +- packet.addValue(7, aBuddy.userName); +- // The purpose of these three values are also unknown. +- packet.addValue(334, "0"); +- packet.addValue(301, "319"); +- packet.addValue(303, "319"); +- this.sendPacket(packet); +- }, +- +- removeBuddyFromServer: function(aBuddy) { +- let packet = new YahooPacket(kPacketType.RemoveBuddy, 0, this.sessionId); +- packet.addValue(1, this._account.cleanUsername); +- packet.addValue(7, aBuddy.userName); +- packet.addValue(65, aBuddy.tag.name); +- this.sendPacket(packet); +- }, +- +- setStatus: function(aStatus, aMessage) { +- let packet = new YahooPacket(kPacketType.StatusUpdate, 0, this.sessionId); +- +- // When a custom status message is used, key 10 is set to 99, and key 97 +- // is set to 1. Otherwise, key 10 is set to our current status code. +- if (aMessage && aMessage.length > 0) { +- packet.addValue(10, "99"); +- packet.addValue(97, "1"); +- } else { +- let statusCode; +- switch(aStatus) { +- // Available +- case Ci.imIStatusInfo.STATUS_AVAILABLE: +- case Ci.imIStatusInfo.STATUS_MOBILE: +- statusCode = "0"; +- break; +- // Away +- case Ci.imIStatusInfo.STATUS_AWAY: +- statusCode = "1"; +- break; +- // Busy +- case Ci.imIStatusInfo.STATUS_UNAVAILABLE: +- statusCode = "2"; +- break; +- // Invisible +- case Ci.imIStatusInfo.STATUS_INVISIBLE: +- statusCode = "12"; +- break; +- // Idle +- case Ci.imIStatusInfo.STATUS_IDLE: +- statusCode = "999"; +- break; +- } +- packet.addValue(10, statusCode); +- } +- +- // Key 19 is always set as the status messgae, even when the message is +- // empty. If key 10 is set to 99, the message is used. +- packet.addValue(19, aMessage); +- +- // Key 47 is always set to either 0, if we are available, or 1, if we are +- // not available. The value is used by the server if key 10 is set to 99. +- // Otherwise, the value of key 10 is used to determine our status. +- packet.addValue(47, (aStatus == Ci.imIStatusInfo.STATUS_AVAILABLE) ? +- "0" : "1"); +- this.sendPacket(packet); +- }, +- +- sendChatMessage: function(aName, aMessage) { +- let packet = new YahooPacket(kPacketType.Message, 0, this.sessionId); +- // XXX Key 0 is the user ID, and key 1 is the active ID. We need to find +- // the difference between these two. Alias maybe? +- packet.addValue(0, this._account.cleanUsername); +- packet.addValue(1, this._account.cleanUsername); +- packet.addValue(5, aName); +- packet.addValue(14, aMessage); +- this.sendPacket(packet); +- }, +- +- sendConferenceMessage: function(aRecipients, aRoom, aMessage) { +- let packet = new YahooPacket(kPacketType.ConfMessage, 0, this.sessionId); +- packet.addValue(1, this._account.cleanUsername); +- packet.addValues(53, aRecipients); +- packet.addValue(57, aRoom); +- packet.addValue(14, aMessage); +- packet.addValue(97, "1"); // Use UTF-8 encoding. +- this.sendPacket(packet); +- }, +- +- sendTypingStatus: function(aBuddyName, aIsTyping) { +- let packet = new YahooPacket(kPacketType.Notify, kPacketStatuses.Typing, +- this.sessionId); +- packet.addValue(1, this._account.cleanUsername); +- packet.addValue(5, aBuddyName); +- packet.addValue(13, aIsTyping ? "1" : "0"); +- packet.addValue(14, " "); // Key 14 contains a single space. +- packet.addValue(49, "TYPING"); +- this.sendPacket(packet); +- }, +- +- acceptConferenceInvite: function(aOwner, aRoom, aParticipants) { +- let packet = new YahooPacket(kPacketType.ConfLogon, 0, this.sessionId); +- packet.addValue(1, this._account.cleanUsername); +- packet.addValue(57, aRoom); +- packet.addValues(3, aParticipants); +- this.sendPacket(packet); +- }, +- +- createConference: function(aRoom) { +- let packet = new YahooPacket(kPacketType.ConfLogon, 0, this.sessionId); +- packet.addValue(1, this._account.cleanUsername); +- packet.addValue(3, this._account.cleanUsername); +- packet.addValue(57, aRoom); +- this.sendPacket(packet); +- }, +- +- inviteToConference: function(aInvitees, aRoom, aParticipants, aMessage) { +- let packet = new YahooPacket(kPacketType.ConfAddInvite, 0, this.sessionId); +- packet.addValue(1, this._account.cleanUsername); +- packet.addValues(51, aInvitees); +- packet.addValues(53, aParticipants); +- packet.addValue(57, aRoom); +- packet.addValue(58, aMessage); +- packet.addValue(13, "0"); +- this.sendPacket(packet); +- }, +- +- sendConferenceLogoff: function(aName, aParticipants, aRoom) { +- let packet = new YahooPacket(kPacketType.ConfLogoff, 0, this.sessionId); +- packet.addValue(1, aName); +- packet.addValues(3, aParticipants); +- packet.addValue(57, aRoom); +- this.sendPacket(packet); +- }, +- +- setProfileIcon: function(aFileName) { +- // If we have an empty filename, remove the icon from the server. +- if (!aFileName) { +- let packet = new YahooPacket(kPacketType.AvatarUpdate, 0, this.sessionId); +- packet.addValue(3, this._account.cleanUsername); +- packet.addValue(213, 0); +- this.sendPacket(packet); +- return; +- } +- // Try to get a handle to the icon file. +- let file = FileUtils.getFile("ProfD", [aFileName]); +- let type = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService) +- .getTypeFromFile(file); +- NetUtil.asyncFetch({ +- uri: NetUtil.newURI(file), +- contentPolicyType: Ci.nsIContentPolicy.TYPE_IMAGE, +- securityFlags: Ci.nsILoadInfo.SEC_NORMAL, +- loadUsingSystemPrincipal: true +- }, (aStream, aStatus) => { +- if (!Components.isSuccessCode(aStatus)) { +- throw "Could not access icon file."; +- return; +- } +- let image = imgTools.decodeImage(aStream, type); +- let uploader = new YahooProfileIconUploader(this._account, this, +- aFileName, image); +- uploader.uploadIcon(); +- }); +- }, +- +- requestBuddyIcon: function(aName) { +- let packet = new YahooPacket(kPacketType.Picture, 0, this.sessionId); +- packet.addValue(1, this._account.cleanUsername); +- packet.addValue(5, aName); // The name of the buddy. +- packet.addValue(13, "1"); // "1" means we wish to request an icon. +- this.sendPacket(packet); +- }, +- +- acceptBuddyRequest: function(aRequest) { +- let packet = new YahooPacket(kPacketType.BuddyAuth, 0, this.sessionId); +- packet.addValue(1, this._account.cleanUsername); +- packet.addValue(5, aRequest.userName); +- // Misc. Unknown flags. +- packet.addValue(13, 1); +- packet.addValue(334, 0); +- this.sendPacket(packet); +- +- // If someone wants to add us as a buddy, place them under the default +- // tag. Also, we make sure that the buddy doesn't already exist in the +- // list in case of a server acknowledgement. +- if (!this._account.hasBuddy(aRequest.userName)) +- this._account.addBuddy(Services.tags.defaultTag, aRequest.userName); +- }, +- +- denyBuddyRequest: function(aRequest) { +- let packet = new YahooPacket(kPacketType.BuddyReqReject, 0, this.sessionId); +- packet.addValue(1, this._account.cleanUsername); +- packet.addValue(7, aRequest.userName); +- packet.addValue(14, ""); +- this.sendPacket(packet); +- }, +- +- sendKeepAlive: function() { +- let packet = new YahooPacket(kPacketType.KeepAlive, 0, this.sessionId); +- packet.addValue(0, this._account.cleanUsername); +- this.sendBinaryData(packet.toArrayBuffer()); +- }, +- +- sendPing: function() { +- let packet = new YahooPacket(kPacketType.Ping, 0, this.sessionId); +- this.sendBinaryData(packet.toArrayBuffer()); +- }, +- +- // Callbacks. +- onLoginComplete: function() { +- this._account.reportConnected(); +- this._account.onLoginComplete(); +- }, +- +- onSessionError: function(aError, aMessage) { +- this._account.reportDisconnecting(aError, aMessage); +- if (!this.disconnected) +- this.disconnect(); +- this._account.reportDisconnected(); +- }, +- +- // Private methods. +- +- // Socket Event Callbacks. +- LOG: function(aString) { return this._account.LOG(aString); }, +- +- DEBUG: function(aString) { return this._account.DEBUG(aString); }, +- +- onConnection: function() { +- // We send an authentication request packet as soon as we connect to the +- // pager server. +- let packet = new YahooPacket(kPacketType.Auth, 0, 0); +- packet.addValue(1, this._account.cleanUsername); +- this.sendPacket(packet); +- }, +- +- onConnectionTimedOut: function() { +- this.onSessionError(Ci.prplIAccount.NETWORK_ERROR, ""); +- }, +- +- onConnectionReset: function() { +- this.onSessionError(Ci.prplIAccount.NETWORK_ERROR, ""); +- }, +- +- // Called when the other end has closed the connection. +- onConnectionClosed: function() { +- if (!this._account.connected) +- return; +- this._account.reportDisconnecting(Ci.prplIAccount.NO_ERROR, ""); +- this._account.reportDisconnected(); +- }, +- +- onBinaryDataReceived: function(aData) { +- let packets; +- let bytesHandled; +- try { +- [packets, bytesHandled] = YahooPacket.extractPackets(aData); +- } catch(e) { +- this._account.ERROR(e); +- this.onSessionError(Ci.prplIAccount.NETWORK_ERROR, ""); +- return 0; +- } +- +- for each (let packet in packets) { +- this._account.LOG("Received Packet:\n" + packet.toString()); +- if (YahooPacketHandler.hasOwnProperty(packet.service)) { +- try { +- YahooPacketHandler[packet.service].call(this._account, packet); +- } catch(e) { +- this._account.ERROR(e); +- } +- } else { +- this._account.WARN("No handler for Yahoo! packet " + +- packet.service.toString(16) + "."); +- } +- } +- return bytesHandled; +- } +-}; +- +-/* The purpose of YahooLoginHelper is to separate the complicated login logic +- * from the YahooSession object. Logging in on Yahoo!'s network is the most +- * complicated stage of a session due to the authentication system that is +- * employed. The login steps are listed below. +- * +- * 1) Get the address of a "pager" server. This pager will be our gateway to +- * the network. +- * +- * 2) Obtain the challenge string from the pager. This string is used to help +- * create the base64 response string needed for the final step. +- * +- * 3) Obtain a token from the login server via HTTP. +- * +- * 4) Obtain the login crumb, Y-Cookie, and T-Cookie from the login server via +- * HTTP. These will also be used in the final response packet to the pager. +- * +- * 5) Create the base64 response string from the MD5 hash of the crumb and +- * challenge string, and build a packet containing the username, password, +- * response string, version numbers, crumb, and cookies, sending it to the +- * pager for a final authenticatcation. +- * +- * If all goes well after the 5th step, the user is considered logged in. */ +-function YahooLoginHelper(aSession) +-{ +- this._session = aSession; +-} +-YahooLoginHelper.prototype = { +- // YahooSession object passed in constructor. +- _session: null, +- // YahooAccount object passed to login(). +- _account: null, +- // The username, stripped of any @yahoo.com or @yahoo.co.jp suffix. +- _username: null, +- // The authentication challenge string sent from the Yahoo!'s login server. +- _challengeString: null, +- // The authentication token sent from Yahoo!'s login server. +- _loginToken: null, +- // Crumb sent from Yahoo!'s login server, and used in the final authentication +- // request to the pager server. +- _crumb: null, +- +- // Public methods. +- login: function(aAccount) { +- this._account = aAccount; +- this._getPagerAddress(); +- }, +- +- // Private methods. +- _getPagerAddress: function() { +- let options = { +- onLoad: this._onPagerAddressResponse.bind(this), +- onError: this._onHttpError.bind(this) +- } +- httpRequest(this._account._protocol.pagerRequestUrl, options); +- }, +- +- _getChallengeString: function() { +- let port = this._account.getInt("port"); +- this._session.connect(this._session.pagerAddress, port); +- // We want to handle a challenge string when the server responds. +- this._session.onBinaryDataReceived = +- this._onChallengeStringResponse.bind(this); +- }, +- +- _getLoginToken: function() { +- // TODO - Simplify this using map and join. +- let url = this._account._protocol.loginTokenGetUrl; +- url += "?src=ymsgr&"; +- url += "login=" + percentEncode(this._account.cleanUsername) + "&"; +- url += "passwd=" + percentEncode(this._account.imAccount.password) + "&"; +- url += "chal=" + percentEncode(this._challengeString); +- +- let options = { +- onLoad: this._onLoginTokenResponse.bind(this), +- onError: this._onHttpError.bind(this) +- } +- httpRequest(url, options); +- }, +- +- _getCookies: function() { +- // TODO - Simplify this using map and join. +- let url = this._account._protocol.loginTokenLoginUrl; +- url += "?src=ymsgr&"; +- url += "token=" + this._loginToken; +- +- let options = { +- onLoad: this._onLoginCookiesResponse.bind(this), +- onError: this._onHttpError.bind(this) +- } +- httpRequest(url, options); +- }, +- +- _sendPagerAuthResponse: function() { +- let response = this._calculatePagerResponse(); +- let packet = new YahooPacket(kPacketType.AuthResponse, 0, +- this._session.sessionId); +- // Build the key/value pairs. +- packet.addValue(1, this._account.cleanUsername); +- packet.addValue(0, this._account.cleanUsername); +- packet.addValue(277, this._session.yCookie); +- packet.addValue(278, this._session.tCookie); +- packet.addValue(307, response); +- packet.addValue(244, this._account.protocol.buildId); +- packet.addValue(2, this._account.cleanUsername); +- packet.addValue(2, "1"); +- packet.addValue(98, "us"); +- this._session.sendPacket(packet); +- // We want to handle a final login confirmation packet when the server +- // responds. +- this._session.onBinaryDataReceived = this._onFinalLoginResponse.bind(this); +- }, +- +- _calculatePagerResponse: function() { +- let hasher = Cc["@mozilla.org/security/hash;1"] +- .createInstance(Ci.nsICryptoHash); +- hasher.init(hasher.MD5); +- +- let crypt = this._crumb + this._challengeString; +- let cryptData = StringToBytes(crypt); +- hasher.update(cryptData, cryptData.length); +- +- // The protocol requires replacing + with ., / with _, and = with - within +- // the base64 response string. +- return btoa(hasher.finish(false)).replace(/+/g, ".").replace(///g, "_") +- .replace(/=/g, "-"); +- }, +- +- _handleLoginError: function(aErrorCode) { +- let errorInfo = kLoginStatusErrors[aErrorCode]; +- let errorMessage; +- let error; +- +- // If we find information on the error code we received, we will use that +- // information. If the error wasn't found in our error table, just throw a +- // generic error with the code included. +- if (errorInfo) { +- errorMessage = _("login.error." + errorInfo[0]); +- error = errorInfo[1]; +- } else { +- errorMessage = _("login.error.unknown", aErrorCode); +- error = Ci.prplIAccount.ERROR_OTHER_ERROR; +- // We also throw a console error because we didn't expect +- // this error code. +- this._account.ERROR("Received unknown error from pager server. Code: " + +- aErrorCode); +- } +- this._session.onSessionError(error, errorMessage); +- }, +- +- _onHttpError: function(aError, aStatusText, aXHR) { +- this._session.onSessionError(Ci.prplIAccount.NETWORK_ERROR, +- _("network.error.http")); +- }, +- +- // HTTP Response Callbacks. +- _onPagerAddressResponse: function(aResponse, aXHR) { +- this._session.pagerAddress = +- aResponse.substring(aResponse.lastIndexOf("=") + 1); +- this._getChallengeString(); +- }, +- +- _onLoginTokenResponse: function(aResponse, aXHR) { +- let responseParams = aResponse.split("\r\n"); +- // Status code "0" means success. +- let statusCode = responseParams[0]; +- if (statusCode != "0") { +- this._handleLoginError(statusCode); +- return; +- } +- +- this._loginToken = responseParams[1].replace("ymsgr=", ""); +- this._getCookies(); +- }, +- +- _onLoginCookiesResponse: function(aResponse, aXHR) { +- let responseParams = aResponse.split("\r\n"); +- // Status code "0" means success. +- let statusCode = responseParams[0]; +- if (statusCode != "0") { +- this._handleLoginError(statusCode); +- return; +- } +- +- this._crumb = responseParams[1].replace("crumb=", ""); +- // Remove the "Y=" bit. +- this._session.yCookie = responseParams[2].substring(2); +- // Remove the "T=" bit. +- this._session.tCookie = responseParams[3].substring(2); +- this._sendPagerAuthResponse(); +- }, +- +- // TCP Response Callbacks. +- _onChallengeStringResponse: function(aData) { +- let packet = new YahooPacket(); +- packet.fromArrayBuffer(aData); +- // The value of the challenge string is associated with key 94. +- this._challengeString = packet.getValue(94); +- this._session.sessionId = packet.sessionId; +- this._getLoginToken(); +- }, +- +- _onFinalLoginResponse: function(aData) { +- this._session.onLoginComplete(); +- // We need to restore data handling to the YahooSession object since our +- // login steps are complete. +- this._session.onBinaryDataReceived = +- YahooSession.prototype.onBinaryDataReceived.bind(this._session); +- } +-}; +- +-/* The YahooPacket class represents a single Yahoo! Messenger data packet. +- * Using this class allows you to easily create packets, stuff them with +- * required data, and convert them to/from ArrayBuffer objects. */ +-function YahooPacket(aService, aStatus, aSessionId) +-{ +- this.service = aService; +- this.status = aStatus; +- this.sessionId = aSessionId; +- this.keyValuePairs = []; +-} +-YahooPacket.prototype = { +- service: null, +- status: null, +- sessionId: null, +- keyValuePairs: null, +- +- // Public methods. +- +- // Add a single key/value pair. +- addValue: function(aKey, aValue) { +- let pair = { +- key: aKey.toString(), // The server handles keys as ASCII number values. +- value: aValue +- }; +- +- this.keyValuePairs.push(pair); +- }, +- +- // Add multiple key/value pairs with the same key but different values +- // stored in an array. +- addValues: function(aKey, aValues) { +- for each (let value in aValues) +- this.addValue(aKey, value); +- }, +- +- // This method returns the first value found with the given key. +- getValue: function(aKey) { +- for (let i = 0; i < this.keyValuePairs.length; ++i) { +- let pair = this.keyValuePairs[i]; +- // The server handles keys as ASCII number values. +- if (pair.key == aKey.toString()) +- return pair.value; +- } +- +- // Throw an error if the key wasn't found. +- throw "Required key " + aKey + " wasn't found. Packet Service: " + +- this.service.toString(16); +- }, +- +- // This method returns all of the values found with the given key. In some +- // packets, one key is associated with multiple values. If that is the case, +- // use this method to retrieve all of them instead of just the first one. +- getValues: function(aKey) { +- let values = []; +- for (let i = 0; i < this.keyValuePairs.length; ++i) { +- let pair = this.keyValuePairs[i]; +- // The server handles keys as ASCII number values. +- if (pair.key == aKey.toString()) +- values.push(pair.value); +- } +- +- // Throw an error if no keys were found. +- if (values.length == 0) { +- throw "Required key " + aKey + " wasn't found. Packet Service: " + +- this.service.toString(16); +- } +- return values; +- }, +- +- hasKey: function(aKey) { +- for (let i = 0; i < this.keyValuePairs.length; ++i) { +- // The server handles keys as ASCII number values. +- if (this.keyValuePairs[i].key == aKey.toString()) +- return true; +- } +- return false; +- }, +- +- toArrayBuffer: function() { +- let dataString = ""; +- for (let i = 0; i < this.keyValuePairs.length; ++i) { +- let pair = this.keyValuePairs[i]; +- dataString += pair.key + kPacketDataDelimiter; +- dataString += pair.value + kPacketDataDelimiter; +- } +- +- let packetLength = dataString.length; +- let buffer = new ArrayBuffer(kPacketHeaderSize + packetLength); +- +- // Build header. +- let view = new DataView(buffer); +- let idBytes = StringToBytes(kPacketIdentifier); +- view.setUint8(0, idBytes[0]); +- view.setUint8(1, idBytes[1]); +- view.setUint8(2, idBytes[2]); +- view.setUint8(3, idBytes[3]); +- view.setUint16(4, kProtocolVersion); +- view.setUint16(6, 0); // Vendor ID +- view.setUint16(8, packetLength); +- view.setUint16(10, this.service); +- view.setUint32(12, this.status); +- view.setUint32(16, this.sessionId); +- +- // Copy in data. +- copyBytes(buffer, BytesToArrayBuffer(StringToBytes(dataString)), kPacketHeaderSize); +- +- return buffer; +- }, +- +- fromArrayBuffer: function(aBuffer) { +- let view = new DataView(aBuffer); +- this.length = view.getUint16(8) + kPacketHeaderSize; +- this.service = view.getUint16(10); +- this.status = view.getUint32(12); +- this.sessionId = view.getUint32(16); +- +- let dataString = ArrayBufferToString(aBuffer).substring(kPacketHeaderSize); +- let delimitedData = dataString.split(kPacketDataDelimiter); +- // Since the data should also end with a trailing delmiter, split() will +- // add an empty element at the end. We need to pop this element off. +- delimitedData.pop(); +- +- // If we don't have an even number of delimitedData elements, that means +- // we are either missing a key or a value. +- if (delimitedData.length % 2 != 0) { +- throw "Odd number of data elements. Either a key or value is missing. " +- "Num of elements: " + delimitedData.length; +- } +- +- for (let i = 0; i < delimitedData.length; i += 2) { +- let key = delimitedData[i]; +- let value = delimitedData[i + 1]; +- if (key && value) { +- let pair = { +- key: key, +- value: value +- }; +- this.keyValuePairs.push(pair); +- } +- } +- }, +- +- toString: function() { +- // First, add packet header information. +- let s = "Service: 0x" + this.service.toString(16) + "\n"; +- s += "Status: 0x" + this.status.toString(16) + "\n"; +- s += "Session ID: 0x" + this.sessionId.toString(16); +- // Now we add the packet data, if there is some. +- if (this.keyValuePairs.length) { +- // Add two preceding newlines for space to make reading easier. +- s += "\n\nPacket Key-Value Data:\n"; +- for each (let pair in this.keyValuePairs) +- s += pair.key + ":\t" + pair.value + "\n"; +- } +- return s; +- } +-}; +-YahooPacket.extractPackets = function(aData, aOnNetworkError) { +- let packets = []; +- let bytesHandled = 0; +- +- while (aData.byteLength >= kPacketHeaderSize) { +- if (ArrayBufferToString(aData.slice(0, kPacketIdentifier.length)) != +- kPacketIdentifier) { +- throw "Malformed packet received. Packet content: " + +- ArrayBufferToHexString(aData); +- } +- +- let packetView = new DataView(aData); +- let packetLength = packetView.getUint16(8) + kPacketHeaderSize; +- // Don't process half packets. +- if (packetLength > aData.byteLength) +- break; +- let packet = new YahooPacket(); +- packet.fromArrayBuffer(aData.slice(0, packetLength)); +- packets.push(packet); +- bytesHandled += packetLength; +- aData = aData.slice(packetLength); +- } +- return [packets, bytesHandled]; +-} +- +-/* In YahooPacketHandler, each handler function is assosiated with a packet +- * service number. You can use the kPacketType enumeration to understand +- * what kind of packet each number is linked to. +- * +- * Keep in mind too that "this" in each function will be bound to a +- * YahooAccount object, since they are all invoked using call(). */ +-var YahooPacketHandler = { +- // Buddy logoff. +- 0x02: function(aPacket) { +- let name = aPacket.getValue(7); +- this.setBuddyStatus(name, Ci.imIStatusInfo.STATUS_OFFLINE, ""); +- }, +- +- // Incoming chat message. +- 0x06: function(aPacket) { +- let from = aPacket.getValue(4); +- let to = aPacket.getValue(5); +- let message = aPacket.getValue(14); +- this.receiveMessage(from, message); +- +- // The official Yahoo! Messenger desktop client requires message ACKs to be +- // sent back to the server. The web client doesn't require this. A good +- // indication of when an ACK is required is when key 429 is sent, which +- // contains the ID of the message. When a message is sent from the official +- // desktop client, and no ACK is sent back, the message is resent seconds +- // later. +- if (aPacket.hasKey(429)) { +- let messageId = aPacket.getValue(429); +- let packet = new YahooPacket(kPacketType.MessageAck, 0, aPacket.sessionId); +- // Some keys have an unknown purpose, so we set a constant value. +- packet.addValue(1, to); +- packet.addValue(5, from); +- packet.addValue(302, "430"); +- packet.addValue(430, messageId); +- packet.addValue(303, 430); +- packet.addValue(450, 0); +- this._session.sendPacket(packet); +- } +- }, +- +- // New mail notification. +- // TODO: Implement this handler when mail notifications are handled in the +- // base code. +- 0x0b: function(aPacket) {}, +- +- // Server ping. +- // TODO: Add support for ping replies. +- 0x12: function(aPacket) {}, +- +- // Conference invitation. +- 0x18: function(aPacket) { +- let owner = aPacket.getValue(50); +- let roomName = aPacket.getValue(57); +- let participants = aPacket.getValues(53); +- // The owner is also a participant. +- participants.push(owner); +- let message = aPacket.getValue(58); +- this.receiveConferenceInvite(owner, roomName, participants, message); +- }, +- +- // Conference logon. +- 0x19: function(aPacket) { +- let userName = aPacket.getValue(53); +- let room = aPacket.getValue(57); +- this.receiveConferenceLogon(room, userName); +- }, +- +- // Conference logoff +- 0x1b: function(aPacket) { +- let userName = aPacket.getValue(56); +- let roomName = aPacket.getValue(57); +- this.receiveConferenceLogoff(roomName, userName); +- }, +- +- // Conference additional invitation. NOTE: Since this packet has the same +- // structure as the normal conference invite (packet 0x18), we simply +- // reuse that handler. +- 0x1c: function(aPacket) { return YahooPacketHandler[0x18].call(this, aPacket); }, +- +- // Conference message. +- 0x1d: function(aPacket) { +- let from = aPacket.getValue(3); +- let room = aPacket.getValue(57); +- let message = aPacket.getValue(14); +- this.receiveConferenceMessage(from, room, message); +- }, +- +- // Typing notification. +- 0x4b: function(aPacket) { +- let name = aPacket.getValue(4); +- let isTyping = (aPacket.getValue(13) == "1"); +- this.receiveTypingNotification(name, isTyping); +- }, +- +- // Legacy Yahoo! buddy list. Packet 0xf1 has replaced this. +- 0x55: function(aPacket) {}, +- +- // Authentication acknowledgement. We can ignore this since we are known +- // to be authenticated if we are receiving other packets anyway. +- 0x57: function(aPacket) {}, +- +- // AddBuddy ack packets can be ignored. They do not depend on whether or not +- // the buddy accepted the invite. +- 0x83: function(aPacket) {}, +- +- // RemoveBuddy ack packets let us know when we should actually remove the +- // buddy from the list, keeping us in sync with the server. +- 0x84: function(aPacket) { +- let buddy = this.getBuddy(aPacket.getValue(7)); +- // The buddy is off the server, so remove it locally. +- this.removeBuddy(buddy, false); +- }, +- +- // Picture upload. +- 0xc2: function(aPacket) { +- let onlineBuddies = this.getOnlineBuddies(); +- // Send a notification to each online buddy that your icon has changed. +- // Those offline will automatically pick up the change when they log in. +- for each (let buddy in onlineBuddies) { +- let packet = new YahooPacket(kPacketType.AvatarUpdate, 0, +- this._session.sessionId); +- packet.addValue(3, buddy.userName); +- packet.addValue(213, 2); // A value of 2 means we are using an icon. +- this._session.sendPacket(packet); +- } +- }, +- +- // Buddy icon checksum. +- // TODO - Make use of the icon checksum to allow icon caching. +- 0xbd: function(aPacket) { +- // Extract the checksum from the URL parameter chksum. +- let buddyName = aPacket.getValue(4); +- let url = aPacket.getValue(20); +- let parameter = "chksum="; +- // The "chksum" parameter is the only parameter in the URL. +- let checksum = url.substring(url.indexOf(parameter) + parameter.length); +- +- let buddy = this.getBuddy(buddyName); +- // We only download the new icon if no older checksum exists, or if the +- // older checksum differs, indicating an updated icon. +- if (buddy && buddy.iconChecksum !== checksum) { +- buddy.buddyIconFilename = url; +- buddy.iconChecksum = checksum; +- } +- }, +- +- // Buddy icon request reply. This can be handled in the same way as a buddy +- // icon checksum packet, so we simply reuse the handler. +- 0xbe: function (aPacket) { return YahooPacketHandler[0xbd].call(this, aPacket); }, +- +- // Buddy status update. +- 0xc6: function (aPacket) { +- let name = aPacket.getValue(7); +- // If the user is mobile, use the mobile status. +- let status = aPacket.hasKey(60) ? Ci.imIStatusInfo.STATUS_MOBILE : +- kBuddyStatuses[aPacket.getValue(10)]; +- +- let message = aPacket.hasKey(19) ? aPacket.getValue(19) : ""; +- this.setBuddyStatus(name, status, message); +- }, +- +- // Buddy avatar (icon) update. +- 0xc7: function(aPacket) { +- // Strangely, in some non-official clients, when someone updates their +- // profile icon we are sent two avatar update packets: one with a default +- // status containing little information, and another with a Server Ack +- // status containing the info we need. So we only accept packets with a +- // Server Ack status to prevent errors. +- if (aPacket.status != kPacketStatuses.ServerAck) +- return; +- // Key 4 contains the name of the buddy who updated their icon. +- this._session.requestBuddyIcon(aPacket.getValue(4)); +- }, +- +- // Buddy authorization request. +- 0xd6: function(aPacket) { +- // Whenever we authorize someone to be our buddy, the server will send an +- // acknowledgement packet. We ignore the ack to prevent the auth request +- // from showing again. +- if (aPacket.status == kPacketStatuses.ServerAck) +- return; +- +- let session = this._session; +- let userName = aPacket.getValue(4); +- this.addBuddyRequest(userName, session.acceptBuddyRequest.bind(session), +- session.denyBuddyRequest.bind(session)); +- }, +- +- // XXX: What does this packet do? +- 0xef: function(aPacket) {}, +- +- // Initial user status. +- 0xf0: function (aPacket) { +- // Return early if we find no buddy names. +- if (!aPacket.hasKey(7)) +- return; +- +- // The key/value pairs are in order as sent by the server. So we must +- // iterate though them to find out information about each buddy. Each +- // buddy section starts with key 7. +- let currentBuddy; +- for (let i = 0; i < aPacket.keyValuePairs.length; ++i) { +- let {key: key, value: value} = aPacket.keyValuePairs[i]; +- +- if (key == 7) { // Buddy name. +- currentBuddyName = value; +- this._session.requestBuddyIcon(currentBuddyName); +- } else if (key == 10) // Buddy status. +- this.setBuddyStatus(currentBuddyName, kBuddyStatuses[value]); +- else if (key == 19) // Buddy status message. +- this.setBuddyStatus(currentBuddyName, undefined, value); +- else if (key == 60) // Mobile status. +- this.setBuddyStatus(currentBuddyName, Ci.imIStatus.STATUS_MOBILE); +- } +- }, +- +- // Friends and groups list. +- 0xf1: function(aPacket) { +- let tagName = ""; +- for each (let pair in aPacket.keyValuePairs) { +- if (pair.key == "65") +- tagName = pair.value; +- else if (pair.key == "7") { +- let buddyName = pair.value; +- this.addBuddyFromServer(Services.tags.createTag(tagName), buddyName); +- } +- } +- } +-}; +- +-/* The YahooProfileIconUploader class is specifically designed to set a profile +- * image on a Yahoo! Messenger account. The reason this functionality is split +- * into a separate class is because of the complexity of the operation. Because +- * of special protocol requirements, it is easier to use raw TCP communication +- * instead of the httpRequest() method. */ +-function YahooProfileIconUploader(aAccount, aSession, aFileName, aImage) +-{ +- this._account = aAccount; +- this._session = aSession; +- this._fileName = aFileName; +- this._image = aImage; +-} +-YahooProfileIconUploader.prototype = { +- __proto__: Socket, +- _account: null, +- _session: null, +- _fileName: null, +- _image: null, +- _host: null, +- _port: null, +- +- uploadIcon: function() { +- // Connect to the file transfer server, and the onConnection callback +- // will do the rest. +- this.connect(kFileTransferHost, kFileTransferPort); +- }, +- +- // Socket callbacks. +- onConnection: function() { +- // Scale the image down, and make it a PNG. Icon widths are constant, but +- // their height varies depending on the aspect ratio of the original image. +- let aspectRatio = this._image.width / this._image.height; +- let scaledHeight = kProfileIconWidth / aspectRatio; +- let scaledImage = imgTools.encodeScaledImage(this._image, "image/png", +- kProfileIconWidth, +- scaledHeight); +- let imageData = NetUtil.readInputStreamToString(scaledImage, +- scaledImage.available()); +- +- // Build the Yahoo packet. +- let packet = new YahooPacket(kPacketType.Picture, 0, this.sessionId); +- packet.addValue(1, this._account.cleanUsername); +- // TODO - Look into how expiration time works for profile icons, and its +- // purpose. We aren't sure if this refers to seconds, days, years, etc. +- packet.addValue(38, "604800"); // Expiration time. +- packet.addValue(0, this._account.cleanUsername); +- packet.addValue(28, imageData.length); // Picture size in bytes. +- packet.addValue(27, this._fileName); // Picture filename. +- packet.addValue(14, ""); // Null string. +- let packetBuffer = packet.toArrayBuffer(); +- +- // Build the request header. +- let headers = [ +- ["User-Agent", "Mozilla/5.0"], +- ["Cookie", "T=" + this._session.tCookie + "; Y=" + this._session.yCookie], +- ["Host", kFileTransferHost + ":" + kFileTransferPort], +- ["Content-Length", packetBuffer.byteLength + 4 + imageData.length], +- ["Cache-Control", "no-cache"], +- ]; +- let headerString = "POST /notifyft HTTP/1.1\r\n"; +- headers.forEach(function(header) { +- headerString += header[0] + ": " + header[1] + "\r\n"; +- }); +- +- // The POST request uses a special delimeter between the end of the included +- // Yahoo binary packet, and the image data. +- let requestPacketEnd = "29" + kPacketDataDelimiter; +- // Build the complete POST request data. +- let requestData = headerString + "\r\n" + +- ArrayBufferToString(packetBuffer) + requestPacketEnd + +- imageData; +- this.sendData(requestData); +- } +-}; +diff --git a/chat/protocols/yahoo/yahoo.js b/chat/protocols/yahoo/yahoo.js +index 8beadb504..86a258969 100644 +--- a/chat/protocols/yahoo/yahoo.js ++++ b/chat/protocols/yahoo/yahoo.js +@@ -2,575 +2,39 @@ + * 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/. */ + +-var {classes: Cc, interfaces: Ci, utils: Cu} = Components; ++var {interfaces: Ci, utils: Cu} = Components; + +-Cu.import("resource:///modules/imServices.jsm"); + Cu.import("resource:///modules/imXPCOMUtils.jsm"); + Cu.import("resource:///modules/jsProtoHelper.jsm"); +-Cu.import("resource:///modules/yahoo-session.jsm"); + + XPCOMUtils.defineLazyGetter(this, "_", () => + l10nHelper("chrome://chat/locale/yahoo.properties") + ); + +-// These timeouts are in milliseconds. +-var kKeepAliveTimeout = 60 * 1000; // One minute. +-var kPingTimeout = 3600 * 1000; // One hour. +- +-function YahooConversation(aAccount, aName) +-{ +- this._buddyUserName = aName; +- this._account = aAccount; +- this.buddy = aAccount.getBuddy(aName); +- this._init(aAccount); +-} +-YahooConversation.prototype = { +- __proto__: GenericConvIMPrototype, +- _account: null, +- _buddyUserName: null, +- _typingTimer: null, +- +- close: function() { +- this._account.deleteConversation(this._buddyUserName); +- GenericConvChatPrototype.close.call(this); +- }, +- +- sendMsg: function (aMsg) { +- // Deliver the message, then write it to the window. +- this._account._session.sendChatMessage(this._buddyUserName, +- this._account.encodeMessage(aMsg)); +- this.finishedComposing(); +- this.writeMessage(this._account.cleanUsername, aMsg, +- {outgoing: true, _alias: this._account.imAccount.alias}); +- }, +- +- sendTyping: function(aString) { +- if (aString.length) { +- if (!this._typingTimer) +- this._account._session.sendTypingStatus(this._buddyUserName, true); +- this._refreshTypingTimer(); +- } +- return Ci.prplIConversation.NO_TYPING_LIMIT; +- }, +- +- finishedComposing: function() { +- this._account._session.sendTypingStatus(this._buddyUserName, false); +- this._cancelTypingTimer(); +- }, +- +- _refreshTypingTimer: function() { +- this._cancelTypingTimer(); +- this._typingTimer = setTimeout(this.finishedComposing.bind(this), 10000); +- }, +- +- _cancelTypingTimer: function() { +- if (!this._typingTimer) +- return; +- clearTimeout(this._typingTimer); +- delete this._typingTimer +- this._typingTimer = null; +- }, +- +- get name() { return this._buddyUserName; } +-}; +- +-function YahooConference(aAccount, aRoom, aOwner) +-{ +- this._account = aAccount; +- this._roomName = aRoom; +- this._owner = aOwner; +- this._init(aAccount, aRoom, aAccount.cleanUsername); +-} +-YahooConference.prototype = { +- __proto__: GenericConvChatPrototype, +- _account: null, +- _roomName: null, +- _owner: null, +- +- close: function() { +- this.reportLogoff(); +- this._account.deleteConference(this._roomName); +- GenericConvChatPrototype.close.call(this); +- }, +- +- reportLogoff: function() { +- if (this.left) +- return; +- this._account._session.sendConferenceLogoff(this._account.cleanUsername, +- this.getParticipantNames(), +- this._roomName); +- this.left = true; +- }, +- +- sendMsg: function(aMsg) { +- this._account._session.sendConferenceMessage(this.getParticipantNames(), +- this._roomName, +- this._account.encodeMessage(aMsg)); +- }, +- +- addParticipant: function(aName) { +- // In case we receive multiple conference logon packets, prevent adding +- // duplicate buddies. +- if (this._participants.get(aName)) +- return; +- let buddy = new YahooConferenceBuddy(aName, this); +- this._participants.set(aName, buddy); +- this.notifyObservers(new nsSimpleEnumerator([buddy]), "chat-buddy-add"); +- this.writeMessage(this._roomName, +- _("system.message.conferenceLogon", aName), +- {system: true}); +- }, +- +- getParticipantNames: function() { return [for (p of this._participants.values()) p.name]; } +-}; +- +-function YahooConferenceBuddy(aName, aConference) +-{ +- this._name = aName; +- this._conference = aConference; +-} +-YahooConferenceBuddy.prototype = { +- __proto__: GenericConvChatBuddyPrototype, +- _conference: null, +- +- get founder() { return this._conference._owner == this._name; } +-}; +- +-function YahooAccountBuddy(aAccount, aBuddy, aTag, aUserName) +-{ +- this._init(aAccount, aBuddy, aTag, aUserName); +-} +-YahooAccountBuddy.prototype = { +- __proto__: GenericAccountBuddyPrototype, +- iconChecksum: null, +- +- // This removes the buddy locally, and from the Yahoo! servers. +- remove: function() { return this._account.removeBuddy(this, true); }, +- // This removes the buddy locally, but keeps him on the servers. +- removeLocal: function() { return this._account.removeBuddy(this, false); }, +- createConversation: function() { return this._account.createConversation(this.userName); } +-} +- + function YahooAccount(aProtoInstance, aImAccount) + { + this._init(aProtoInstance, aImAccount); +- this._buddies = new Map(); +- this._conversations = new Map(); +- this._conferences = new Map(); +- this._protocol = aProtoInstance; +- this._converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"] +- .createInstance(Ci.nsIScriptableUnicodeConverter); +- this._converter.charset = this.getString("local_charset") || "UTF-8"; +- +- // The username stripped of any @yahoo.* domain. +- this.cleanUsername = this.name.replace(/@yahoo..+$/, ""); + } + YahooAccount.prototype = { + __proto__: GenericAccountPrototype, +- // YahooSession object passed in constructor. +- _session: null, +- // A Map holding the list of buddies associated with their usernames. +- _buddies: null, +- // A Map holding the list of open buddy conversations associated with the +- // username of the buddy. +- _conversations: null, +- // A Map holding the list of open conference rooms associated with the room +- // name. +- _conferences: null, +- // YahooProtocol object passed in the constructor. +- _protocol: null, +- // An nsIScriptableUnicodeConverter used to convert incoming/outgoing chat +- // messages to the correct charset. +- _converter: null, +- // This is simply incremented by one everytime a new conference room is +- // created. It is appened to the end of the room name when a new room is +- // created, ensuring name uniqueness. +- _roomsCreated: 0, +- // The username stripped of any @yahoo.* domain. +- cleanUsername: null, +- // The timers used to send keepalive and ping packets to the server to ensrue +- // the server that the user is still connected. +- _keepAliveTimer: null, +- _pingTimer: null, + + connect: function() { +- this._session = new YahooSession(this); +- this._session.login(this.imAccount.name, this.imAccount.password); +- }, +- +- disconnect: function(aSilent) { +- // Log out of all of the conferences the user is in. +- for (let conf of this._conferences) +- conf[1].reportLogoff(); +- +- if (this.connected) { +- this.reportDisconnecting(Ci.prplIAccount.NO_ERROR, ""); +- if (this._session.isConnected) +- this._session.disconnect(); +- this.reportDisconnected(); +- } +- // buddy[1] is the actual object. +- for (let buddy of this._buddies) +- buddy[1].setStatus(Ci.imIStatusInfo.STATUS_UNKNOWN, ""); +- +- // Clear and delete the timers to avoid memory leaks. +- if (this._keepAliveTimer) { +- this._keepAliveTimer.cancel(); +- delete this._keepAliveTimer; +- } +- +- if (this._pingTimer) { +- this._pingTimer.cancel(); +- delete this._pingTimer; +- } +- }, +- +- observe: function(aSubject, aTopic, aData) { +- if (aTopic == "status-changed") +- this._session.setStatus(aSubject.statusType, aData); +- else if (aTopic == "user-icon-changed") +- this._session.setProfileIcon(aData); +- }, +- +- remove: function() { +- for each(let conv in this._conversations) +- conv.close(); +- delete this._conversations; +- for (let buddy of this._buddies) +- buddy[1].removeLocal(); // buddy[1] is the actual object. +- }, +- +- unInit: function() { +- this.disconnect(true); +- delete this.imAccount; +- }, +- +- createConversation: function(aName) { +- let conv = new YahooConversation(this, aName); +- this._conversations.set(aName, conv); +- return conv; +- }, +- +- deleteConversation: function(aName) { +- if (this._conversations.has(aName)) +- this._conversations.delete(aName); +- }, +- +- receiveConferenceInvite: function(aOwner, aRoom, aParticipants, aMessage) { +- // Do nothing if we wish to ignore invites. +- if (!Services.prefs.getIntPref("messenger.conversations.autoAcceptChatInvitations") || +- this.getBool("ignore_invites")) +- return; +- +- let conf = new YahooConference(this, aRoom, aOwner); +- this._conferences.set(aRoom, conf); +- +- for each (let participant in aParticipants) +- conf.addParticipant(participant); +- +- // Add ourselves to the conference room as well. +- conf.addParticipant(this.imAccount.name); +- +- this._session.acceptConferenceInvite(aOwner, aRoom, +- conf.getParticipantNames()); +- }, +- +- receiveConferenceLogon: function(aRoom, aUsername) { +- if (!this._conferences.has(aRoom)) +- return; +- let conf = this._conferences.get(aRoom); +- conf.addParticipant(aUsername); +- }, +- +- receiveConferenceLogoff: function(aRoom, aUsername) { +- if (!this._conferences.has(aRoom)) +- return; +- let conf = this._conferences.get(aRoom); +- conf.removeParticipant(aUsername); +- conf.writeMessage(this._roomName, +- _("system.message.conferenceLogoff", aName), +- {system: true}); +- }, +- +- deleteConference: function(aName) { +- if (this._conferences.has(aName)) +- this._conferences.delete(aName); +- }, +- +- // Called when the user adds or authorizes a new contact. +- addBuddy: function(aTag, aName) { +- let buddy = new YahooAccountBuddy(this, null, aTag, aName); +- this._buddies.set(buddy.userName, buddy); +- this._session.addBuddyToServer(buddy); +- Services.contacts.accountBuddyAdded(buddy); +- }, +- +- hasBuddy: function(aName) { +- return this._buddies.has(aName); +- }, +- +- // Called for each buddy that is sent in a list packet from Yahoo! on login. +- addBuddyFromServer: function(aTag, aName) { +- let buddy; +- if (this._buddies.has(aName)) +- buddy = this._buddies.get(aName); +- else { +- buddy = new YahooAccountBuddy(this, null, aTag, aName); +- Services.contacts.accountBuddyAdded(buddy); +- this._buddies.set(aName, buddy); +- } +- +- // Set all new buddies as offline because a following status packet will +- // tell their status if they are online. +- buddy.setStatus(Ci.imIStatusInfo.STATUS_OFFLINE, ""); +- +- // Request the buddy's picture. +- this._session.requestBuddyIcon(aName); +- }, +- +- // Called when a user removes a contact from within Instantbird. +- removeBuddy: function(aBuddy, aRemoveFromServer) { +- if (aRemoveFromServer) { +- // We will remove the buddy locally when we get a server ack packet. +- this._session.removeBuddyFromServer(aBuddy); +- return; +- } +- +- this._buddies.delete(aBuddy.userName); +- Services.contacts.accountBuddyRemoved(aBuddy); +- }, +- +- loadBuddy: function(aBuddy, aTag) { +- let buddy = new YahooAccountBuddy(this, aBuddy, aTag); +- this._buddies.set(buddy.userName, buddy); +- +- return buddy; +- }, +- +- // Both the status and message can be defined, or only one can be defined. +- // When defining just the message, set aStatus to undefined. +- setBuddyStatus: function(aName, aStatus, aMessage) { +- if (!this._buddies.has(aName)) +- return; +- let buddy = this._buddies.get(aName); +- // If the message is set as undefined, use the existing message. +- if (aMessage === undefined) +- aMessage = buddy.statusText; +- // If the status is undefined, use the existing status. +- if (aStatus === undefined) +- aStatus = buddy.statusType; +- buddy.setStatus(aStatus, aMessage); +- }, +- +- getBuddy: function(aName) { +- if (this._buddies.has(aName)) +- return this._buddies.get(aName); +- return null; +- }, +- +- getOnlineBuddies: function() { +- let onlineBuddies = []; +- for (let buddy of this._buddies) { +- if (buddy[1].statusType != Ci.imIStatusInfo.STATUS_OFFLINE) +- onlineBuddies.push(buddy[1]); +- } +- return onlineBuddies; +- }, +- +- receiveMessage: function(aName, aMessage) { +- let conv; +- // Check if we have an existing converstaion open with this user. If not, +- // create one and add it to the list. +- if (!this._conversations.has(aName)) +- conv = this.createConversation(aName); +- else +- conv = this._conversations.get(aName); +- +- // Certain Yahoo clients, such as the official web client, sends formatted +- // messages, but the size value is the actual pt size, not the 1 - 7 size +- // expected from the HTML <font> tag. We replace it with the correct size. +- let message = this.decodeMessage(aMessage) +- .replace(/(<font[^>]+)size="(\d+)"/g, this._fixFontSize); +- +- conv.writeMessage(aName, message, {incoming: true}); +- conv.updateTyping(Ci.prplIConvIM.NOT_TYPING, conv.name); +- }, +- +- receiveConferenceMessage: function(aName, aRoom, aMessage) { +- if (!this._conferences.has(aRoom)) +- return; +- +- this._conferences.get(aRoom).writeMessage(aName, +- this.decodeMessage(aMessage), +- {incoming: true}); +- }, +- +- receiveTypingNotification: function(aName, aIsTyping) { +- if (!this._conversations.has(aName)) +- return; +- +- let conv = this._conversations.get(aName); +- if (aIsTyping) +- conv.updateTyping(Ci.prplIConvIM.TYPING, conv.name); +- else +- conv.updateTyping(Ci.prplIConvIM.NOT_TYPING, conv.name); +- }, +- +- encodeMessage: function(aMessage) { +- // Try to perform a convertion from JavaScript UTF-16 into the charset +- // specified in the options. If the conversion fails, just leave +- // the message as it is. +- let encodedMsg; +- try { +- encodedMsg = this._converter.ConvertFromUnicode(aMessage); +- } catch (e) { +- encodedMsg = aMessage; +- this.WARN("Could not encode UTF-16 message into " + +- this._converter.charset + ". Message: " + aMessage); +- } +- return encodedMsg; +- }, +- +- decodeMessage: function(aMessage) { +- // Try to perform a convertion from the charset specified in the options +- // to JavaScript UTF-16. If the conversion fails, just leave the message +- // as it is. +- let decodedMsg; +- try { +- decodedMsg = this._converter.ConvertToUnicode(aMessage); +- } catch (e) { +- decodedMsg = aMessage; +- this.WARN("Could not decode " + this._converter.charset + +- " message into UTF-16. Message: " + aMessage); +- } +- return decodedMsg; +- }, +- +- get canJoinChat() { return true; }, +- chatRoomFields: {}, +- joinChat: function(aComponents) { +- // Use _roomsCreated to append a unique number to the room name. +- let roomName = this.cleanUsername + "-" + ++this._roomsCreated; +- let conf = new YahooConference(this, roomName, this.cleanUsername); +- this._conferences.set(roomName, conf); +- this._session.createConference(roomName); +- }, +- +- // Callbacks. +- onLoginComplete: function() { +- // Now that we are connected, get ready to start to sending pings and +- // keepalive packets. +- this._keepAliveTimer = Cc["@mozilla.org/timer;1"] +- .createInstance(Ci.nsITimer); +- this._pingTimer = Cc["@mozilla.org/timer;1"] +- .createInstance(Ci.nsITimer); +- +- // We use slack timers since we don't need millisecond precision when +- // sending the keepalive and ping packets. +- let s = this._session; +- this._keepAliveTimer +- .initWithCallback(s.sendKeepAlive.bind(s), kKeepAliveTimeout, +- this._keepAliveTimer.TYPE_REPEATING_SLACK); +- +- this._pingTimer +- .initWithCallback(s.sendPing.bind(s), kPingTimeout, +- this._pingTimer.TYPE_REPEATING_SLACK); +- +- }, +- +- // Private methods. +- +- // This method is used to fix font sizes given by formatted messages. This +- // method is designed to be used as a method for a string replace() call. +- _fixFontSize: function(aMatch, aTagAttributes, aFontSize, aOffset, aString) { +- // Approximate the font size. +- let newSize; +- if (aFontSize <= 8) +- newSize = "1"; +- else if (aFontSize <= 10) +- newSize = "2"; +- else if (aFontSize <= 12) +- newSize = "3"; +- else if (aFontSize <= 14) +- newSize = "4"; +- else if (aFontSize <= 20) +- newSize = "5"; +- else if (aFontSize <= 30) +- newSize = "6"; +- else if (aFontSize <= 40) +- newSize = "7"; +- else // If we get some gigantic size, just default to the standard 3 size. +- newSize = "3"; +- +- let sizeAttribute = "size="" + newSize + """; +- // We keep any preceding attributes, but replace the size attribute. +- return aTagAttributes + sizeAttribute; ++ this.WARN("The legacy versions of Yahoo Messenger was disabled on August " + ++ "5, 2016. It is currently not possible to connect to Yahoo " + ++ "Messenger. See bug 1316000"); ++ this.reportDisconnecting(Ci.prplIAccount.ERROR_OTHER_ERROR, ++ _("yahoo.disabled")); ++ this.reportDisconnected(); + } + }; + +-function YahooProtocol() { +- this.registerCommands(); +-} ++function YahooProtocol() {} + YahooProtocol.prototype = { + __proto__: GenericProtocolPrototype, +- // Protocol specific connection parameters. +- pagerRequestUrl: "http://scsa.msg.yahoo.com/capacity", +- loginTokenGetUrl: "https://login.yahoo.com/config/pwtoken_get", +- loginTokenLoginUrl: "https://login.yahoo.com/config/pwtoken_login", +- buildId: "4194239", + + get id() { return "prpl-yahoo"; }, + get name() { return "Yahoo"; }, + get iconBaseURI() { return "chrome://prpl-yahoo/skin/"; }, +- options: { +- port: {get label() { return _("options.pagerPort"); }, default: 5050}, +- local_charset: {get label() { return _("options.chatEncoding"); }, default: "UTF-8"}, +- ignore_invites: {get label() { return _("options.ignoreInvites"); }, default: false} +- }, +- commands: [ +- { +- name: "invite", +- get helpString() { return _("command.help.invite2", "invite"); }, +- usageContext: Ci.imICommand.CMD_CONTEXT_ALL, +- run: function(aMsg, aConv) { +- if (aMsg.trim().length == 0) +- return false; +- +- let splitPosition = aMsg.indexOf(" "); // Split at first space. +- let invitees; +- let message; +- +- // If we have an invite message. +- if (splitPosition > 0) { +- invitees = aMsg.substring(0, splitPosition).split(","); +- message = aMsg.substring(splitPosition); +- } else { +- invitees = aMsg.split(","); +- message = _("conference.invite.message"); // Use default message. +- } +- +- let conf = aConv.wrappedJSObject; +- conf._account._session.inviteToConference(invitees, conf._roomName, +- conf.getParticipantNames(), +- message); +- conf.writeMessage(conf._roomName, +- _("command.feedback.invite", invitees.join(", ")), +- {system: true, noLog: true}); +- conf._account.LOG("Sending conference invite to " + invitees); +- return true; +- }, +- }, +- +- { +- name: "conference", +- get helpString() { return _("command.help.conference", "conference"); }, +- usageContext: Ci.imICommand.CMD_CONTEXT_CHAT, +- run: function(aMsg, aConv) { +- aConv.account.joinChat(null); +- return true; +- } +- } +- ], + getAccount: function(aImAccount) { return new YahooAccount(this, aImAccount); }, + classID: Components.ID("{50ea817e-5d79-4657-91ae-aa0a52bdb98c}") + }; +diff --git a/im/content/conversation.xml b/im/content/conversation.xml +index 6f00c8d39..c93dab00f 100644 +--- a/im/content/conversation.xml ++++ b/im/content/conversation.xml +@@ -342,8 +342,7 @@ + msg = "<font face="" + style.fontFamily + "">" + msg + "</font>"; + // MSN doesn't support font size info in messages... + } +- else if (proto == "prpl-aim" || proto == "prpl-icq" || +- proto == "prpl-yahoo" || proto == "prpl-yahoojp") { ++ else if (proto == "prpl-aim" || proto == "prpl-icq") { + let styleAttributes = "" + if ("color" in style) + styleAttributes += " color="" + style.color + """; +diff --git a/im/locales/en-US/chrome/instantbird/accountWizard.properties b/im/locales/en-US/chrome/instantbird/accountWizard.properties +index 7d371bd21..1d6fd48e1 100644 +--- a/im/locales/en-US/chrome/instantbird/accountWizard.properties ++++ b/im/locales/en-US/chrome/instantbird/accountWizard.properties +@@ -14,9 +14,8 @@ topProtocol.list=prpl-irc,prpl-jabber,prpl-twitter,prpl-gtalk + # 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 +-topProtocol.prpl-yahoo.description=Chat with friends using Yahoo! Messenger + topProtocol.prpl-irc.description=Join IRC channels ++topProtocol.prpl-jabber.description=Chat using the open Jabber/XMPP protocol +diff --git a/im/test/xpcshell.ini b/im/test/xpcshell.ini +index 5f7dd70fc..578122a2a 100644 +--- a/im/test/xpcshell.ini ++++ b/im/test/xpcshell.ini +@@ -6,5 +6,4 @@ + [include:chat/components/src/test/xpcshell.ini] + [include:chat/protocols/irc/test/xpcshell.ini] + [include:chat/protocols/skype/test/xpcshell.ini] +-[include:chat/protocols/yahoo/test/xpcshell.ini] + #[include:extensions/purple/purplexpcom/src/test/xpcshell.ini] +diff --git a/mail/components/im/content/imconversation.xml b/mail/components/im/content/imconversation.xml +index 16c665ab4..a4b9fc638 100644 +--- a/mail/components/im/content/imconversation.xml ++++ b/mail/components/im/content/imconversation.xml +@@ -285,8 +285,7 @@ + msg = "<font face="" + style.fontFamily + "">" + msg + "</font>"; + // MSN doesn't support font size info in messages... + } +- else if (proto == "prpl-aim" || proto == "prpl-icq" || +- proto == "prpl-yahoo" || proto == "prpl-yahoojp") { ++ else if (proto == "prpl-aim" || proto == "prpl-icq") { + let styleAttributes = "" + if ("color" in style) + styleAttributes += " color="" + style.color + """; +-- +2.11.0 + diff --git a/projects/instantbird/0025-Bug-1316000-Remove-old-Yahoo-Messenger-support.-r-al.patch b/projects/instantbird/0025-Bug-1316000-Remove-old-Yahoo-Messenger-support.-r-al.patch deleted file mode 100644 index 1722403..0000000 --- a/projects/instantbird/0025-Bug-1316000-Remove-old-Yahoo-Messenger-support.-r-al.patch +++ /dev/null @@ -1,2398 +0,0 @@ -From 28b6432939ad61eacfe8c1e9559b3d5382298947 Mon Sep 17 00:00:00 2001 -From: Patrick Cloke clokep@gmail.com -Date: Wed, 9 Nov 2016 09:03:49 -0800 -Subject: [PATCH 25/27] Bug 1316000 - Remove old Yahoo! Messenger support. - r=aleth - ---- - chat/chat-prefs.js | 2 + - chat/locales/en-US/facebook.properties | 3 +- - chat/locales/en-US/yahoo.properties | 34 +- - chat/protocols/facebook/facebook.js | 13 +- - chat/protocols/yahoo/moz.build | 6 - - chat/protocols/yahoo/test/test_yahooAccount.js | 98 -- - chat/protocols/yahoo/test/test_yahooLoginHelper.js | 89 -- - chat/protocols/yahoo/test/test_yahoopacket.js | 217 ---- - chat/protocols/yahoo/test/xpcshell.ini | 7 - - chat/protocols/yahoo/yahoo-session.jsm | 1156 -------------------- - chat/protocols/yahoo/yahoo.js | 552 +--------- - im/content/conversation.xml | 3 +- - .../chrome/instantbird/accountWizard.properties | 3 +- - im/test/xpcshell.ini | 1 - - mail/components/im/content/imconversation.xml | 3 +- - 15 files changed, 18 insertions(+), 2169 deletions(-) - delete mode 100644 chat/protocols/yahoo/test/test_yahooAccount.js - delete mode 100644 chat/protocols/yahoo/test/test_yahooLoginHelper.js - delete mode 100644 chat/protocols/yahoo/test/test_yahoopacket.js - delete mode 100644 chat/protocols/yahoo/test/xpcshell.ini - delete mode 100644 chat/protocols/yahoo/yahoo-session.jsm - -diff --git a/chat/chat-prefs.js b/chat/chat-prefs.js -index fb769163d..60b9c1e8c 100644 ---- a/chat/chat-prefs.js -+++ b/chat/chat-prefs.js -@@ -84,6 +84,8 @@ pref("chat.irc.automaticList", true); - pref("chat.prpls.prpl-skype.disable", true); - // Disable Facebook as the XMPP gateway no longer exists. - pref("chat.prpls.prpl-facebook.disable", true); -+// Disable Yahoo Messenger as legacy Yahoo was shut down. -+pref("chat.prpls.prpl-yahoo.disable", true); - - // loglevel is the minimum severity level that a libpurple message - // must have to be reported in the Error Console. -diff --git a/chat/locales/en-US/facebook.properties b/chat/locales/en-US/facebook.properties -index aaf7cdc9c..2e00cbcb2 100644 ---- a/chat/locales/en-US/facebook.properties -+++ b/chat/locales/en-US/facebook.properties -@@ -2,6 +2,5 @@ - # 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/. - --connection.error.useUsernameNotEmailAddress=Please use your Facebook username, not an email address -- - facebook.chat.name=Facebook Chat -+facebook.disabled=Facebook Chat is no longer supported due to Facebook disabling their XMPP gateway. -diff --git a/chat/locales/en-US/yahoo.properties b/chat/locales/en-US/yahoo.properties -index 727faa6ee..89ee0093c 100644 ---- a/chat/locales/en-US/yahoo.properties -+++ b/chat/locales/en-US/yahoo.properties -@@ -2,36 +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/. - --login.error.badCredentials=Username or password is incorrect. --login.error.accountLockedFailed=Account locked due to too many failed login attempts. --login.error.accountLockedGeneral=Account locked due to too many login attempts. --login.error.accountDeactivated=Account has been deactivated. --login.error.usernameNotExist=The username does not exist. --# The %S will be an error code returned by the server. --login.error.unknown=Unknown error: %S --network.error.http=HTTP connection error. -- --conference.invite.message=Join my conference. -- --# Some options are commented out because they aren't used. We do the same thing --# to their description strings. --options.pagerPort=Port --options.transferHost=File transfer server --options.transferPort=File transfer port --options.chatEncoding=Encoding --options.ignoreInvites=Ignore conference invitations -- --# In this message, %S is replaced with the username of the user who left. --system.message.conferenceLogoff=%S has left the conference. --system.message.conferenceLogon=%S has joined the conference. -- --# LOCALZIATION NOTE (command.*): --# These are the help messages for each command, the %S is the command name --# Each command first gives the parameter it accepts and then a description of --# the command. --command.help.invite2=%S <user1>[,<user2>,...] [<invite message>]: invite one or more users into this conference chat. --command.help.conference=%S: Create a new conference room in which you can later invite other users. -- --# LOCALIZATION NOTE (command.feedback.invite): --# %S is the user, or comma separated list of users, invited to the conference. --command.feedback.invite=You have invited %S to the conference. -+yahoo.disabled=Yahoo Messenger is no longer supported due to Yahoo disabling their legacy protocol. -diff --git a/chat/protocols/facebook/facebook.js b/chat/protocols/facebook/facebook.js -index 7b5b3b86e..9d90eacdb 100644 ---- a/chat/protocols/facebook/facebook.js -+++ b/chat/protocols/facebook/facebook.js -@@ -6,33 +6,26 @@ var {interfaces: Ci, utils: Cu} = Components; - - Cu.import("resource:///modules/imXPCOMUtils.jsm"); - Cu.import("resource:///modules/jsProtoHelper.jsm"); --Cu.import("resource:///modules/xmpp.jsm"); --Cu.import("resource:///modules/xmpp-session.jsm"); - - XPCOMUtils.defineLazyGetter(this, "_", () => - l10nHelper("chrome://chat/locale/facebook.properties") - ); --XPCOMUtils.defineLazyGetter(this, "_irc", () => -- l10nHelper("chrome://chat/locale/irc.properties") --); - - function FacebookAccount(aProtoInstance, aImAccount) { - this._init(aProtoInstance, aImAccount); - } - FacebookAccount.prototype = { -- __proto__: XMPPAccountPrototype, -- get canJoinChat() { return false; }, -+ __proto__: GenericAccountPrototype, - connect: function() { - this.WARN("As Facebook deprecated its XMPP gateway, it is currently not " + - "possible to connect to Facebook Chat. See bug 1141674."); - this.reportDisconnecting(Ci.prplIAccount.ERROR_OTHER_ERROR, -- _irc("error.unavailable", _("facebook.chat.name"))); -+ _("facebook.disabled")); - this.reportDisconnected(); - } - }; - --function FacebookProtocol() { --} -+function FacebookProtocol() {} - FacebookProtocol.prototype = { - __proto__: GenericProtocolPrototype, - get normalizedName() { return "facebook"; }, -diff --git a/chat/protocols/yahoo/moz.build b/chat/protocols/yahoo/moz.build -index f14434732..ea378535a 100644 ---- a/chat/protocols/yahoo/moz.build -+++ b/chat/protocols/yahoo/moz.build -@@ -3,15 +3,9 @@ - # 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/. - --XPCSHELL_TESTS_MANIFESTS += ['test/xpcshell.ini'] -- - EXTRA_COMPONENTS += [ - 'yahoo.js', - 'yahoo.manifest', - ] - --EXTRA_JS_MODULES += [ -- 'yahoo-session.jsm', --] -- - JAR_MANIFESTS += ['jar.mn'] -diff --git a/chat/protocols/yahoo/test/test_yahooAccount.js b/chat/protocols/yahoo/test/test_yahooAccount.js -deleted file mode 100644 -index 51df00bb9..000000000 ---- a/chat/protocols/yahoo/test/test_yahooAccount.js -+++ /dev/null -@@ -1,98 +0,0 @@ --/* Any copyright is dedicated to the Public Domain. -- * http://creativecommons.org/publicdomain/zero/1.0/ */ -- --Components.utils.import("resource://gre/modules/Services.jsm"); --var yahoo = {}; --Services.scriptloader.loadSubScript("resource:///components/yahoo.js", yahoo); -- --function run_test() --{ -- add_test(test_cleanUsername); -- add_test(test_fixFontSize); -- run_next_test(); --} -- --// Test the stripping of @yahoo.* domains from usernames. --function test_cleanUsername() --{ -- // These are just a few of the many possible domains. -- let domains = ["yahoo.com.ar", "yahoo.com.au", "yahoo.com", "yahoo.co.jp", -- "yahoo.it", "yahoo.cn", "yahoo.co.in"]; -- let userId = "user"; -- -- // We must provide a mimimal fake implementation of a protocol object, to keep -- // the YahooAccount constructor happy. -- let fakeProtocol = { -- id: "fake-proto", -- options: { -- local_charset: "UTF-8" -- }, -- _getOptionDefault: function(aOption) { return this.options[aOption]; } -- }; -- let fakeImAccount = {}; -- -- for each(let domain in domains) { -- fakeImAccount.name = userId + "@" + domain; -- let yahooAccount = new yahoo.YahooAccount(fakeProtocol, fakeImAccount); -- do_check_eq(userId, yahooAccount.cleanUsername); -- } -- run_next_test(); --} -- --// Test the _fixFontSize() method and ensure that it correctly fixes font sizes --// in <font> tags while keeping any mention of size= in conversation untouched. --function test_fixFontSize() --{ -- // This is an array of two-element arrays. Each inner two-element array -- // contains a message with a badly formed font size as the first element, -- // and a message with a well-formed font size as the second element. We test -- // to ensure that the badly formed message is converted to the well-formed -- // one. -- let testMessages = [ -- // Single font tag. -- ["<font face="Arial" size="12">Test message 1", -- "<font face="Arial" size="3">Test message 1"], -- // Single font tag with size="<digit>" in innner message. -- ["<font face="Arial" size="9">size="30" is a big size.</font>", -- "<font face="Arial" size="2">size="30" is a big size.</font>"], -- // Single font tag with no face attribute. -- ["<font size="12">This message has no font face attribute.", -- "<font size="3">This message has no font face attribute."], -- // Single font tag with no size attribute. -- ["<font face="Arial">This message has no font size attribute.", -- "<font face="Arial">This message has no font size attribute."], -- // Single font tag with rearranged attribute order. -- ["<font size="9" face="Arial">size="30" is a big size.</font>", -- "<font size="2" face="Arial">size="30" is a big size.</font>"], -- // Multiple font tags. -- ["<font face="Arial" size="12">Hello. <font face="Consolas" size="40">World", -- "<font face="Arial" size="3">Hello. <font face="Consolas" size="7">World"] -- ]; -- -- let fakeProtocol = { -- id: "fake-proto", -- options: { -- local_charset: "UTF-8" -- }, -- _getOptionDefault: function(aOption) { return this.options[aOption]; } -- }; -- let fakeImAccount = {name: "test-user"}; -- // We create a fake conversation object so we can obtain the cleaned up -- // message from the conv.writeMessage() call. -- let messagePair; -- let fakeConversation = { -- writeMessage: function(aName, aMessage, aProperties) { -- do_check_eq(aMessage, messagePair[1]); // Compare to the good message. -- }, -- updateTyping: function(aStatus, aName) { } -- }; -- -- let yahooAccount = new yahoo.YahooAccount(fakeProtocol, fakeImAccount); -- yahooAccount._conversations.set("test-user", fakeConversation); -- for each(let pair in testMessages) { -- messagePair = pair; -- // Send in the badly formed message. -- yahooAccount.receiveMessage("test-user", messagePair[0]); -- } -- run_next_test(); --} -diff --git a/chat/protocols/yahoo/test/test_yahooLoginHelper.js b/chat/protocols/yahoo/test/test_yahooLoginHelper.js -deleted file mode 100644 -index e4d8bc1b8..000000000 ---- a/chat/protocols/yahoo/test/test_yahooLoginHelper.js -+++ /dev/null -@@ -1,89 +0,0 @@ --/* Any copyright is dedicated to the Public Domain. -- * http://creativecommons.org/publicdomain/zero/1.0/ */ -- --Components.utils.import("resource:///modules/ArrayBufferUtils.jsm"); --Components.utils.import("resource://gre/modules/Services.jsm"); --Components.utils.import("resource:///modules/yahoo-session.jsm"); --var yahoo = {}; --Services.scriptloader.loadSubScript("resource:///modules/yahoo-session.jsm", yahoo); -- --// Preset test values. --var kUsername = "testUser"; --var kPassword = "instantbird"; --var kPagerIp = "123.456.78.9"; --var kCrumb = "MG-Z/jNG+Q=="; --var kChallengeString = "AEF08DBAC33F9EEDABCFEA=="; --var kYCookie = "OTJmMTQyOTU1ZGQ4MDA3Y2I2ODljMTU5"; --var kTCookie = "NTdlZmIzY2Q4ODI3ZTc3NTIxYTk1MDhm"; --var kToken = "MThmMzg3OWM3ODcxMW"; -- --var kPagerAddressResponse = "COLO_CAPACITY=1\r\nCS_IP_ADDRESS=" + kPagerIp; --var kTokenResponse = "0\r\n" + kToken + "\r\npartnerid=dummyValue"; --var kCookieResponse = "0\r\ncrumb=" + kCrumb + "\r\nY=" + kYCookie + -- "\r\nT=" + kTCookie + "\r\ncookievalidfor=86400"; -- --/* In each test, we override the function that would normally be called next in -- * the login process. We do this so that we can intercept the login process, -- * preventing calls to real Yahoo! servers, and do equality testing. */ --function run_test() --{ -- add_test(test_pagerAddress); -- add_test(test_challengeString); -- add_test(test_loginToken); -- add_test(test_cookies); -- run_next_test(); --} -- --function test_pagerAddress() --{ -- let helper = new yahoo.YahooLoginHelper({}, {}); -- -- helper._getChallengeString = function() { -- do_check_eq(kPagerIp, helper._session.pagerAddress); -- run_next_test(); -- }; -- -- helper._onPagerAddressResponse(kPagerAddressResponse, null); --} -- --function test_challengeString() --{ -- let helper = new yahoo.YahooLoginHelper({}, {}); -- -- helper._getLoginToken = function() { -- do_check_eq(kChallengeString, helper._challengeString); -- run_next_test(); -- }; -- -- let response = new yahoo.YahooPacket(yahoo.kPacketType.AuthResponse, 0, 0); -- response.addValue(1, helper._username); -- response.addValue(94, kChallengeString); -- response.addValue(13, 0); -- helper._onChallengeStringResponse(response.toArrayBuffer()); --} -- --function test_loginToken() --{ -- let helper = new yahoo.YahooLoginHelper({}, {}); -- -- helper._getCookies = function() { -- do_check_eq(kToken, helper._loginToken); -- run_next_test(); -- }; -- -- helper._onLoginTokenResponse(kTokenResponse, null); --} -- --function test_cookies() --{ -- let helper = new yahoo.YahooLoginHelper({}, {}); -- -- helper._sendPagerAuthResponse = function() { -- do_check_eq(kCrumb, helper._crumb); -- do_check_eq(kYCookie, helper._session.yCookie); -- do_check_eq(kTCookie, helper._session.tCookie); -- run_next_test(); -- }; -- -- helper._onLoginCookiesResponse(kCookieResponse, null); --} -diff --git a/chat/protocols/yahoo/test/test_yahoopacket.js b/chat/protocols/yahoo/test/test_yahoopacket.js -deleted file mode 100644 -index 7908c4429..000000000 ---- a/chat/protocols/yahoo/test/test_yahoopacket.js -+++ /dev/null -@@ -1,217 +0,0 @@ --/* Any copyright is dedicated to the Public Domain. -- * http://creativecommons.org/publicdomain/zero/1.0/ */ -- --Components.utils.import("resource:///modules/ArrayBufferUtils.jsm"); --Components.utils.import("resource://gre/modules/Services.jsm"); --Components.utils.import("resource:///modules/yahoo-session.jsm"); --var yahoo = {}; --Services.scriptloader.loadSubScript("resource:///modules/yahoo-session.jsm", yahoo); -- --var kPacketIdBytes = StringToBytes(yahoo.kPacketIdentfier); --var kHelloKey = 1; --var kHelloValue = "Hello"; --var kWorldKey = 20; --var kWorldValue = "World"; --var kNumberKey = 4; --var kNumberValue = 32; --var kParamsKey = 60; --var kParam1Value = "param1"; --var kParam2Value = "param2"; --var kPacketDataString = "1\xC0\x80Hello\xC0\x8020\xC0\x80World\xC0\x80" + -- "4\xC0\x8032\xC0\x8060\xC0\x80param1\xC0\x80" + -- "60\xC0\x80param2\xC0\x80"; -- --function run_test() --{ -- add_test(test_headerCreation); -- add_test(test_fullPacketCreation); -- add_test(test_packetDecoding); -- add_test(test_extractPackets); -- add_test(test_malformedPacketExtraction); -- -- run_next_test(); --} -- --function test_headerCreation() --{ -- let packetLength = 0; -- // Random numbers. -- let serviceNumber = 0x57; -- let status = 0x04; -- let sessionId = 0x57842390; -- -- let packet = new yahoo.YahooPacket(serviceNumber, status, sessionId); -- let buf = packet.toArrayBuffer(); -- let view = new DataView(buf); -- -- // Ensure that the first 4 bytes contain the YMSG identifier. -- for (let i = 0; i < kPacketIdBytes.length; ++i) -- do_check_eq(kPacketIdBytes[i], view.getUint8(i)); -- -- do_check_eq(yahoo.kProtocolVersion, view.getUint16(4)); -- do_check_eq(yahoo.kVendorId, view.getUint16(6)); -- do_check_eq(packetLength, view.getUint16(8)); -- do_check_eq(serviceNumber, view.getUint16(10)); -- do_check_eq(status, view.getUint32(12)); -- do_check_eq(sessionId, view.getUint32(16)); -- -- run_next_test(); --} -- --function test_fullPacketCreation() --{ -- packetLength = kPacketDataString.length; -- // Random numbers. -- let serviceNumber = 0x55; -- let status = 0x02; -- let sessionId = 0x12567800; -- -- let packet = new yahoo.YahooPacket(serviceNumber, status, sessionId); -- packet.addValue(kHelloKey, kHelloValue); -- packet.addValue(kWorldKey, kWorldValue); -- packet.addValue(kNumberKey, kNumberValue); -- packet.addValues(kParamsKey, [kParam1Value, kParam2Value]); -- let buf = packet.toArrayBuffer(); -- let view = new DataView(buf); -- -- // Header check. -- -- // Ensure that the first 4 bytes contain the YMSG identifier. -- for (let i = 0; i < kPacketIdBytes.length; ++i) -- do_check_eq(kPacketIdBytes[i], view.getUint8(i)); -- -- do_check_eq(yahoo.kProtocolVersion, view.getUint16(4)); -- do_check_eq(yahoo.kVendorId, view.getUint16(6)); -- do_check_eq(packetLength, view.getUint16(8)); -- do_check_eq(serviceNumber, view.getUint16(10)); -- do_check_eq(status, view.getUint32(12)); -- do_check_eq(sessionId, view.getUint32(16)); -- -- // Packet data check. -- let dataBytes = StringToBytes(kPacketDataString); -- for (let i = 0; i < dataBytes.length; ++i) -- do_check_eq(dataBytes[i], view.getUint8(yahoo.kPacketHeaderSize + i)); -- run_next_test() --} -- --function test_packetDecoding() --{ -- let packetLength = kPacketDataString.length; -- // Random numbers. -- let serviceNumber = 0x20; -- let status = 0x06; -- let sessionId = 0x13319AB2; -- -- let buf = new ArrayBuffer(yahoo.kPacketHeaderSize + packetLength); -- let view = new DataView(buf); -- -- for (let i = 0; i < kPacketIdBytes.length; ++i) -- view.setUint8(i, kPacketIdBytes[i]); -- -- view.setUint16(4, yahoo.kProtocolVersion); -- view.setUint16(6, yahoo.kVendorId); -- view.setUint16(8, packetLength); -- view.setUint16(10, serviceNumber); -- view.setUint32(12, status); -- view.setUint32(16, sessionId); -- -- let dataBuf = BytesToArrayBuffer(StringToBytes(kPacketDataString)); -- copyBytes(buf, dataBuf, 20); -- -- // Now we decode and test. -- let packet = new yahoo.YahooPacket(); -- packet.fromArrayBuffer(buf); -- -- // Test header information. -- do_check_eq(serviceNumber, packet.service); -- do_check_eq(status, packet.status); -- do_check_eq(sessionId, packet.sessionId); -- -- // Test the getting of single packet data values. -- do_check_eq(kHelloValue, packet.getValue(kHelloKey)); -- do_check_eq(kWorldValue, packet.getValue(kWorldKey)); -- do_check_eq(kNumberValue, packet.getValue(kNumberKey)); -- -- // Test the getting of multiple values with a single key. -- let multiValue = packet.getValues(kParamsKey); -- do_check_eq(2, multiValue.length); -- do_check_eq(kParam1Value, multiValue[0]); -- do_check_eq(kParam2Value, multiValue[1]); -- -- // Test if certain keys are non-existant. -- do_check_true(packet.hasKey(kHelloKey)); -- do_check_false(packet.hasKey(500)); // There is no key 500. -- -- run_next_test(); --} -- --function test_extractPackets() --{ -- // Some constants for each packet. -- const kP1Service = 0x47; -- const kP1Status = 0; -- const kP1SessionId = 0x12345678; -- // Used for testing packet verification. -- const kP1FuzzerKey = 42; -- const kP1FuzzerValue = "I am using the YMSG protocol!"; -- -- const kP2Service = 0x57; -- const kP2Status = 5; -- const kP2SessionId = 0x87654321; -- -- // First, create two packets and obtain their buffers. -- let packet1 = new yahoo.YahooPacket(kP1Service, kP1Status, kP1SessionId); -- packet1.addValue(kHelloKey, kHelloValue); -- packet1.addValue(kP1FuzzerKey, kP1FuzzerValue); -- let packet1Buffer = packet1.toArrayBuffer(); -- -- let packet2 = new yahoo.YahooPacket(kP2Service, kP2Status, kP2SessionId); -- packet2.addValue(kWorldKey, kWorldValue); -- let packet2Buffer = packet2.toArrayBuffer(); -- -- // Create one full buffer with both packets inside. -- let fullBuffer = new ArrayBuffer(packet1Buffer.byteLength + -- packet2Buffer.byteLength); -- copyBytes(fullBuffer, packet1Buffer); -- copyBytes(fullBuffer, packet2Buffer, packet1Buffer.byteLength); -- -- // Now, run the packets through the extractPackets() method. -- let [extractedPackets, bytesHandled] = -- yahoo.YahooPacket.extractPackets(fullBuffer); -- do_check_eq(2, extractedPackets.length); -- -- // Packet 1 checks. -- let p1 = extractedPackets[0]; -- do_check_eq(kP1Service, p1.service); -- do_check_eq(kP1Status, p1.status); -- do_check_eq(kP1SessionId, p1.sessionId); -- do_check_true(p1.hasKey(kHelloKey)); -- do_check_eq(kHelloValue, p1.getValue(kHelloKey)); -- -- // Packet 2 checks. -- let p2 = extractedPackets[1]; -- do_check_eq(kP2Service, p2.service); -- do_check_eq(kP2Status, p2.status); -- do_check_eq(kP2SessionId, p2.sessionId); -- do_check_true(p2.hasKey(kWorldKey)); -- do_check_eq(kWorldValue, p2.getValue(kWorldKey)); -- -- // Check if all the bytes were handled. -- do_check_eq(fullBuffer.byteLength, bytesHandled); -- -- run_next_test(); --} -- --function test_malformedPacketExtraction() --{ -- const kInvalidPacketData = "MSYG1\xC0\x80Hello\xC0\x8020\xC0\x80World\xC0\x80"; -- let buffer = BytesToArrayBuffer(StringToBytes(kInvalidPacketData)); -- let malformed = false; -- try { -- yahoo.YahooPacket.extractPackets(buffer); -- } catch(e) { -- malformed = true; -- } -- do_check_true(malformed); -- run_next_test(); --} -diff --git a/chat/protocols/yahoo/test/xpcshell.ini b/chat/protocols/yahoo/test/xpcshell.ini -deleted file mode 100644 -index f4b464e61..000000000 ---- a/chat/protocols/yahoo/test/xpcshell.ini -+++ /dev/null -@@ -1,7 +0,0 @@ --[DEFAULT] --head = --tail = -- --[test_yahooAccount.js] --[test_yahooLoginHelper.js] --[test_yahoopacket.js] -diff --git a/chat/protocols/yahoo/yahoo-session.jsm b/chat/protocols/yahoo/yahoo-session.jsm -deleted file mode 100644 -index cc9612036..000000000 ---- a/chat/protocols/yahoo/yahoo-session.jsm -+++ /dev/null -@@ -1,1156 +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/. */ -- --this.EXPORTED_SYMBOLS = ["YahooSession"]; -- --var {classes: Cc, interfaces: Ci, utils: Cu} = Components; -- --Cu.import("resource://gre/modules/FileUtils.jsm"); --Cu.import("resource://gre/modules/Http.jsm"); --Cu.import("resource://gre/modules/NetUtil.jsm"); --Cu.import("resource:///modules/ArrayBufferUtils.jsm"); --Cu.import("resource:///modules/imServices.jsm"); --Cu.import("resource:///modules/imXPCOMUtils.jsm"); --Cu.import("resource:///modules/socket.jsm"); -- --XPCOMUtils.defineLazyGetter(this, "_", () => -- l10nHelper("chrome://chat/locale/yahoo.properties") --); -- --XPCOMUtils.defineLazyServiceGetter(this, "imgTools", -- "@mozilla.org/image/tools;1", "imgITools"); -- --var kProtocolVersion = 16; --var kVendorId = 0; -- --var kPacketDataDelimiter = "\xC0\x80"; --var kPacketIdentifier = "YMSG"; --var kPacketHeaderSize = 20; --var kProfileIconWidth = 96; -- --// These constants are used by the icon uploading code since the Yahoo! file --// transfer server is used for user icon uploads. --var kFileTransferHost = "filetransfer.msg.yahoo.com"; --var kFileTransferPort = 80; -- --var kPacketType = { -- // Sent by a client when logging off of the Yahoo! network. -- Logoff: 0x02, -- // Sent by a client when a message is sent to a buddy. -- Message: 0x06, -- // Sent to the pager server once per hour. -- Ping: 0x12, -- // Used for inviting others to a conference. -- ConfInvite: 0x18, -- // Used as a notification when you or someone else joins a conference room. -- ConfLogon: 0x19, -- // Used as a notification when you or someone else leaves a conference room. -- ConfLogoff: 0x1b, -- // This is sent by the client when additional users are invited to the -- // conference, but it can be sent as the first invite as well. -- ConfAddInvite: 0x1c, -- // Broadcast to all users in a conference room when someone posts a message. -- ConfMessage: 0x1d, -- // Used for typing notifications. -- Notify: 0x4b, -- // These two are used during initial authentication with the pager server. -- AuthResponse: 0x54, -- Auth: 0x57, -- // Buddy list controls. -- AddBuddy: 0x83, -- RemoveBuddy: 0x84, -- // This is sent when you reject a Yahoo! user's buddy request. -- BuddyReqReject: 0x86, -- // Sent to the server once every minute, telling it here are still alive. -- KeepAlive: 0x8A, -- // This is sent when we request a buddy icon. -- Picture: 0xbe, -- // This is sent after a profile picture has been successfully uploaded. -- PictureUpload: 0xc2, -- // This is sent whenever a buddy changes their status. -- StatusUpdate: 0xc6, -- // This is sent when we update our icon. -- AvatarUpdate: 0xc7, -- // This is sent when someone wishes to become your buddy. -- BuddyAuth: 0xd6, -- // Holds the initial status of all buddies when a user first logs in. -- StatusInitial: 0xf0, -- // Contains the buddy list sent from the server. -- List: 0xf1, -- // Sent back to the pager server after each received message. Sending this -- // prevents echoed messages when chatting with the official Yahoo! client. -- MessageAck: 0xfb --}; -- --var kPacketStatuses = { -- ServerAck: 0x1, -- Typing: 0x16 --}; -- --// Each Yahoo! error code is mapped to a two-element array. The first element --// contains the last part of the name of its localized string. This is appended --// to "login.error." to obtain the string. The second element is the --// Instantbird error that is given to the error handler. --var kLoginStatusErrors = { -- "1212" : ["badCredentials", -- Ci.prplIAccount.ERROR_AUTHENTICATION_FAILED], -- "1213" : ["accountLockedFailed", -- Ci.prplIAccount.ERROR_AUTHENTICATION_FAILED], -- "1218" : ["accountDeactivated", -- Ci.prplIAccount.ERROR_AUTHENTICATION_FAILED], -- "1235" : ["usernameNotExist", -- Ci.prplIAccount.ERROR_INVALID_USERNAME], -- "1236" : ["accountLockedGeneral", -- Ci.prplIAccount.ERROR_AUTHENTICATION_FAILED] --}; -- --// These are the status codes that buddies can send us. --var kBuddyStatuses = { -- // Available. -- "0" : Ci.imIStatusInfo.STATUS_AVAILABLE, -- // Be right back. -- "1" : Ci.imIStatusInfo.STATUS_AWAY, -- // Busy. -- "2" : Ci.imIStatusInfo.STATUS_UNAVAILABLE, -- // Not at home. -- "3" : Ci.imIStatusInfo.STATUS_AWAY, -- // Not at desk. -- "4" : Ci.imIStatusInfo.STATUS_AWAY, -- // Not in office. -- "5" : Ci.imIStatusInfo.STATUS_AWAY, -- // On phone. -- "6" : Ci.imIStatusInfo.STATUS_AWAY, -- // On vacation. -- "7" : Ci.imIStatusInfo.STATUS_AWAY, -- // Out to lunch. -- "8" : Ci.imIStatusInfo.STATUS_AWAY, -- // Stepped out. -- "9" : Ci.imIStatusInfo.STATUS_AWAY, -- // Invisible. -- "12" : Ci.imIStatusInfo.STATUS_INVISIBLE, -- // Custom status. -- "99" : Ci.imIStatusInfo.STATUS_AWAY, -- // Idle. -- "999" : Ci.imIStatusInfo.STATUS_IDLE --}; -- --/* The purpose of the YahooSession object is to serve as a gateway between the -- * protocol plug-in and the Yahoo! Messenger servers. Anytime an object outside -- * of this file wishes to communicate with the servers, it should do it through -- * one of the methods provided by YahooSession. By centralizing such network -- * access, we can easily catch errors, and ensure that communication is handled -- * correctly. */ --function YahooSession(aAccount) --{ -- this._account = aAccount; -- this.binaryMode = true; --} --YahooSession.prototype = { -- __proto__: Socket, -- _account: null, -- _socket: null, -- _username: null, -- // This is the IPv4 address to the pager server which is the gateway into the -- // Yahoo! Messenger network. -- pagerAddress: null, -- // The session ID is obtained during the login process and is maintained -- // throughout the session. This helps the pager server identify the client. -- sessionId: null, -- // The T and Y cookies obtained by the YahooLoginHelper during login. -- tCookie: null, -- yCookie: null, -- -- // Public methods. -- login: function() { -- this._account.reportConnecting(); -- new YahooLoginHelper(this).login(this._account); -- }, -- -- sendPacket: function(aPacket) { -- this.sendBinaryData(aPacket.toArrayBuffer(), aPacket.toString()); -- }, -- -- addBuddyToServer: function(aBuddy) { -- let packet = new YahooPacket(kPacketType.AddBuddy, 0, this.sessionId); -- // We leave this invite message empty. Any message placed here will -- // annoyingly be sent to the invitee when they accept the invite. -- packet.addValue(14, ""); -- packet.addValue(65, aBuddy.tag.name); -- packet.addValue(97, "1"); // UTF-8 encoding. -- packet.addValue(1, this._account.cleanUsername); -- // The purpose of these two values are unknown. -- packet.addValue(302, "319"); -- packet.addValue(300, "319"); -- packet.addValue(7, aBuddy.userName); -- // The purpose of these three values are also unknown. -- packet.addValue(334, "0"); -- packet.addValue(301, "319"); -- packet.addValue(303, "319"); -- this.sendPacket(packet); -- }, -- -- removeBuddyFromServer: function(aBuddy) { -- let packet = new YahooPacket(kPacketType.RemoveBuddy, 0, this.sessionId); -- packet.addValue(1, this._account.cleanUsername); -- packet.addValue(7, aBuddy.userName); -- packet.addValue(65, aBuddy.tag.name); -- this.sendPacket(packet); -- }, -- -- setStatus: function(aStatus, aMessage) { -- let packet = new YahooPacket(kPacketType.StatusUpdate, 0, this.sessionId); -- -- // When a custom status message is used, key 10 is set to 99, and key 97 -- // is set to 1. Otherwise, key 10 is set to our current status code. -- if (aMessage && aMessage.length > 0) { -- packet.addValue(10, "99"); -- packet.addValue(97, "1"); -- } else { -- let statusCode; -- switch(aStatus) { -- // Available -- case Ci.imIStatusInfo.STATUS_AVAILABLE: -- case Ci.imIStatusInfo.STATUS_MOBILE: -- statusCode = "0"; -- break; -- // Away -- case Ci.imIStatusInfo.STATUS_AWAY: -- statusCode = "1"; -- break; -- // Busy -- case Ci.imIStatusInfo.STATUS_UNAVAILABLE: -- statusCode = "2"; -- break; -- // Invisible -- case Ci.imIStatusInfo.STATUS_INVISIBLE: -- statusCode = "12"; -- break; -- // Idle -- case Ci.imIStatusInfo.STATUS_IDLE: -- statusCode = "999"; -- break; -- } -- packet.addValue(10, statusCode); -- } -- -- // Key 19 is always set as the status messgae, even when the message is -- // empty. If key 10 is set to 99, the message is used. -- packet.addValue(19, aMessage); -- -- // Key 47 is always set to either 0, if we are available, or 1, if we are -- // not available. The value is used by the server if key 10 is set to 99. -- // Otherwise, the value of key 10 is used to determine our status. -- packet.addValue(47, (aStatus == Ci.imIStatusInfo.STATUS_AVAILABLE) ? -- "0" : "1"); -- this.sendPacket(packet); -- }, -- -- sendChatMessage: function(aName, aMessage) { -- let packet = new YahooPacket(kPacketType.Message, 0, this.sessionId); -- // XXX Key 0 is the user ID, and key 1 is the active ID. We need to find -- // the difference between these two. Alias maybe? -- packet.addValue(0, this._account.cleanUsername); -- packet.addValue(1, this._account.cleanUsername); -- packet.addValue(5, aName); -- packet.addValue(14, aMessage); -- this.sendPacket(packet); -- }, -- -- sendConferenceMessage: function(aRecipients, aRoom, aMessage) { -- let packet = new YahooPacket(kPacketType.ConfMessage, 0, this.sessionId); -- packet.addValue(1, this._account.cleanUsername); -- packet.addValues(53, aRecipients); -- packet.addValue(57, aRoom); -- packet.addValue(14, aMessage); -- packet.addValue(97, "1"); // Use UTF-8 encoding. -- this.sendPacket(packet); -- }, -- -- sendTypingStatus: function(aBuddyName, aIsTyping) { -- let packet = new YahooPacket(kPacketType.Notify, kPacketStatuses.Typing, -- this.sessionId); -- packet.addValue(1, this._account.cleanUsername); -- packet.addValue(5, aBuddyName); -- packet.addValue(13, aIsTyping ? "1" : "0"); -- packet.addValue(14, " "); // Key 14 contains a single space. -- packet.addValue(49, "TYPING"); -- this.sendPacket(packet); -- }, -- -- acceptConferenceInvite: function(aOwner, aRoom, aParticipants) { -- let packet = new YahooPacket(kPacketType.ConfLogon, 0, this.sessionId); -- packet.addValue(1, this._account.cleanUsername); -- packet.addValue(57, aRoom); -- packet.addValues(3, aParticipants); -- this.sendPacket(packet); -- }, -- -- createConference: function(aRoom) { -- let packet = new YahooPacket(kPacketType.ConfLogon, 0, this.sessionId); -- packet.addValue(1, this._account.cleanUsername); -- packet.addValue(3, this._account.cleanUsername); -- packet.addValue(57, aRoom); -- this.sendPacket(packet); -- }, -- -- inviteToConference: function(aInvitees, aRoom, aParticipants, aMessage) { -- let packet = new YahooPacket(kPacketType.ConfAddInvite, 0, this.sessionId); -- packet.addValue(1, this._account.cleanUsername); -- packet.addValues(51, aInvitees); -- packet.addValues(53, aParticipants); -- packet.addValue(57, aRoom); -- packet.addValue(58, aMessage); -- packet.addValue(13, "0"); -- this.sendPacket(packet); -- }, -- -- sendConferenceLogoff: function(aName, aParticipants, aRoom) { -- let packet = new YahooPacket(kPacketType.ConfLogoff, 0, this.sessionId); -- packet.addValue(1, aName); -- packet.addValues(3, aParticipants); -- packet.addValue(57, aRoom); -- this.sendPacket(packet); -- }, -- -- setProfileIcon: function(aFileName) { -- // If we have an empty filename, remove the icon from the server. -- if (!aFileName) { -- let packet = new YahooPacket(kPacketType.AvatarUpdate, 0, this.sessionId); -- packet.addValue(3, this._account.cleanUsername); -- packet.addValue(213, 0); -- this.sendPacket(packet); -- return; -- } -- // Try to get a handle to the icon file. -- let file = FileUtils.getFile("ProfD", [aFileName]); -- let type = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService) -- .getTypeFromFile(file); -- NetUtil.asyncFetch({ -- uri: NetUtil.newURI(file), -- contentPolicyType: Ci.nsIContentPolicy.TYPE_IMAGE, -- securityFlags: Ci.nsILoadInfo.SEC_NORMAL, -- loadUsingSystemPrincipal: true -- }, (aStream, aStatus) => { -- if (!Components.isSuccessCode(aStatus)) { -- throw "Could not access icon file."; -- return; -- } -- let image = imgTools.decodeImage(aStream, type); -- let uploader = new YahooProfileIconUploader(this._account, this, -- aFileName, image); -- uploader.uploadIcon(); -- }); -- }, -- -- requestBuddyIcon: function(aName) { -- let packet = new YahooPacket(kPacketType.Picture, 0, this.sessionId); -- packet.addValue(1, this._account.cleanUsername); -- packet.addValue(5, aName); // The name of the buddy. -- packet.addValue(13, "1"); // "1" means we wish to request an icon. -- this.sendPacket(packet); -- }, -- -- acceptBuddyRequest: function(aRequest) { -- let packet = new YahooPacket(kPacketType.BuddyAuth, 0, this.sessionId); -- packet.addValue(1, this._account.cleanUsername); -- packet.addValue(5, aRequest.userName); -- // Misc. Unknown flags. -- packet.addValue(13, 1); -- packet.addValue(334, 0); -- this.sendPacket(packet); -- -- // If someone wants to add us as a buddy, place them under the default -- // tag. Also, we make sure that the buddy doesn't already exist in the -- // list in case of a server acknowledgement. -- if (!this._account.hasBuddy(aRequest.userName)) -- this._account.addBuddy(Services.tags.defaultTag, aRequest.userName); -- }, -- -- denyBuddyRequest: function(aRequest) { -- let packet = new YahooPacket(kPacketType.BuddyReqReject, 0, this.sessionId); -- packet.addValue(1, this._account.cleanUsername); -- packet.addValue(7, aRequest.userName); -- packet.addValue(14, ""); -- this.sendPacket(packet); -- }, -- -- sendKeepAlive: function() { -- let packet = new YahooPacket(kPacketType.KeepAlive, 0, this.sessionId); -- packet.addValue(0, this._account.cleanUsername); -- this.sendBinaryData(packet.toArrayBuffer()); -- }, -- -- sendPing: function() { -- let packet = new YahooPacket(kPacketType.Ping, 0, this.sessionId); -- this.sendBinaryData(packet.toArrayBuffer()); -- }, -- -- // Callbacks. -- onLoginComplete: function() { -- this._account.reportConnected(); -- this._account.onLoginComplete(); -- }, -- -- onSessionError: function(aError, aMessage) { -- this._account.reportDisconnecting(aError, aMessage); -- if (!this.disconnected) -- this.disconnect(); -- this._account.reportDisconnected(); -- }, -- -- // Private methods. -- -- // Socket Event Callbacks. -- LOG: function(aString) { return this._account.LOG(aString); }, -- -- DEBUG: function(aString) { return this._account.DEBUG(aString); }, -- -- onConnection: function() { -- // We send an authentication request packet as soon as we connect to the -- // pager server. -- let packet = new YahooPacket(kPacketType.Auth, 0, 0); -- packet.addValue(1, this._account.cleanUsername); -- this.sendPacket(packet); -- }, -- -- onConnectionTimedOut: function() { -- this.onSessionError(Ci.prplIAccount.NETWORK_ERROR, ""); -- }, -- -- onConnectionReset: function() { -- this.onSessionError(Ci.prplIAccount.NETWORK_ERROR, ""); -- }, -- -- // Called when the other end has closed the connection. -- onConnectionClosed: function() { -- if (!this._account.connected) -- return; -- this._account.reportDisconnecting(Ci.prplIAccount.NO_ERROR, ""); -- this._account.reportDisconnected(); -- }, -- -- onBinaryDataReceived: function(aData) { -- let packets; -- let bytesHandled; -- try { -- [packets, bytesHandled] = YahooPacket.extractPackets(aData); -- } catch(e) { -- this._account.ERROR(e); -- this.onSessionError(Ci.prplIAccount.NETWORK_ERROR, ""); -- return 0; -- } -- -- for each (let packet in packets) { -- this._account.LOG("Received Packet:\n" + packet.toString()); -- if (YahooPacketHandler.hasOwnProperty(packet.service)) { -- try { -- YahooPacketHandler[packet.service].call(this._account, packet); -- } catch(e) { -- this._account.ERROR(e); -- } -- } else { -- this._account.WARN("No handler for Yahoo! packet " + -- packet.service.toString(16) + "."); -- } -- } -- return bytesHandled; -- } --}; -- --/* The purpose of YahooLoginHelper is to separate the complicated login logic -- * from the YahooSession object. Logging in on Yahoo!'s network is the most -- * complicated stage of a session due to the authentication system that is -- * employed. The login steps are listed below. -- * -- * 1) Get the address of a "pager" server. This pager will be our gateway to -- * the network. -- * -- * 2) Obtain the challenge string from the pager. This string is used to help -- * create the base64 response string needed for the final step. -- * -- * 3) Obtain a token from the login server via HTTP. -- * -- * 4) Obtain the login crumb, Y-Cookie, and T-Cookie from the login server via -- * HTTP. These will also be used in the final response packet to the pager. -- * -- * 5) Create the base64 response string from the MD5 hash of the crumb and -- * challenge string, and build a packet containing the username, password, -- * response string, version numbers, crumb, and cookies, sending it to the -- * pager for a final authenticatcation. -- * -- * If all goes well after the 5th step, the user is considered logged in. */ --function YahooLoginHelper(aSession) --{ -- this._session = aSession; --} --YahooLoginHelper.prototype = { -- // YahooSession object passed in constructor. -- _session: null, -- // YahooAccount object passed to login(). -- _account: null, -- // The username, stripped of any @yahoo.com or @yahoo.co.jp suffix. -- _username: null, -- // The authentication challenge string sent from the Yahoo!'s login server. -- _challengeString: null, -- // The authentication token sent from Yahoo!'s login server. -- _loginToken: null, -- // Crumb sent from Yahoo!'s login server, and used in the final authentication -- // request to the pager server. -- _crumb: null, -- -- // Public methods. -- login: function(aAccount) { -- this._account = aAccount; -- this._getPagerAddress(); -- }, -- -- // Private methods. -- _getPagerAddress: function() { -- let options = { -- onLoad: this._onPagerAddressResponse.bind(this), -- onError: this._onHttpError.bind(this) -- } -- httpRequest(this._account._protocol.pagerRequestUrl, options); -- }, -- -- _getChallengeString: function() { -- let port = this._account.getInt("port"); -- this._session.connect(this._session.pagerAddress, port); -- // We want to handle a challenge string when the server responds. -- this._session.onBinaryDataReceived = -- this._onChallengeStringResponse.bind(this); -- }, -- -- _getLoginToken: function() { -- // TODO - Simplify this using map and join. -- let url = this._account._protocol.loginTokenGetUrl; -- url += "?src=ymsgr&"; -- url += "login=" + percentEncode(this._account.cleanUsername) + "&"; -- url += "passwd=" + percentEncode(this._account.imAccount.password) + "&"; -- url += "chal=" + percentEncode(this._challengeString); -- -- let options = { -- onLoad: this._onLoginTokenResponse.bind(this), -- onError: this._onHttpError.bind(this) -- } -- httpRequest(url, options); -- }, -- -- _getCookies: function() { -- // TODO - Simplify this using map and join. -- let url = this._account._protocol.loginTokenLoginUrl; -- url += "?src=ymsgr&"; -- url += "token=" + this._loginToken; -- -- let options = { -- onLoad: this._onLoginCookiesResponse.bind(this), -- onError: this._onHttpError.bind(this) -- } -- httpRequest(url, options); -- }, -- -- _sendPagerAuthResponse: function() { -- let response = this._calculatePagerResponse(); -- let packet = new YahooPacket(kPacketType.AuthResponse, 0, -- this._session.sessionId); -- // Build the key/value pairs. -- packet.addValue(1, this._account.cleanUsername); -- packet.addValue(0, this._account.cleanUsername); -- packet.addValue(277, this._session.yCookie); -- packet.addValue(278, this._session.tCookie); -- packet.addValue(307, response); -- packet.addValue(244, this._account.protocol.buildId); -- packet.addValue(2, this._account.cleanUsername); -- packet.addValue(2, "1"); -- packet.addValue(98, "us"); -- this._session.sendPacket(packet); -- // We want to handle a final login confirmation packet when the server -- // responds. -- this._session.onBinaryDataReceived = this._onFinalLoginResponse.bind(this); -- }, -- -- _calculatePagerResponse: function() { -- let hasher = Cc["@mozilla.org/security/hash;1"] -- .createInstance(Ci.nsICryptoHash); -- hasher.init(hasher.MD5); -- -- let crypt = this._crumb + this._challengeString; -- let cryptData = StringToBytes(crypt); -- hasher.update(cryptData, cryptData.length); -- -- // The protocol requires replacing + with ., / with _, and = with - within -- // the base64 response string. -- return btoa(hasher.finish(false)).replace(/+/g, ".").replace(///g, "_") -- .replace(/=/g, "-"); -- }, -- -- _handleLoginError: function(aErrorCode) { -- let errorInfo = kLoginStatusErrors[aErrorCode]; -- let errorMessage; -- let error; -- -- // If we find information on the error code we received, we will use that -- // information. If the error wasn't found in our error table, just throw a -- // generic error with the code included. -- if (errorInfo) { -- errorMessage = _("login.error." + errorInfo[0]); -- error = errorInfo[1]; -- } else { -- errorMessage = _("login.error.unknown", aErrorCode); -- error = Ci.prplIAccount.ERROR_OTHER_ERROR; -- // We also throw a console error because we didn't expect -- // this error code. -- this._account.ERROR("Received unknown error from pager server. Code: " + -- aErrorCode); -- } -- this._session.onSessionError(error, errorMessage); -- }, -- -- _onHttpError: function(aError, aStatusText, aXHR) { -- this._session.onSessionError(Ci.prplIAccount.NETWORK_ERROR, -- _("network.error.http")); -- }, -- -- // HTTP Response Callbacks. -- _onPagerAddressResponse: function(aResponse, aXHR) { -- this._session.pagerAddress = -- aResponse.substring(aResponse.lastIndexOf("=") + 1); -- this._getChallengeString(); -- }, -- -- _onLoginTokenResponse: function(aResponse, aXHR) { -- let responseParams = aResponse.split("\r\n"); -- // Status code "0" means success. -- let statusCode = responseParams[0]; -- if (statusCode != "0") { -- this._handleLoginError(statusCode); -- return; -- } -- -- this._loginToken = responseParams[1].replace("ymsgr=", ""); -- this._getCookies(); -- }, -- -- _onLoginCookiesResponse: function(aResponse, aXHR) { -- let responseParams = aResponse.split("\r\n"); -- // Status code "0" means success. -- let statusCode = responseParams[0]; -- if (statusCode != "0") { -- this._handleLoginError(statusCode); -- return; -- } -- -- this._crumb = responseParams[1].replace("crumb=", ""); -- // Remove the "Y=" bit. -- this._session.yCookie = responseParams[2].substring(2); -- // Remove the "T=" bit. -- this._session.tCookie = responseParams[3].substring(2); -- this._sendPagerAuthResponse(); -- }, -- -- // TCP Response Callbacks. -- _onChallengeStringResponse: function(aData) { -- let packet = new YahooPacket(); -- packet.fromArrayBuffer(aData); -- // The value of the challenge string is associated with key 94. -- this._challengeString = packet.getValue(94); -- this._session.sessionId = packet.sessionId; -- this._getLoginToken(); -- }, -- -- _onFinalLoginResponse: function(aData) { -- this._session.onLoginComplete(); -- // We need to restore data handling to the YahooSession object since our -- // login steps are complete. -- this._session.onBinaryDataReceived = -- YahooSession.prototype.onBinaryDataReceived.bind(this._session); -- } --}; -- --/* The YahooPacket class represents a single Yahoo! Messenger data packet. -- * Using this class allows you to easily create packets, stuff them with -- * required data, and convert them to/from ArrayBuffer objects. */ --function YahooPacket(aService, aStatus, aSessionId) --{ -- this.service = aService; -- this.status = aStatus; -- this.sessionId = aSessionId; -- this.keyValuePairs = []; --} --YahooPacket.prototype = { -- service: null, -- status: null, -- sessionId: null, -- keyValuePairs: null, -- -- // Public methods. -- -- // Add a single key/value pair. -- addValue: function(aKey, aValue) { -- let pair = { -- key: aKey.toString(), // The server handles keys as ASCII number values. -- value: aValue -- }; -- -- this.keyValuePairs.push(pair); -- }, -- -- // Add multiple key/value pairs with the same key but different values -- // stored in an array. -- addValues: function(aKey, aValues) { -- for each (let value in aValues) -- this.addValue(aKey, value); -- }, -- -- // This method returns the first value found with the given key. -- getValue: function(aKey) { -- for (let i = 0; i < this.keyValuePairs.length; ++i) { -- let pair = this.keyValuePairs[i]; -- // The server handles keys as ASCII number values. -- if (pair.key == aKey.toString()) -- return pair.value; -- } -- -- // Throw an error if the key wasn't found. -- throw "Required key " + aKey + " wasn't found. Packet Service: " + -- this.service.toString(16); -- }, -- -- // This method returns all of the values found with the given key. In some -- // packets, one key is associated with multiple values. If that is the case, -- // use this method to retrieve all of them instead of just the first one. -- getValues: function(aKey) { -- let values = []; -- for (let i = 0; i < this.keyValuePairs.length; ++i) { -- let pair = this.keyValuePairs[i]; -- // The server handles keys as ASCII number values. -- if (pair.key == aKey.toString()) -- values.push(pair.value); -- } -- -- // Throw an error if no keys were found. -- if (values.length == 0) { -- throw "Required key " + aKey + " wasn't found. Packet Service: " + -- this.service.toString(16); -- } -- return values; -- }, -- -- hasKey: function(aKey) { -- for (let i = 0; i < this.keyValuePairs.length; ++i) { -- // The server handles keys as ASCII number values. -- if (this.keyValuePairs[i].key == aKey.toString()) -- return true; -- } -- return false; -- }, -- -- toArrayBuffer: function() { -- let dataString = ""; -- for (let i = 0; i < this.keyValuePairs.length; ++i) { -- let pair = this.keyValuePairs[i]; -- dataString += pair.key + kPacketDataDelimiter; -- dataString += pair.value + kPacketDataDelimiter; -- } -- -- let packetLength = dataString.length; -- let buffer = new ArrayBuffer(kPacketHeaderSize + packetLength); -- -- // Build header. -- let view = new DataView(buffer); -- let idBytes = StringToBytes(kPacketIdentifier); -- view.setUint8(0, idBytes[0]); -- view.setUint8(1, idBytes[1]); -- view.setUint8(2, idBytes[2]); -- view.setUint8(3, idBytes[3]); -- view.setUint16(4, kProtocolVersion); -- view.setUint16(6, 0); // Vendor ID -- view.setUint16(8, packetLength); -- view.setUint16(10, this.service); -- view.setUint32(12, this.status); -- view.setUint32(16, this.sessionId); -- -- // Copy in data. -- copyBytes(buffer, BytesToArrayBuffer(StringToBytes(dataString)), kPacketHeaderSize); -- -- return buffer; -- }, -- -- fromArrayBuffer: function(aBuffer) { -- let view = new DataView(aBuffer); -- this.length = view.getUint16(8) + kPacketHeaderSize; -- this.service = view.getUint16(10); -- this.status = view.getUint32(12); -- this.sessionId = view.getUint32(16); -- -- let dataString = ArrayBufferToString(aBuffer).substring(kPacketHeaderSize); -- let delimitedData = dataString.split(kPacketDataDelimiter); -- // Since the data should also end with a trailing delmiter, split() will -- // add an empty element at the end. We need to pop this element off. -- delimitedData.pop(); -- -- // If we don't have an even number of delimitedData elements, that means -- // we are either missing a key or a value. -- if (delimitedData.length % 2 != 0) { -- throw "Odd number of data elements. Either a key or value is missing. " -- "Num of elements: " + delimitedData.length; -- } -- -- for (let i = 0; i < delimitedData.length; i += 2) { -- let key = delimitedData[i]; -- let value = delimitedData[i + 1]; -- if (key && value) { -- let pair = { -- key: key, -- value: value -- }; -- this.keyValuePairs.push(pair); -- } -- } -- }, -- -- toString: function() { -- // First, add packet header information. -- let s = "Service: 0x" + this.service.toString(16) + "\n"; -- s += "Status: 0x" + this.status.toString(16) + "\n"; -- s += "Session ID: 0x" + this.sessionId.toString(16); -- // Now we add the packet data, if there is some. -- if (this.keyValuePairs.length) { -- // Add two preceding newlines for space to make reading easier. -- s += "\n\nPacket Key-Value Data:\n"; -- for each (let pair in this.keyValuePairs) -- s += pair.key + ":\t" + pair.value + "\n"; -- } -- return s; -- } --}; --YahooPacket.extractPackets = function(aData, aOnNetworkError) { -- let packets = []; -- let bytesHandled = 0; -- -- while (aData.byteLength >= kPacketHeaderSize) { -- if (ArrayBufferToString(aData.slice(0, kPacketIdentifier.length)) != -- kPacketIdentifier) { -- throw "Malformed packet received. Packet content: " + -- ArrayBufferToHexString(aData); -- } -- -- let packetView = new DataView(aData); -- let packetLength = packetView.getUint16(8) + kPacketHeaderSize; -- // Don't process half packets. -- if (packetLength > aData.byteLength) -- break; -- let packet = new YahooPacket(); -- packet.fromArrayBuffer(aData.slice(0, packetLength)); -- packets.push(packet); -- bytesHandled += packetLength; -- aData = aData.slice(packetLength); -- } -- return [packets, bytesHandled]; --} -- --/* In YahooPacketHandler, each handler function is assosiated with a packet -- * service number. You can use the kPacketType enumeration to understand -- * what kind of packet each number is linked to. -- * -- * Keep in mind too that "this" in each function will be bound to a -- * YahooAccount object, since they are all invoked using call(). */ --var YahooPacketHandler = { -- // Buddy logoff. -- 0x02: function(aPacket) { -- let name = aPacket.getValue(7); -- this.setBuddyStatus(name, Ci.imIStatusInfo.STATUS_OFFLINE, ""); -- }, -- -- // Incoming chat message. -- 0x06: function(aPacket) { -- let from = aPacket.getValue(4); -- let to = aPacket.getValue(5); -- let message = aPacket.getValue(14); -- this.receiveMessage(from, message); -- -- // The official Yahoo! Messenger desktop client requires message ACKs to be -- // sent back to the server. The web client doesn't require this. A good -- // indication of when an ACK is required is when key 429 is sent, which -- // contains the ID of the message. When a message is sent from the official -- // desktop client, and no ACK is sent back, the message is resent seconds -- // later. -- if (aPacket.hasKey(429)) { -- let messageId = aPacket.getValue(429); -- let packet = new YahooPacket(kPacketType.MessageAck, 0, aPacket.sessionId); -- // Some keys have an unknown purpose, so we set a constant value. -- packet.addValue(1, to); -- packet.addValue(5, from); -- packet.addValue(302, "430"); -- packet.addValue(430, messageId); -- packet.addValue(303, 430); -- packet.addValue(450, 0); -- this._session.sendPacket(packet); -- } -- }, -- -- // New mail notification. -- // TODO: Implement this handler when mail notifications are handled in the -- // base code. -- 0x0b: function(aPacket) {}, -- -- // Server ping. -- // TODO: Add support for ping replies. -- 0x12: function(aPacket) {}, -- -- // Conference invitation. -- 0x18: function(aPacket) { -- let owner = aPacket.getValue(50); -- let roomName = aPacket.getValue(57); -- let participants = aPacket.getValues(53); -- // The owner is also a participant. -- participants.push(owner); -- let message = aPacket.getValue(58); -- this.receiveConferenceInvite(owner, roomName, participants, message); -- }, -- -- // Conference logon. -- 0x19: function(aPacket) { -- let userName = aPacket.getValue(53); -- let room = aPacket.getValue(57); -- this.receiveConferenceLogon(room, userName); -- }, -- -- // Conference logoff -- 0x1b: function(aPacket) { -- let userName = aPacket.getValue(56); -- let roomName = aPacket.getValue(57); -- this.receiveConferenceLogoff(roomName, userName); -- }, -- -- // Conference additional invitation. NOTE: Since this packet has the same -- // structure as the normal conference invite (packet 0x18), we simply -- // reuse that handler. -- 0x1c: function(aPacket) { return YahooPacketHandler[0x18].call(this, aPacket); }, -- -- // Conference message. -- 0x1d: function(aPacket) { -- let from = aPacket.getValue(3); -- let room = aPacket.getValue(57); -- let message = aPacket.getValue(14); -- this.receiveConferenceMessage(from, room, message); -- }, -- -- // Typing notification. -- 0x4b: function(aPacket) { -- let name = aPacket.getValue(4); -- let isTyping = (aPacket.getValue(13) == "1"); -- this.receiveTypingNotification(name, isTyping); -- }, -- -- // Legacy Yahoo! buddy list. Packet 0xf1 has replaced this. -- 0x55: function(aPacket) {}, -- -- // Authentication acknowledgement. We can ignore this since we are known -- // to be authenticated if we are receiving other packets anyway. -- 0x57: function(aPacket) {}, -- -- // AddBuddy ack packets can be ignored. They do not depend on whether or not -- // the buddy accepted the invite. -- 0x83: function(aPacket) {}, -- -- // RemoveBuddy ack packets let us know when we should actually remove the -- // buddy from the list, keeping us in sync with the server. -- 0x84: function(aPacket) { -- let buddy = this.getBuddy(aPacket.getValue(7)); -- // The buddy is off the server, so remove it locally. -- this.removeBuddy(buddy, false); -- }, -- -- // Picture upload. -- 0xc2: function(aPacket) { -- let onlineBuddies = this.getOnlineBuddies(); -- // Send a notification to each online buddy that your icon has changed. -- // Those offline will automatically pick up the change when they log in. -- for each (let buddy in onlineBuddies) { -- let packet = new YahooPacket(kPacketType.AvatarUpdate, 0, -- this._session.sessionId); -- packet.addValue(3, buddy.userName); -- packet.addValue(213, 2); // A value of 2 means we are using an icon. -- this._session.sendPacket(packet); -- } -- }, -- -- // Buddy icon checksum. -- // TODO - Make use of the icon checksum to allow icon caching. -- 0xbd: function(aPacket) { -- // Extract the checksum from the URL parameter chksum. -- let buddyName = aPacket.getValue(4); -- let url = aPacket.getValue(20); -- let parameter = "chksum="; -- // The "chksum" parameter is the only parameter in the URL. -- let checksum = url.substring(url.indexOf(parameter) + parameter.length); -- -- let buddy = this.getBuddy(buddyName); -- // We only download the new icon if no older checksum exists, or if the -- // older checksum differs, indicating an updated icon. -- if (buddy && buddy.iconChecksum !== checksum) { -- buddy.buddyIconFilename = url; -- buddy.iconChecksum = checksum; -- } -- }, -- -- // Buddy icon request reply. This can be handled in the same way as a buddy -- // icon checksum packet, so we simply reuse the handler. -- 0xbe: function (aPacket) { return YahooPacketHandler[0xbd].call(this, aPacket); }, -- -- // Buddy status update. -- 0xc6: function (aPacket) { -- let name = aPacket.getValue(7); -- // If the user is mobile, use the mobile status. -- let status = aPacket.hasKey(60) ? Ci.imIStatusInfo.STATUS_MOBILE : -- kBuddyStatuses[aPacket.getValue(10)]; -- -- let message = aPacket.hasKey(19) ? aPacket.getValue(19) : ""; -- this.setBuddyStatus(name, status, message); -- }, -- -- // Buddy avatar (icon) update. -- 0xc7: function(aPacket) { -- // Strangely, in some non-official clients, when someone updates their -- // profile icon we are sent two avatar update packets: one with a default -- // status containing little information, and another with a Server Ack -- // status containing the info we need. So we only accept packets with a -- // Server Ack status to prevent errors. -- if (aPacket.status != kPacketStatuses.ServerAck) -- return; -- // Key 4 contains the name of the buddy who updated their icon. -- this._session.requestBuddyIcon(aPacket.getValue(4)); -- }, -- -- // Buddy authorization request. -- 0xd6: function(aPacket) { -- // Whenever we authorize someone to be our buddy, the server will send an -- // acknowledgement packet. We ignore the ack to prevent the auth request -- // from showing again. -- if (aPacket.status == kPacketStatuses.ServerAck) -- return; -- -- let session = this._session; -- let userName = aPacket.getValue(4); -- this.addBuddyRequest(userName, session.acceptBuddyRequest.bind(session), -- session.denyBuddyRequest.bind(session)); -- }, -- -- // XXX: What does this packet do? -- 0xef: function(aPacket) {}, -- -- // Initial user status. -- 0xf0: function (aPacket) { -- // Return early if we find no buddy names. -- if (!aPacket.hasKey(7)) -- return; -- -- // The key/value pairs are in order as sent by the server. So we must -- // iterate though them to find out information about each buddy. Each -- // buddy section starts with key 7. -- let currentBuddy; -- for (let i = 0; i < aPacket.keyValuePairs.length; ++i) { -- let {key: key, value: value} = aPacket.keyValuePairs[i]; -- -- if (key == 7) { // Buddy name. -- currentBuddyName = value; -- this._session.requestBuddyIcon(currentBuddyName); -- } else if (key == 10) // Buddy status. -- this.setBuddyStatus(currentBuddyName, kBuddyStatuses[value]); -- else if (key == 19) // Buddy status message. -- this.setBuddyStatus(currentBuddyName, undefined, value); -- else if (key == 60) // Mobile status. -- this.setBuddyStatus(currentBuddyName, Ci.imIStatus.STATUS_MOBILE); -- } -- }, -- -- // Friends and groups list. -- 0xf1: function(aPacket) { -- let tagName = ""; -- for each (let pair in aPacket.keyValuePairs) { -- if (pair.key == "65") -- tagName = pair.value; -- else if (pair.key == "7") { -- let buddyName = pair.value; -- this.addBuddyFromServer(Services.tags.createTag(tagName), buddyName); -- } -- } -- } --}; -- --/* The YahooProfileIconUploader class is specifically designed to set a profile -- * image on a Yahoo! Messenger account. The reason this functionality is split -- * into a separate class is because of the complexity of the operation. Because -- * of special protocol requirements, it is easier to use raw TCP communication -- * instead of the httpRequest() method. */ --function YahooProfileIconUploader(aAccount, aSession, aFileName, aImage) --{ -- this._account = aAccount; -- this._session = aSession; -- this._fileName = aFileName; -- this._image = aImage; --} --YahooProfileIconUploader.prototype = { -- __proto__: Socket, -- _account: null, -- _session: null, -- _fileName: null, -- _image: null, -- _host: null, -- _port: null, -- -- uploadIcon: function() { -- // Connect to the file transfer server, and the onConnection callback -- // will do the rest. -- this.connect(kFileTransferHost, kFileTransferPort); -- }, -- -- // Socket callbacks. -- onConnection: function() { -- // Scale the image down, and make it a PNG. Icon widths are constant, but -- // their height varies depending on the aspect ratio of the original image. -- let aspectRatio = this._image.width / this._image.height; -- let scaledHeight = kProfileIconWidth / aspectRatio; -- let scaledImage = imgTools.encodeScaledImage(this._image, "image/png", -- kProfileIconWidth, -- scaledHeight); -- let imageData = NetUtil.readInputStreamToString(scaledImage, -- scaledImage.available()); -- -- // Build the Yahoo packet. -- let packet = new YahooPacket(kPacketType.Picture, 0, this.sessionId); -- packet.addValue(1, this._account.cleanUsername); -- // TODO - Look into how expiration time works for profile icons, and its -- // purpose. We aren't sure if this refers to seconds, days, years, etc. -- packet.addValue(38, "604800"); // Expiration time. -- packet.addValue(0, this._account.cleanUsername); -- packet.addValue(28, imageData.length); // Picture size in bytes. -- packet.addValue(27, this._fileName); // Picture filename. -- packet.addValue(14, ""); // Null string. -- let packetBuffer = packet.toArrayBuffer(); -- -- // Build the request header. -- let headers = [ -- ["User-Agent", "Mozilla/5.0"], -- ["Cookie", "T=" + this._session.tCookie + "; Y=" + this._session.yCookie], -- ["Host", kFileTransferHost + ":" + kFileTransferPort], -- ["Content-Length", packetBuffer.byteLength + 4 + imageData.length], -- ["Cache-Control", "no-cache"], -- ]; -- let headerString = "POST /notifyft HTTP/1.1\r\n"; -- headers.forEach(function(header) { -- headerString += header[0] + ": " + header[1] + "\r\n"; -- }); -- -- // The POST request uses a special delimeter between the end of the included -- // Yahoo binary packet, and the image data. -- let requestPacketEnd = "29" + kPacketDataDelimiter; -- // Build the complete POST request data. -- let requestData = headerString + "\r\n" + -- ArrayBufferToString(packetBuffer) + requestPacketEnd + -- imageData; -- this.sendData(requestData); -- } --}; -diff --git a/chat/protocols/yahoo/yahoo.js b/chat/protocols/yahoo/yahoo.js -index 8beadb504..86a258969 100644 ---- a/chat/protocols/yahoo/yahoo.js -+++ b/chat/protocols/yahoo/yahoo.js -@@ -2,575 +2,39 @@ - * 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/. */ - --var {classes: Cc, interfaces: Ci, utils: Cu} = Components; -+var {interfaces: Ci, utils: Cu} = Components; - --Cu.import("resource:///modules/imServices.jsm"); - Cu.import("resource:///modules/imXPCOMUtils.jsm"); - Cu.import("resource:///modules/jsProtoHelper.jsm"); --Cu.import("resource:///modules/yahoo-session.jsm"); - - XPCOMUtils.defineLazyGetter(this, "_", () => - l10nHelper("chrome://chat/locale/yahoo.properties") - ); - --// These timeouts are in milliseconds. --var kKeepAliveTimeout = 60 * 1000; // One minute. --var kPingTimeout = 3600 * 1000; // One hour. -- --function YahooConversation(aAccount, aName) --{ -- this._buddyUserName = aName; -- this._account = aAccount; -- this.buddy = aAccount.getBuddy(aName); -- this._init(aAccount); --} --YahooConversation.prototype = { -- __proto__: GenericConvIMPrototype, -- _account: null, -- _buddyUserName: null, -- _typingTimer: null, -- -- close: function() { -- this._account.deleteConversation(this._buddyUserName); -- GenericConvChatPrototype.close.call(this); -- }, -- -- sendMsg: function (aMsg) { -- // Deliver the message, then write it to the window. -- this._account._session.sendChatMessage(this._buddyUserName, -- this._account.encodeMessage(aMsg)); -- this.finishedComposing(); -- this.writeMessage(this._account.cleanUsername, aMsg, -- {outgoing: true, _alias: this._account.imAccount.alias}); -- }, -- -- sendTyping: function(aString) { -- if (aString.length) { -- if (!this._typingTimer) -- this._account._session.sendTypingStatus(this._buddyUserName, true); -- this._refreshTypingTimer(); -- } -- return Ci.prplIConversation.NO_TYPING_LIMIT; -- }, -- -- finishedComposing: function() { -- this._account._session.sendTypingStatus(this._buddyUserName, false); -- this._cancelTypingTimer(); -- }, -- -- _refreshTypingTimer: function() { -- this._cancelTypingTimer(); -- this._typingTimer = setTimeout(this.finishedComposing.bind(this), 10000); -- }, -- -- _cancelTypingTimer: function() { -- if (!this._typingTimer) -- return; -- clearTimeout(this._typingTimer); -- delete this._typingTimer -- this._typingTimer = null; -- }, -- -- get name() { return this._buddyUserName; } --}; -- --function YahooConference(aAccount, aRoom, aOwner) --{ -- this._account = aAccount; -- this._roomName = aRoom; -- this._owner = aOwner; -- this._init(aAccount, aRoom, aAccount.cleanUsername); --} --YahooConference.prototype = { -- __proto__: GenericConvChatPrototype, -- _account: null, -- _roomName: null, -- _owner: null, -- -- close: function() { -- this.reportLogoff(); -- this._account.deleteConference(this._roomName); -- GenericConvChatPrototype.close.call(this); -- }, -- -- reportLogoff: function() { -- if (this.left) -- return; -- this._account._session.sendConferenceLogoff(this._account.cleanUsername, -- this.getParticipantNames(), -- this._roomName); -- this.left = true; -- }, -- -- sendMsg: function(aMsg) { -- this._account._session.sendConferenceMessage(this.getParticipantNames(), -- this._roomName, -- this._account.encodeMessage(aMsg)); -- }, -- -- addParticipant: function(aName) { -- // In case we receive multiple conference logon packets, prevent adding -- // duplicate buddies. -- if (this._participants.get(aName)) -- return; -- let buddy = new YahooConferenceBuddy(aName, this); -- this._participants.set(aName, buddy); -- this.notifyObservers(new nsSimpleEnumerator([buddy]), "chat-buddy-add"); -- this.writeMessage(this._roomName, -- _("system.message.conferenceLogon", aName), -- {system: true}); -- }, -- -- getParticipantNames: function() { return [for (p of this._participants.values()) p.name]; } --}; -- --function YahooConferenceBuddy(aName, aConference) --{ -- this._name = aName; -- this._conference = aConference; --} --YahooConferenceBuddy.prototype = { -- __proto__: GenericConvChatBuddyPrototype, -- _conference: null, -- -- get founder() { return this._conference._owner == this._name; } --}; -- --function YahooAccountBuddy(aAccount, aBuddy, aTag, aUserName) --{ -- this._init(aAccount, aBuddy, aTag, aUserName); --} --YahooAccountBuddy.prototype = { -- __proto__: GenericAccountBuddyPrototype, -- iconChecksum: null, -- -- // This removes the buddy locally, and from the Yahoo! servers. -- remove: function() { return this._account.removeBuddy(this, true); }, -- // This removes the buddy locally, but keeps him on the servers. -- removeLocal: function() { return this._account.removeBuddy(this, false); }, -- createConversation: function() { return this._account.createConversation(this.userName); } --} -- - function YahooAccount(aProtoInstance, aImAccount) - { - this._init(aProtoInstance, aImAccount); -- this._buddies = new Map(); -- this._conversations = new Map(); -- this._conferences = new Map(); -- this._protocol = aProtoInstance; -- this._converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"] -- .createInstance(Ci.nsIScriptableUnicodeConverter); -- this._converter.charset = this.getString("local_charset") || "UTF-8"; -- -- // The username stripped of any @yahoo.* domain. -- this.cleanUsername = this.name.replace(/@yahoo..+$/, ""); - } - YahooAccount.prototype = { - __proto__: GenericAccountPrototype, -- // YahooSession object passed in constructor. -- _session: null, -- // A Map holding the list of buddies associated with their usernames. -- _buddies: null, -- // A Map holding the list of open buddy conversations associated with the -- // username of the buddy. -- _conversations: null, -- // A Map holding the list of open conference rooms associated with the room -- // name. -- _conferences: null, -- // YahooProtocol object passed in the constructor. -- _protocol: null, -- // An nsIScriptableUnicodeConverter used to convert incoming/outgoing chat -- // messages to the correct charset. -- _converter: null, -- // This is simply incremented by one everytime a new conference room is -- // created. It is appened to the end of the room name when a new room is -- // created, ensuring name uniqueness. -- _roomsCreated: 0, -- // The username stripped of any @yahoo.* domain. -- cleanUsername: null, -- // The timers used to send keepalive and ping packets to the server to ensrue -- // the server that the user is still connected. -- _keepAliveTimer: null, -- _pingTimer: null, - - connect: function() { -- this._session = new YahooSession(this); -- this._session.login(this.imAccount.name, this.imAccount.password); -- }, -- -- disconnect: function(aSilent) { -- // Log out of all of the conferences the user is in. -- for (let conf of this._conferences) -- conf[1].reportLogoff(); -- -- if (this.connected) { -- this.reportDisconnecting(Ci.prplIAccount.NO_ERROR, ""); -- if (this._session.isConnected) -- this._session.disconnect(); -- this.reportDisconnected(); -- } -- // buddy[1] is the actual object. -- for (let buddy of this._buddies) -- buddy[1].setStatus(Ci.imIStatusInfo.STATUS_UNKNOWN, ""); -- -- // Clear and delete the timers to avoid memory leaks. -- if (this._keepAliveTimer) { -- this._keepAliveTimer.cancel(); -- delete this._keepAliveTimer; -- } -- -- if (this._pingTimer) { -- this._pingTimer.cancel(); -- delete this._pingTimer; -- } -- }, -- -- observe: function(aSubject, aTopic, aData) { -- if (aTopic == "status-changed") -- this._session.setStatus(aSubject.statusType, aData); -- else if (aTopic == "user-icon-changed") -- this._session.setProfileIcon(aData); -- }, -- -- remove: function() { -- for each(let conv in this._conversations) -- conv.close(); -- delete this._conversations; -- for (let buddy of this._buddies) -- buddy[1].removeLocal(); // buddy[1] is the actual object. -- }, -- -- unInit: function() { -- this.disconnect(true); -- delete this.imAccount; -- }, -- -- createConversation: function(aName) { -- let conv = new YahooConversation(this, aName); -- this._conversations.set(aName, conv); -- return conv; -- }, -- -- deleteConversation: function(aName) { -- if (this._conversations.has(aName)) -- this._conversations.delete(aName); -- }, -- -- receiveConferenceInvite: function(aOwner, aRoom, aParticipants, aMessage) { -- // Do nothing if we wish to ignore invites. -- if (!Services.prefs.getIntPref("messenger.conversations.autoAcceptChatInvitations") || -- this.getBool("ignore_invites")) -- return; -- -- let conf = new YahooConference(this, aRoom, aOwner); -- this._conferences.set(aRoom, conf); -- -- for each (let participant in aParticipants) -- conf.addParticipant(participant); -- -- // Add ourselves to the conference room as well. -- conf.addParticipant(this.imAccount.name); -- -- this._session.acceptConferenceInvite(aOwner, aRoom, -- conf.getParticipantNames()); -- }, -- -- receiveConferenceLogon: function(aRoom, aUsername) { -- if (!this._conferences.has(aRoom)) -- return; -- let conf = this._conferences.get(aRoom); -- conf.addParticipant(aUsername); -- }, -- -- receiveConferenceLogoff: function(aRoom, aUsername) { -- if (!this._conferences.has(aRoom)) -- return; -- let conf = this._conferences.get(aRoom); -- conf.removeParticipant(aUsername); -- conf.writeMessage(this._roomName, -- _("system.message.conferenceLogoff", aName), -- {system: true}); -- }, -- -- deleteConference: function(aName) { -- if (this._conferences.has(aName)) -- this._conferences.delete(aName); -- }, -- -- // Called when the user adds or authorizes a new contact. -- addBuddy: function(aTag, aName) { -- let buddy = new YahooAccountBuddy(this, null, aTag, aName); -- this._buddies.set(buddy.userName, buddy); -- this._session.addBuddyToServer(buddy); -- Services.contacts.accountBuddyAdded(buddy); -- }, -- -- hasBuddy: function(aName) { -- return this._buddies.has(aName); -- }, -- -- // Called for each buddy that is sent in a list packet from Yahoo! on login. -- addBuddyFromServer: function(aTag, aName) { -- let buddy; -- if (this._buddies.has(aName)) -- buddy = this._buddies.get(aName); -- else { -- buddy = new YahooAccountBuddy(this, null, aTag, aName); -- Services.contacts.accountBuddyAdded(buddy); -- this._buddies.set(aName, buddy); -- } -- -- // Set all new buddies as offline because a following status packet will -- // tell their status if they are online. -- buddy.setStatus(Ci.imIStatusInfo.STATUS_OFFLINE, ""); -- -- // Request the buddy's picture. -- this._session.requestBuddyIcon(aName); -- }, -- -- // Called when a user removes a contact from within Instantbird. -- removeBuddy: function(aBuddy, aRemoveFromServer) { -- if (aRemoveFromServer) { -- // We will remove the buddy locally when we get a server ack packet. -- this._session.removeBuddyFromServer(aBuddy); -- return; -- } -- -- this._buddies.delete(aBuddy.userName); -- Services.contacts.accountBuddyRemoved(aBuddy); -- }, -- -- loadBuddy: function(aBuddy, aTag) { -- let buddy = new YahooAccountBuddy(this, aBuddy, aTag); -- this._buddies.set(buddy.userName, buddy); -- -- return buddy; -- }, -- -- // Both the status and message can be defined, or only one can be defined. -- // When defining just the message, set aStatus to undefined. -- setBuddyStatus: function(aName, aStatus, aMessage) { -- if (!this._buddies.has(aName)) -- return; -- let buddy = this._buddies.get(aName); -- // If the message is set as undefined, use the existing message. -- if (aMessage === undefined) -- aMessage = buddy.statusText; -- // If the status is undefined, use the existing status. -- if (aStatus === undefined) -- aStatus = buddy.statusType; -- buddy.setStatus(aStatus, aMessage); -- }, -- -- getBuddy: function(aName) { -- if (this._buddies.has(aName)) -- return this._buddies.get(aName); -- return null; -- }, -- -- getOnlineBuddies: function() { -- let onlineBuddies = []; -- for (let buddy of this._buddies) { -- if (buddy[1].statusType != Ci.imIStatusInfo.STATUS_OFFLINE) -- onlineBuddies.push(buddy[1]); -- } -- return onlineBuddies; -- }, -- -- receiveMessage: function(aName, aMessage) { -- let conv; -- // Check if we have an existing converstaion open with this user. If not, -- // create one and add it to the list. -- if (!this._conversations.has(aName)) -- conv = this.createConversation(aName); -- else -- conv = this._conversations.get(aName); -- -- // Certain Yahoo clients, such as the official web client, sends formatted -- // messages, but the size value is the actual pt size, not the 1 - 7 size -- // expected from the HTML <font> tag. We replace it with the correct size. -- let message = this.decodeMessage(aMessage) -- .replace(/(<font[^>]+)size="(\d+)"/g, this._fixFontSize); -- -- conv.writeMessage(aName, message, {incoming: true}); -- conv.updateTyping(Ci.prplIConvIM.NOT_TYPING, conv.name); -- }, -- -- receiveConferenceMessage: function(aName, aRoom, aMessage) { -- if (!this._conferences.has(aRoom)) -- return; -- -- this._conferences.get(aRoom).writeMessage(aName, -- this.decodeMessage(aMessage), -- {incoming: true}); -- }, -- -- receiveTypingNotification: function(aName, aIsTyping) { -- if (!this._conversations.has(aName)) -- return; -- -- let conv = this._conversations.get(aName); -- if (aIsTyping) -- conv.updateTyping(Ci.prplIConvIM.TYPING, conv.name); -- else -- conv.updateTyping(Ci.prplIConvIM.NOT_TYPING, conv.name); -- }, -- -- encodeMessage: function(aMessage) { -- // Try to perform a convertion from JavaScript UTF-16 into the charset -- // specified in the options. If the conversion fails, just leave -- // the message as it is. -- let encodedMsg; -- try { -- encodedMsg = this._converter.ConvertFromUnicode(aMessage); -- } catch (e) { -- encodedMsg = aMessage; -- this.WARN("Could not encode UTF-16 message into " + -- this._converter.charset + ". Message: " + aMessage); -- } -- return encodedMsg; -- }, -- -- decodeMessage: function(aMessage) { -- // Try to perform a convertion from the charset specified in the options -- // to JavaScript UTF-16. If the conversion fails, just leave the message -- // as it is. -- let decodedMsg; -- try { -- decodedMsg = this._converter.ConvertToUnicode(aMessage); -- } catch (e) { -- decodedMsg = aMessage; -- this.WARN("Could not decode " + this._converter.charset + -- " message into UTF-16. Message: " + aMessage); -- } -- return decodedMsg; -- }, -- -- get canJoinChat() { return true; }, -- chatRoomFields: {}, -- joinChat: function(aComponents) { -- // Use _roomsCreated to append a unique number to the room name. -- let roomName = this.cleanUsername + "-" + ++this._roomsCreated; -- let conf = new YahooConference(this, roomName, this.cleanUsername); -- this._conferences.set(roomName, conf); -- this._session.createConference(roomName); -- }, -- -- // Callbacks. -- onLoginComplete: function() { -- // Now that we are connected, get ready to start to sending pings and -- // keepalive packets. -- this._keepAliveTimer = Cc["@mozilla.org/timer;1"] -- .createInstance(Ci.nsITimer); -- this._pingTimer = Cc["@mozilla.org/timer;1"] -- .createInstance(Ci.nsITimer); -- -- // We use slack timers since we don't need millisecond precision when -- // sending the keepalive and ping packets. -- let s = this._session; -- this._keepAliveTimer -- .initWithCallback(s.sendKeepAlive.bind(s), kKeepAliveTimeout, -- this._keepAliveTimer.TYPE_REPEATING_SLACK); -- -- this._pingTimer -- .initWithCallback(s.sendPing.bind(s), kPingTimeout, -- this._pingTimer.TYPE_REPEATING_SLACK); -- -- }, -- -- // Private methods. -- -- // This method is used to fix font sizes given by formatted messages. This -- // method is designed to be used as a method for a string replace() call. -- _fixFontSize: function(aMatch, aTagAttributes, aFontSize, aOffset, aString) { -- // Approximate the font size. -- let newSize; -- if (aFontSize <= 8) -- newSize = "1"; -- else if (aFontSize <= 10) -- newSize = "2"; -- else if (aFontSize <= 12) -- newSize = "3"; -- else if (aFontSize <= 14) -- newSize = "4"; -- else if (aFontSize <= 20) -- newSize = "5"; -- else if (aFontSize <= 30) -- newSize = "6"; -- else if (aFontSize <= 40) -- newSize = "7"; -- else // If we get some gigantic size, just default to the standard 3 size. -- newSize = "3"; -- -- let sizeAttribute = "size="" + newSize + """; -- // We keep any preceding attributes, but replace the size attribute. -- return aTagAttributes + sizeAttribute; -+ this.WARN("The legacy versions of Yahoo Messenger was disabled on August " + -+ "5, 2016. It is currently not possible to connect to Yahoo " + -+ "Messenger. See bug 1316000"); -+ this.reportDisconnecting(Ci.prplIAccount.ERROR_OTHER_ERROR, -+ _("yahoo.disabled")); -+ this.reportDisconnected(); - } - }; - --function YahooProtocol() { -- this.registerCommands(); --} -+function YahooProtocol() {} - YahooProtocol.prototype = { - __proto__: GenericProtocolPrototype, -- // Protocol specific connection parameters. -- pagerRequestUrl: "http://scsa.msg.yahoo.com/capacity", -- loginTokenGetUrl: "https://login.yahoo.com/config/pwtoken_get", -- loginTokenLoginUrl: "https://login.yahoo.com/config/pwtoken_login", -- buildId: "4194239", - - get id() { return "prpl-yahoo"; }, - get name() { return "Yahoo"; }, - get iconBaseURI() { return "chrome://prpl-yahoo/skin/"; }, -- options: { -- port: {get label() { return _("options.pagerPort"); }, default: 5050}, -- local_charset: {get label() { return _("options.chatEncoding"); }, default: "UTF-8"}, -- ignore_invites: {get label() { return _("options.ignoreInvites"); }, default: false} -- }, -- commands: [ -- { -- name: "invite", -- get helpString() { return _("command.help.invite2", "invite"); }, -- usageContext: Ci.imICommand.CMD_CONTEXT_ALL, -- run: function(aMsg, aConv) { -- if (aMsg.trim().length == 0) -- return false; -- -- let splitPosition = aMsg.indexOf(" "); // Split at first space. -- let invitees; -- let message; -- -- // If we have an invite message. -- if (splitPosition > 0) { -- invitees = aMsg.substring(0, splitPosition).split(","); -- message = aMsg.substring(splitPosition); -- } else { -- invitees = aMsg.split(","); -- message = _("conference.invite.message"); // Use default message. -- } -- -- let conf = aConv.wrappedJSObject; -- conf._account._session.inviteToConference(invitees, conf._roomName, -- conf.getParticipantNames(), -- message); -- conf.writeMessage(conf._roomName, -- _("command.feedback.invite", invitees.join(", ")), -- {system: true, noLog: true}); -- conf._account.LOG("Sending conference invite to " + invitees); -- return true; -- }, -- }, -- -- { -- name: "conference", -- get helpString() { return _("command.help.conference", "conference"); }, -- usageContext: Ci.imICommand.CMD_CONTEXT_CHAT, -- run: function(aMsg, aConv) { -- aConv.account.joinChat(null); -- return true; -- } -- } -- ], - getAccount: function(aImAccount) { return new YahooAccount(this, aImAccount); }, - classID: Components.ID("{50ea817e-5d79-4657-91ae-aa0a52bdb98c}") - }; -diff --git a/im/content/conversation.xml b/im/content/conversation.xml -index 6f00c8d39..c93dab00f 100644 ---- a/im/content/conversation.xml -+++ b/im/content/conversation.xml -@@ -342,8 +342,7 @@ - msg = "<font face="" + style.fontFamily + "">" + msg + "</font>"; - // MSN doesn't support font size info in messages... - } -- else if (proto == "prpl-aim" || proto == "prpl-icq" || -- proto == "prpl-yahoo" || proto == "prpl-yahoojp") { -+ else if (proto == "prpl-aim" || proto == "prpl-icq") { - let styleAttributes = "" - if ("color" in style) - styleAttributes += " color="" + style.color + """; -diff --git a/im/locales/en-US/chrome/instantbird/accountWizard.properties b/im/locales/en-US/chrome/instantbird/accountWizard.properties -index 7d371bd21..1d6fd48e1 100644 ---- a/im/locales/en-US/chrome/instantbird/accountWizard.properties -+++ b/im/locales/en-US/chrome/instantbird/accountWizard.properties -@@ -14,9 +14,8 @@ topProtocol.list=prpl-irc,prpl-jabber,prpl-twitter,prpl-gtalk - # 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 --topProtocol.prpl-yahoo.description=Chat with friends using Yahoo! Messenger - topProtocol.prpl-irc.description=Join IRC channels -+topProtocol.prpl-jabber.description=Chat using the open Jabber/XMPP protocol -diff --git a/im/test/xpcshell.ini b/im/test/xpcshell.ini -index 5f7dd70fc..578122a2a 100644 ---- a/im/test/xpcshell.ini -+++ b/im/test/xpcshell.ini -@@ -6,5 +6,4 @@ - [include:chat/components/src/test/xpcshell.ini] - [include:chat/protocols/irc/test/xpcshell.ini] - [include:chat/protocols/skype/test/xpcshell.ini] --[include:chat/protocols/yahoo/test/xpcshell.ini] - #[include:extensions/purple/purplexpcom/src/test/xpcshell.ini] -diff --git a/mail/components/im/content/imconversation.xml b/mail/components/im/content/imconversation.xml -index 16c665ab4..a4b9fc638 100644 ---- a/mail/components/im/content/imconversation.xml -+++ b/mail/components/im/content/imconversation.xml -@@ -285,8 +285,7 @@ - msg = "<font face="" + style.fontFamily + "">" + msg + "</font>"; - // MSN doesn't support font size info in messages... - } -- else if (proto == "prpl-aim" || proto == "prpl-icq" || -- proto == "prpl-yahoo" || proto == "prpl-yahoojp") { -+ else if (proto == "prpl-aim" || proto == "prpl-icq") { - let styleAttributes = "" - if ("color" in style) - styleAttributes += " color="" + style.color + """; --- -2.11.0 - diff --git a/projects/instantbird/0025-Bug-1321641-Use-built-in-functions-instead-of-an-svg.patch b/projects/instantbird/0025-Bug-1321641-Use-built-in-functions-instead-of-an-svg.patch new file mode 100644 index 0000000..0a7172b --- /dev/null +++ b/projects/instantbird/0025-Bug-1321641-Use-built-in-functions-instead-of-an-svg.patch @@ -0,0 +1,57 @@ +From 4b7b7f09dab1b90af3073304d8bcfa529ac1183b Mon Sep 17 00:00:00 2001 +From: Arlo Breault arlolra@gmail.com +Date: Thu, 1 Dec 2016 13:25:42 -0800 +Subject: [PATCH 25/26] Bug 1321641 - Use built-in functions instead of an svg + for bubbles filter + +--- + im/themes/jar.mn | 1 - + im/themes/messages/bubbles/bubbles.svg | 10 ---------- + im/themes/messages/bubbles/main.css | 2 +- + 3 files changed, 1 insertion(+), 12 deletions(-) + delete mode 100644 im/themes/messages/bubbles/bubbles.svg + +diff --git a/im/themes/jar.mn b/im/themes/jar.mn +index e422619d4..e39f5dcd8 100644 +--- a/im/themes/jar.mn ++++ b/im/themes/jar.mn +@@ -268,7 +268,6 @@ instantbird.jar: + skin/classic/instantbird/messages/bubbles/Bitmaps/minus.png (messages/bubbles/Bitmaps/minus.png) + skin/classic/instantbird/messages/bubbles/Bitmaps/plus-hover.png (messages/bubbles/Bitmaps/plus-hover.png) + skin/classic/instantbird/messages/bubbles/Bitmaps/plus.png (messages/bubbles/Bitmaps/plus.png) +- skin/classic/instantbird/messages/bubbles/bubbles.svg (messages/bubbles/bubbles.svg) + skin/classic/instantbird/messages/bubbles/Footer.html (messages/bubbles/Footer.html) + skin/classic/instantbird/messages/bubbles/Incoming/Content.html (messages/bubbles/Incoming/Content.html) + skin/classic/instantbird/messages/bubbles/Incoming/Context.html (messages/bubbles/Incoming/Context.html) +diff --git a/im/themes/messages/bubbles/bubbles.svg b/im/themes/messages/bubbles/bubbles.svg +deleted file mode 100644 +index 963521eca..000000000 +--- a/im/themes/messages/bubbles/bubbles.svg ++++ /dev/null +@@ -1,10 +0,0 @@ +-<?xml version="1.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/. --> +- +-<svg xmlns="http://www.w3.org/2000/svg"> +- <filter id="desaturate"> +- <feColorMatrix type="saturate" values="0.4"/> +- </filter> +-</svg> +diff --git a/im/themes/messages/bubbles/main.css b/im/themes/messages/bubbles/main.css +index 15ba97346..4488c30bb 100644 +--- a/im/themes/messages/bubbles/main.css ++++ b/im/themes/messages/bubbles/main.css +@@ -40,7 +40,7 @@ p { + } + + .bubble.context:not(:hover) { +- filter: url("bubbles.svg#desaturate"); ++ filter: saturate(40%); + } + + .indicator { +-- +2.11.0 + diff --git a/projects/instantbird/0026-Bug-1321420-Add-a-pref-to-disable-JavaScript-in-brow.patch b/projects/instantbird/0026-Bug-1321420-Add-a-pref-to-disable-JavaScript-in-brow.patch new file mode 100644 index 0000000..2f6a82e --- /dev/null +++ b/projects/instantbird/0026-Bug-1321420-Add-a-pref-to-disable-JavaScript-in-brow.patch @@ -0,0 +1,52 @@ +From f076a0ffdaa9b69dad2c04b706f5a8daf8e8314d Mon Sep 17 00:00:00 2001 +From: Arlo Breault arlolra@gmail.com +Date: Thu, 1 Dec 2016 14:34:51 -0800 +Subject: [PATCH 26/26] Bug 1321420 - Add a pref to disable JavaScript in + browser requests + +--- + chat/chat-prefs.js | 2 ++ + chat/content/browserRequest.js | 7 +++++++ + 2 files changed, 9 insertions(+) + +diff --git a/chat/chat-prefs.js b/chat/chat-prefs.js +index 60b9c1e8c..90a212e5c 100644 +--- a/chat/chat-prefs.js ++++ b/chat/chat-prefs.js +@@ -86,6 +86,8 @@ pref("chat.prpls.prpl-skype.disable", true); + pref("chat.prpls.prpl-facebook.disable", true); + // Disable Yahoo Messenger as legacy Yahoo was shut down. + pref("chat.prpls.prpl-yahoo.disable", true); ++// Disable JavaScript in browser requests. ++pref("chat.browserRequest.disableJavascript", false); + + // loglevel is the minimum severity level that a libpurple message + // must have to be reported in the Error Console. +diff --git a/chat/content/browserRequest.js b/chat/content/browserRequest.js +index c52c8c637..0069219fa 100644 +--- a/chat/content/browserRequest.js ++++ b/chat/content/browserRequest.js +@@ -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/. */ + ++Components.utils.import("resource:///modules/imServices.jsm"); ++ + var wpl = Components.interfaces.nsIWebProgressListener; + + var reporterListener = { +@@ -133,6 +135,11 @@ function loadRequestedUrl() + account.protocol.iconBaseURI + "icon48.png"; + + let browser = document.getElementById("requestFrame"); ++ browser.docShell.allowPlugins = false; ++ ++ if (Services.prefs.getBoolPref("chat.browserRequest.disableJavascript")) ++ browser.docShell.allowJavascript = false; ++ + browser.addProgressListener(reporterListener, + Components.interfaces.nsIWebProgress.NOTIFY_ALL); + let url = request.url; +-- +2.11.0 + diff --git a/projects/instantbird/0026-Bug-1321641-Use-built-in-functions-instead-of-an-svg.patch b/projects/instantbird/0026-Bug-1321641-Use-built-in-functions-instead-of-an-svg.patch deleted file mode 100644 index 1beef80..0000000 --- a/projects/instantbird/0026-Bug-1321641-Use-built-in-functions-instead-of-an-svg.patch +++ /dev/null @@ -1,57 +0,0 @@ -From b8b4eee34d1e88ffc0100c2c3f8e91a8afba1f01 Mon Sep 17 00:00:00 2001 -From: Arlo Breault arlolra@gmail.com -Date: Thu, 1 Dec 2016 13:25:42 -0800 -Subject: [PATCH 26/27] Bug 1321641 - Use built-in functions instead of an svg - for bubbles filter - ---- - im/themes/jar.mn | 1 - - im/themes/messages/bubbles/bubbles.svg | 10 ---------- - im/themes/messages/bubbles/main.css | 2 +- - 3 files changed, 1 insertion(+), 12 deletions(-) - delete mode 100644 im/themes/messages/bubbles/bubbles.svg - -diff --git a/im/themes/jar.mn b/im/themes/jar.mn -index e422619d4..e39f5dcd8 100644 ---- a/im/themes/jar.mn -+++ b/im/themes/jar.mn -@@ -268,7 +268,6 @@ instantbird.jar: - skin/classic/instantbird/messages/bubbles/Bitmaps/minus.png (messages/bubbles/Bitmaps/minus.png) - skin/classic/instantbird/messages/bubbles/Bitmaps/plus-hover.png (messages/bubbles/Bitmaps/plus-hover.png) - skin/classic/instantbird/messages/bubbles/Bitmaps/plus.png (messages/bubbles/Bitmaps/plus.png) -- skin/classic/instantbird/messages/bubbles/bubbles.svg (messages/bubbles/bubbles.svg) - skin/classic/instantbird/messages/bubbles/Footer.html (messages/bubbles/Footer.html) - skin/classic/instantbird/messages/bubbles/Incoming/Content.html (messages/bubbles/Incoming/Content.html) - skin/classic/instantbird/messages/bubbles/Incoming/Context.html (messages/bubbles/Incoming/Context.html) -diff --git a/im/themes/messages/bubbles/bubbles.svg b/im/themes/messages/bubbles/bubbles.svg -deleted file mode 100644 -index 963521eca..000000000 ---- a/im/themes/messages/bubbles/bubbles.svg -+++ /dev/null -@@ -1,10 +0,0 @@ --<?xml version="1.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/. --> -- --<svg xmlns="http://www.w3.org/2000/svg"> -- <filter id="desaturate"> -- <feColorMatrix type="saturate" values="0.4"/> -- </filter> --</svg> -diff --git a/im/themes/messages/bubbles/main.css b/im/themes/messages/bubbles/main.css -index 15ba97346..4488c30bb 100644 ---- a/im/themes/messages/bubbles/main.css -+++ b/im/themes/messages/bubbles/main.css -@@ -40,7 +40,7 @@ p { - } - - .bubble.context:not(:hover) { -- filter: url("bubbles.svg#desaturate"); -+ filter: saturate(40%); - } - - .indicator { --- -2.11.0 - diff --git a/projects/instantbird/0027-Bug-1321420-Add-a-pref-to-disable-JavaScript-in-brow.patch b/projects/instantbird/0027-Bug-1321420-Add-a-pref-to-disable-JavaScript-in-brow.patch deleted file mode 100644 index 23fa129..0000000 --- a/projects/instantbird/0027-Bug-1321420-Add-a-pref-to-disable-JavaScript-in-brow.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 0e9e3c12e782b4c4f010115b9115775b7e829f3f Mon Sep 17 00:00:00 2001 -From: Arlo Breault arlolra@gmail.com -Date: Thu, 1 Dec 2016 14:34:51 -0800 -Subject: [PATCH 27/27] Bug 1321420 - Add a pref to disable JavaScript in - browser requests - ---- - chat/chat-prefs.js | 2 ++ - chat/content/browserRequest.js | 7 +++++++ - 2 files changed, 9 insertions(+) - -diff --git a/chat/chat-prefs.js b/chat/chat-prefs.js -index 60b9c1e8c..90a212e5c 100644 ---- a/chat/chat-prefs.js -+++ b/chat/chat-prefs.js -@@ -86,6 +86,8 @@ pref("chat.prpls.prpl-skype.disable", true); - pref("chat.prpls.prpl-facebook.disable", true); - // Disable Yahoo Messenger as legacy Yahoo was shut down. - pref("chat.prpls.prpl-yahoo.disable", true); -+// Disable JavaScript in browser requests. -+pref("chat.browserRequest.disableJavascript", false); - - // loglevel is the minimum severity level that a libpurple message - // must have to be reported in the Error Console. -diff --git a/chat/content/browserRequest.js b/chat/content/browserRequest.js -index c52c8c637..0069219fa 100644 ---- a/chat/content/browserRequest.js -+++ b/chat/content/browserRequest.js -@@ -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/. */ - -+Components.utils.import("resource:///modules/imServices.jsm"); -+ - var wpl = Components.interfaces.nsIWebProgressListener; - - var reporterListener = { -@@ -133,6 +135,11 @@ function loadRequestedUrl() - account.protocol.iconBaseURI + "icon48.png"; - - let browser = document.getElementById("requestFrame"); -+ browser.docShell.allowPlugins = false; -+ -+ if (Services.prefs.getBoolPref("chat.browserRequest.disableJavascript")) -+ browser.docShell.allowJavascript = false; -+ - browser.addProgressListener(reporterListener, - Components.interfaces.nsIWebProgress.NOTIFY_ALL); - let url = request.url; --- -2.11.0 - diff --git a/projects/instantbird/config b/projects/instantbird/config index 2e4ded1..13859d7 100644 --- a/projects/instantbird/config +++ b/projects/instantbird/config @@ -69,26 +69,25 @@ input_files: - 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: 0021-SASL-ECDSA-NIST256P-CHALLENGE.patch - - filename: 0022-Bug-1313137-msg-is-not-defined-error-in-irc.js-chang.patch - - filename: 0023-Bug-954368-Contact-list-entries-should-adapt-their-h.patch - - filename: 0024-Bug-1187281-Only-show-close-button-on-Windows.patch - - filename: 0025-Bug-1316000-Remove-old-Yahoo-Messenger-support.-r-al.patch - - filename: 0026-Bug-1321641-Use-built-in-functions-instead-of-an-svg.patch - - filename: 0027-Bug-1321420-Add-a-pref-to-disable-JavaScript-in-brow.patch + - filename: 0008-XMPP-in-band-registration.patch + - filename: 0009-Remove-search-from-UI.patch + - filename: 0010-Add-Tor-Messenger-branding.patch + - filename: 0011-Account-picture.patch + - filename: 0012-Modify-protocol-defaults.patch + - filename: 0013-Modify-IRC-defaults.patch + - filename: 0014-Modify-themes.patch + - filename: 0015-Modify-XMPP-defaults.patch + - filename: 0016-Remove-logging-UI.patch + - filename: 0017-Cert-override.patch + - filename: 0018-Display-all-traffic-over-Tor.patch + - filename: 0019-Trac-17480-Content-sink.patch + - filename: 0020-SASL-ECDSA-NIST256P-CHALLENGE.patch + - filename: 0021-Bug-1313137-msg-is-not-defined-error-in-irc.js-chang.patch + - filename: 0022-Bug-954368-Contact-list-entries-should-adapt-their-h.patch + - filename: 0023-Bug-1187281-Only-show-close-button-on-Windows.patch + - filename: 0024-Bug-1316000-Remove-old-Yahoo-Messenger-support.-r-al.patch + - filename: 0025-Bug-1321641-Use-built-in-functions-instead-of-an-svg.patch + - filename: 0026-Bug-1321420-Add-a-pref-to-disable-JavaScript-in-brow.patch - filename: mozconfig-common - filename: 'mozconfig-[% c("var/osname") %]' name: mozconfig diff --git a/projects/mozilla/0001-Trac-19910-Prevents-STARTTLS-in-XMPP.patch b/projects/mozilla/0001-Trac-19910-Prevents-STARTTLS-in-XMPP.patch index d4faed1..d107480 100644 --- a/projects/mozilla/0001-Trac-19910-Prevents-STARTTLS-in-XMPP.patch +++ b/projects/mozilla/0001-Trac-19910-Prevents-STARTTLS-in-XMPP.patch @@ -1,4 +1,4 @@ -From d107a09da25db93e19b8512c29205de2aa0387c1 Mon Sep 17 00:00:00 2001 +From 8b9d71382cdf988c17dc20c38d2f9062a0643748 Mon Sep 17 00:00:00 2001 From: Arlo Breault arlolra@gmail.com Date: Mon, 10 Oct 2016 10:52:52 -0700 Subject: [PATCH 1/7] Trac 19910: Prevents STARTTLS in XMPP diff --git a/projects/mozilla/0002-Trac-16475-Block-flash-too.patch b/projects/mozilla/0002-Trac-16475-Block-flash-too.patch index 2f0ab05..cef65eb 100644 --- a/projects/mozilla/0002-Trac-16475-Block-flash-too.patch +++ b/projects/mozilla/0002-Trac-16475-Block-flash-too.patch @@ -1,4 +1,4 @@ -From 6c422054720f3ec350854c5560c36061b6146149 Mon Sep 17 00:00:00 2001 +From 37767eb8aaaa39fec605b9c636a9e529af84901a Mon Sep 17 00:00:00 2001 From: Arlo Breault arlolra@gmail.com Date: Thu, 6 Oct 2016 20:13:35 -0700 Subject: [PATCH 2/7] Trac 16475: Block flash too diff --git a/projects/mozilla/0003-Trac-20206-Avoid-the-need-to-download-the-font-Osaka.patch b/projects/mozilla/0003-Trac-20206-Avoid-the-need-to-download-the-font-Osaka.patch index faa24fa..2e42dc3 100644 --- a/projects/mozilla/0003-Trac-20206-Avoid-the-need-to-download-the-font-Osaka.patch +++ b/projects/mozilla/0003-Trac-20206-Avoid-the-need-to-download-the-font-Osaka.patch @@ -1,4 +1,4 @@ -From f3465153bc87a2e9c57d0fe8e796d4a09bcc0e24 Mon Sep 17 00:00:00 2001 +From 7faec6186979e8d6dca736f27949db09d07b0056 Mon Sep 17 00:00:00 2001 From: Jonathan Kew jkew@mozilla.com Date: Sun, 9 Oct 2016 09:18:37 -0700 Subject: [PATCH 3/7] Trac 20206: Avoid the need to download the font Osaka @@ -44,7 +44,7 @@ index eb7a7889ae6a..5c63e698726a 100644 LOG_FONTLIST(("(fontlist-singleface) family name: %s, key: %s\n", NS_ConvertUTF16toUTF8(familyName).get(), diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js -index e855cdbcb949..2891c804601d 100644 +index e3d98b13c6de..fc8ca9d14656 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -3577,9 +3577,9 @@ pref("font.name.monospace.x-math", "Courier"); diff --git a/projects/mozilla/0004-Trac-18331-Update-OS-X-toolchain-to-work-with-ESR-45.patch b/projects/mozilla/0004-Trac-18331-Update-OS-X-toolchain-to-work-with-ESR-45.patch index 1e7c83b..d2c084a 100644 --- a/projects/mozilla/0004-Trac-18331-Update-OS-X-toolchain-to-work-with-ESR-45.patch +++ b/projects/mozilla/0004-Trac-18331-Update-OS-X-toolchain-to-work-with-ESR-45.patch @@ -1,4 +1,4 @@ -From 0f7fcd0b4dba93f3e652838f9d9f988e9e8b8726 Mon Sep 17 00:00:00 2001 +From 527afa8ed730a3287b0ae13f8e48acacb7addc4d Mon Sep 17 00:00:00 2001 From: Arlo Breault arlolra@gmail.com Date: Wed, 23 Mar 2016 19:52:07 -0700 Subject: [PATCH 4/7] Trac 18331: Update OS X toolchain to work with ESR 45 diff --git a/projects/mozilla/0005-OSX-package-as-tar.bz2.patch b/projects/mozilla/0005-OSX-package-as-tar.bz2.patch index 2c24d45..ce2fbb1 100644 --- a/projects/mozilla/0005-OSX-package-as-tar.bz2.patch +++ b/projects/mozilla/0005-OSX-package-as-tar.bz2.patch @@ -1,4 +1,4 @@ -From 4c88cc660df421c77335f0d5fb73ea97430ed441 Mon Sep 17 00:00:00 2001 +From 9ba71cc32503f29cfb07204ffcdd2c2703ed0e92 Mon Sep 17 00:00:00 2001 From: Nicolas Vigier boklm@torproject.org Date: Thu, 25 Jun 2015 12:18:43 +0200 Subject: [PATCH 5/7] OSX: package as tar.bz2 diff --git a/projects/mozilla/0006-Updater-fixups-for-TM.patch b/projects/mozilla/0006-Updater-fixups-for-TM.patch index a8b017a..8a413fd 100644 --- a/projects/mozilla/0006-Updater-fixups-for-TM.patch +++ b/projects/mozilla/0006-Updater-fixups-for-TM.patch @@ -1,4 +1,4 @@ -From 08e87872bdf1b8b4fb643682cf33005ba335ba9b Mon Sep 17 00:00:00 2001 +From 102bcac5d81791ced5f245d4cbb6c8a13c10c5a2 Mon Sep 17 00:00:00 2001 From: Arlo Breault arlolra@gmail.com Date: Sun, 9 Oct 2016 09:34:38 -0700 Subject: [PATCH 6/7] Updater fixups for TM diff --git a/projects/mozilla/0007-Permit-storing-exceptions-even-w-inPrivateBrowsingMo.patch b/projects/mozilla/0007-Permit-storing-exceptions-even-w-inPrivateBrowsingMo.patch index da802fa..5c9c443 100644 --- a/projects/mozilla/0007-Permit-storing-exceptions-even-w-inPrivateBrowsingMo.patch +++ b/projects/mozilla/0007-Permit-storing-exceptions-even-w-inPrivateBrowsingMo.patch @@ -1,4 +1,4 @@ -From 57e056fd04d9e6b49ef84217dce3702959c1a9b3 Mon Sep 17 00:00:00 2001 +From 20c5a6360e15709ca1d7d053fea164a115cbc59e Mon Sep 17 00:00:00 2001 From: Arlo Breault arlolra@gmail.com Date: Sat, 3 Dec 2016 10:01:52 -0800 Subject: [PATCH 7/7] Permit storing exceptions even w/ inPrivateBrowsingMode diff --git a/projects/mozilla/config b/projects/mozilla/config index e936de2..a948ce4 100644 --- a/projects/mozilla/config +++ b/projects/mozilla/config @@ -1,5 +1,5 @@ # vim: filetype=yaml sw=2 -version: tor-browser-45.6.0esr-6.0-1-build1 +version: tor-browser-45.7.0esr-6.5-1-build1 filename: 'mozilla-[% c("version") %]-[% c("var/osname") %]-[% c("var/build_id") %].tar.gz' git_url: https://git.torproject.org/tor-browser.git git_hash: '[% c("version") %]' diff --git a/projects/tor-browser/config b/projects/tor-browser/config index c0337b9..6e6174c 100644 --- a/projects/tor-browser/config +++ b/projects/tor-browser/config @@ -1,5 +1,5 @@ # vim: filetype=yaml sw=2 -version: 6.0.8 +version: 6.5 filename: 'tor-browser-[% c("version") %]-[% c("var/osname") %].[% c("var/extension") %]'
input_files: diff --git a/projects/tor-launcher/0001-Bug-19432-Remove-special-handling-for-Instantbird-Th.patch b/projects/tor-launcher/0001-Bug-19432-Remove-special-handling-for-Instantbird-Th.patch deleted file mode 100644 index 366cde0..0000000 --- a/projects/tor-launcher/0001-Bug-19432-Remove-special-handling-for-Instantbird-Th.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 985b87cb1c6e6e0d70adb9279232423bd105eb4f Mon Sep 17 00:00:00 2001 -From: Kathy Brade brade@pearlcrescent.com -Date: Fri, 24 Jun 2016 12:04:39 -0400 -Subject: [PATCH 1/2] Bug 19432: Remove special handling for - Instantbird/Thunderbird - -These applications now use the same directory structure as Tor Browser. ---- - src/components/tl-process.js | 39 +++++++++++++-------------------------- - 1 file changed, 13 insertions(+), 26 deletions(-) - -diff --git a/src/components/tl-process.js b/src/components/tl-process.js -index ba50310..4f9928a 100644 ---- a/src/components/tl-process.js -+++ b/src/components/tl-process.js -@@ -32,8 +32,6 @@ TorProcessService.prototype = - kContractID : "@torproject.org/torlauncher-process-service;1", - kServiceName : "Tor Launcher Process Service", - kClassID: Components.ID("{FE7B4CAF-BCF4-4848-8BFF-EFA66C9AFDA1}"), -- kThunderbirdID: "{3550f703-e582-4d05-9a08-453d09bdfdc6}", -- kInstantbirdID: "{33cb9019-c295-46dd-be21-8c4936574bee}", - kTorLauncherExtPath: "tor-launcher@torproject.org", // This could vary. - - kPrefPromptAtStartup: "extensions.torlauncher.prompt_at_startup", -@@ -868,30 +866,19 @@ TorProcessService.prototype = - .getService(Ci.nsIProperties).get("CurProcD", Ci.nsIFile); - let appInfo = Cc["@mozilla.org/xre/app-info;1"] - .getService(Ci.nsIXULAppInfo); -- if ((appInfo.ID == this.kThunderbirdID) || -- (appInfo.ID == this.kInstantbirdID)) -- { -- // For TorBirdy and Tor Messenger the Tor Launcher extension -- // directory is returned. -- topDir.append("extensions"); -- topDir.append(this.kTorLauncherExtPath); -- } -- else // Tor Browser -- { -- // On Linux and Windows, we want to return the Browser/ directory. -- // Because topDir ("CurProcD") points to Browser/browser on those -- // platforms, we need to go up one level. -- // On Mac OS, we want to return the TorBrowser.app/ directory. -- // Because topDir points to Contents/Resources/browser on Mac OS, -- // we need to go up 3 levels. -- let tbbBrowserDepth = (TorLauncherUtil.isMac) ? 3 : 1; -- while (tbbBrowserDepth > 0) -- { -- let didRemove = (topDir.leafName != "."); -- topDir = topDir.parent; -- if (didRemove) -- tbbBrowserDepth--; -- } -+ // On Linux and Windows, we want to return the Browser/ directory. -+ // Because topDir ("CurProcD") points to Browser/browser on those -+ // platforms, we need to go up one level. -+ // On Mac OS, we want to return the TorBrowser.app/ directory. -+ // Because topDir points to Contents/Resources/browser on Mac OS, -+ // we need to go up 3 levels. -+ let tbbBrowserDepth = (TorLauncherUtil.isMac) ? 3 : 1; -+ while (tbbBrowserDepth > 0) -+ { -+ let didRemove = (topDir.leafName != "."); -+ topDir = topDir.parent; -+ if (didRemove) -+ tbbBrowserDepth--; - } - - this.mAppDir = topDir; --- -2.10.2 - diff --git a/projects/tor-launcher/0002-Bug-19568-Set-CurProcD-for-Thunderbird-Instantbird.patch b/projects/tor-launcher/0002-Bug-19568-Set-CurProcD-for-Thunderbird-Instantbird.patch deleted file mode 100644 index 0e45ae1..0000000 --- a/projects/tor-launcher/0002-Bug-19568-Set-CurProcD-for-Thunderbird-Instantbird.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 44c1cc246e8736e88906c74058f2c582aa6178ed Mon Sep 17 00:00:00 2001 -From: Sukhbir Singh sukhbir@torproject.org -Date: Mon, 4 Jul 2016 11:59:34 -0400 -Subject: [PATCH 2/2] Bug 19568: Set CurProcD for Thunderbird/Instantbird - -For Thunderbird/Instantbird, the CurProcD (topDir) is not browser/, -so we need to iterate one level less than Firefox. ---- - src/components/tl-process.js | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/src/components/tl-process.js b/src/components/tl-process.js -index 4f9928a..8e42feb 100644 ---- a/src/components/tl-process.js -+++ b/src/components/tl-process.js -@@ -31,6 +31,8 @@ TorProcessService.prototype = - { - kContractID : "@torproject.org/torlauncher-process-service;1", - kServiceName : "Tor Launcher Process Service", -+ kThunderbirdID: "{3550f703-e582-4d05-9a08-453d09bdfdc6}", -+ kInstantbirdID: "{33cb9019-c295-46dd-be21-8c4936574bee}", - kClassID: Components.ID("{FE7B4CAF-BCF4-4848-8BFF-EFA66C9AFDA1}"), - kTorLauncherExtPath: "tor-launcher@torproject.org", // This could vary. - -@@ -873,6 +875,14 @@ TorProcessService.prototype = - // Because topDir points to Contents/Resources/browser on Mac OS, - // we need to go up 3 levels. - let tbbBrowserDepth = (TorLauncherUtil.isMac) ? 3 : 1; -+ if ((appInfo.ID == this.kThunderbirdID) || -+ (appInfo.ID == this.kInstantbirdID)) -+ { -+ // On Thunderbird/Instantbird, the topDir is the root dir and not -+ // browser/, so we need to iterate one level less than Firefox. -+ --tbbBrowserDepth; -+ } -+ - while (tbbBrowserDepth > 0) - { - let didRemove = (topDir.leafName != "."); --- -2.10.2 - diff --git a/projects/tor-launcher/build b/projects/tor-launcher/build index 1f51756..8735d33 100644 --- a/projects/tor-launcher/build +++ b/projects/tor-launcher/build @@ -2,8 +2,6 @@ set -e tar xvf [% project %]-[% c('version') %].tar.gz cd [% project %]-[% c('version') %] -patch -p1 < ../0001-Bug-19432-Remove-special-handling-for-Instantbird-Th.patch -patch -p1 < ../0002-Bug-19568-Set-CurProcD-for-Thunderbird-Instantbird.patch [% IF c("var/tor_control_port") -%] patch -p1 < ../controlport.patch [% END -%] diff --git a/projects/tor-launcher/config b/projects/tor-launcher/config index e0a1248..f018c0b 100644 --- a/projects/tor-launcher/config +++ b/projects/tor-launcher/config @@ -1,13 +1,11 @@ # vim: filetype=yaml sw=2 -version: 0.2.9.4 +version: 0.2.10.3 git_url: https://git.torproject.org/tor-launcher.git git_hash: '[% c("version") %]' gpg_keyring: gk.gpg tag_gpg_id: 1 filename: "[% project %]-[% c('version') %]-[% c('var/build_id') %].xpi" input_files: - - filename: 0001-Bug-19432-Remove-special-handling-for-Instantbird-Th.patch - - filename: 0002-Bug-19568-Set-CurProcD-for-Thunderbird-Instantbird.patch - filename: torbirdy.png - filename: messenger.png - filename: default48.png diff --git a/rbm.conf b/rbm.conf index 300465f..1d41b47 100644 --- a/rbm.conf +++ b/rbm.conf @@ -6,7 +6,7 @@ output_dir: "out/[% project %]" pkg_type: build
var: - tormessenger_version: '0.3.0b3' + tormessenger_version: '0.4.0b1' copyright_year: '2016' build_id: '[% sha256(c("var/build_id_txt")).substr(0, 6) %]' build_id_txt: | diff --git a/tools/update-responses/config.yml b/tools/update-responses/config.yml index d504f85..9e09f57 100644 --- a/tools/update-responses/config.yml +++ b/tools/update-responses/config.yml @@ -18,7 +18,7 @@ build_targets: - WINNT_x86-gcc3-x64 osx64: Darwin_x86_64-gcc3 channels: - release: 0.3.0b3 + release: 0.4.0b1 versions: 0.3.0b1: platformVersion: 45.5.0
tor-commits@lists.torproject.org