diff options
Diffstat (limited to 'application/basilisk/base/content')
58 files changed, 397 insertions, 9643 deletions
diff --git a/application/basilisk/base/content/aboutNetError.xhtml b/application/basilisk/base/content/aboutNetError.xhtml index 3296600c8..5ff79ea12 100644 --- a/application/basilisk/base/content/aboutNetError.xhtml +++ b/application/basilisk/base/content/aboutNetError.xhtml @@ -362,7 +362,7 @@ // First, find the index of the <a> tag we care about, being // careful not to use an over-greedy regex. var re = /<a id="cert_domain_link" title="([^"]+)">/; - var result = domainRe.exec(desc); + var result = re.exec(desc); if (!result) return; diff --git a/application/basilisk/base/content/aboutRobots-icon.png b/application/basilisk/base/content/aboutRobots-icon.png Binary files differdeleted file mode 100644 index 1c4899aaf..000000000 --- a/application/basilisk/base/content/aboutRobots-icon.png +++ /dev/null diff --git a/application/basilisk/base/content/aboutRobots-widget-left.png b/application/basilisk/base/content/aboutRobots-widget-left.png Binary files differdeleted file mode 100644 index 3a1e48d5f..000000000 --- a/application/basilisk/base/content/aboutRobots-widget-left.png +++ /dev/null diff --git a/application/basilisk/base/content/aboutRobots.xhtml b/application/basilisk/base/content/aboutRobots.xhtml deleted file mode 100644 index 23fe3ba17..000000000 --- a/application/basilisk/base/content/aboutRobots.xhtml +++ /dev/null @@ -1,108 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<!-- 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/. --> - -<!DOCTYPE html [ - <!ENTITY % htmlDTD - PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" - "DTD/xhtml1-strict.dtd"> - %htmlDTD; - <!ENTITY % netErrorDTD - SYSTEM "chrome://global/locale/netError.dtd"> - %netErrorDTD; - <!ENTITY % globalDTD - SYSTEM "chrome://global/locale/global.dtd"> - %globalDTD; - <!ENTITY % aboutrobotsDTD - SYSTEM "chrome://browser/locale/aboutRobots.dtd"> - %aboutrobotsDTD; -]> - -<html xmlns="http://www.w3.org/1999/xhtml"> - <head> - <title>&robots.pagetitle;</title> - <link rel="stylesheet" href="chrome://global/skin/netError.css" type="text/css" media="all" /> - <link rel="icon" type="image/png" id="favicon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8%2F9hAAAACGFjVEwAAAASAAAAAJNtBPIAAAAaZmNUTAAAAAAAAAAQAAAAEAAAAAAAAAAALuAD6AABhIDeugAAALhJREFUOI2Nk8sNxCAMRDlGohauXFOMpfTiAlxICqAELltHLqlgctg1InzMRhpFAc%2BLGWTnmoeZYamt78zXdZmaQtQMADlnU0OIAlbmJUBEcO4bRKQY2rUXIPmAGnDuG%2FBx3%2FfvOPVaDUg%2BoAPUf1PArIMCSD5glMEsUGaG%2BkyAFWIBaCsKuA%2BHGCNijLgP133XgOEtaPFMy2vUolEGJoCIzBmoRUR9%2B7rxj16DZaW%2FmgtmxnJ8V3oAnApQwNS5zpcAAAAaZmNUTAAAAAEAAAAQAAAAEAAAAAAAAAAAAB4D6AIB52fclgAAACpmZEFUAAAAAjiNY2AYBVhBc3Pzf2LEcGreqcbwH1kDNjHauWAUjAJyAADymxf9WF%2Bu8QAAABpmY1RMAAAAAwAAABAAAAAQAAAAAAAAAAAAHgPoAgEK8Q9%2FAAAAFmZkQVQAAAAEOI1jYBgFo2AUjAIIAAAEEAAB0xIn4wAAABpmY1RMAAAABQAAABAAAAAQAAAAAAAAAAAAHgPoAgHnO30FAAAAQGZkQVQAAAAGOI1jYBieYKcaw39ixHCC%2F6cwFWMTw2rz%2F1MM%2F6Vu%2Ff%2F%2F%2FxTD%2F51qEIwuRjsXILuEGLFRMApgAADhNCsVfozYcAAAABpmY1RMAAAABwAAABAAAAAQAAAAAAAAAAAAHgPoAgEKra7sAAAAFmZkQVQAAAAIOI1jYBgFo2AUjAIIAAAEEAABM9s3hAAAABpmY1RMAAAACQAAABAAAAAQAAAAAAAAAAAAHgPoAgHn3p%2BwAAAAKmZkQVQAAAAKOI1jYBgFWEFzc%2FN%2FYsRwat6pxvAfWQM2Mdq5YBSMAnIAAPKbF%2F1BhPl6AAAAGmZjVEwAAAALAAAAEAAAABAAAAAAAAAAAAAeA%2BgCAQpITFkAAAAWZmRBVAAAAAw4jWNgGAWjYBSMAggAAAQQAAHaszpmAAAAGmZjVEwAAAANAAAAEAAAABAAAAAAAAAAAAAeA%2BgCAeeCPiMAAABAZmRBVAAAAA44jWNgGJ5gpxrDf2LEcIL%2FpzAVYxPDavP%2FUwz%2FpW79%2F%2F%2F%2FFMP%2FnWoQjC5GOxcgu4QYsVEwCmAAAOE0KxUmBL0KAAAAGmZjVEwAAAAPAAAAEAAAABAAAAAAAAAAAAAeA%2BgCAQoU7coAAAAWZmRBVAAAABA4jWNgGAWjYBSMAggAAAQQAAEpOBELAAAAGmZjVEwAAAARAAAAEAAAABAAAAAAAAAAAAAeA%2BgCAeYVWtoAAAAqZmRBVAAAABI4jWNgGAVYQXNz839ixHBq3qnG8B9ZAzYx2rlgFIwCcgAA8psX%2FWvpAecAAAAaZmNUTAAAABMAAAAQAAAAEAAAAAAAAAAAAB4D6AIBC4OJMwAAABZmZEFUAAAAFDiNY2AYBaNgFIwCCAAABBAAAcBQHOkAAAAaZmNUTAAAABUAAAAQAAAAEAAAAAAAAAAAAB4D6AIB5kn7SQAAAEBmZEFUAAAAFjiNY2AYnmCnGsN%2FYsRwgv%2BnMBVjE8Nq8%2F9TDP%2Blbv3%2F%2F%2F8Uw%2F%2BdahCMLkY7FyC7hBixUTAKYAAA4TQrFc%2BcEoQAAAAaZmNUTAAAABcAAAAQAAAAEAAAAAAAAAAAAB4D6AIBC98ooAAAABZmZEFUAAAAGDiNY2AYBaNgFIwCCAAABBAAASCZDI4AAAAaZmNUTAAAABkAAAAQAAAAEAAAAAAAAAAAAB4D6AIB5qwZ%2FAAAACpmZEFUAAAAGjiNY2AYBVhBc3Pzf2LEcGreqcbwH1kDNjHauWAUjAJyAADymxf9cjJWbAAAABpmY1RMAAAAGwAAABAAAAAQAAAAAAAAAAAAHgPoAgELOsoVAAAAFmZkQVQAAAAcOI1jYBgFo2AUjAIIAAAEEAAByfEBbAAAABpmY1RMAAAAHQAAABAAAAAQAAAAAAAAAAAAHgPoAgHm8LhvAAAAQGZkQVQAAAAeOI1jYBieYKcaw39ixHCC%2F6cwFWMTw2rz%2F1MM%2F6Vu%2Ff%2F%2F%2FxTD%2F51qEIwuRjsXILuEGLFRMApgAADhNCsVlxR3%2FgAAABpmY1RMAAAAHwAAABAAAAAQAAAAAAAAAAAAHgPoAgELZmuGAAAAFmZkQVQAAAAgOI1jYBgFo2AUjAIIAAAEEAABHP5cFQAAABpmY1RMAAAAIQAAABAAAAAQAAAAAAAAAAAAHgPoAgHlgtAOAAAAKmZkQVQAAAAiOI1jYBgFWEFzc%2FN%2FYsRwat6pxvAfWQM2Mdq5YBSMAnIAAPKbF%2F0%2FMvDdAAAAAElFTkSuQmCC"/> - - <script type="application/javascript"><![CDATA[ - var buttonClicked = false; - function robotButton() - { - var button = document.getElementById('errorTryAgain'); - if (buttonClicked) { - button.style.visibility = "hidden"; - } else { - var newLabel = button.getAttribute("label2"); - button.textContent = newLabel; - buttonClicked = true; - } - } - ]]></script> - - <style type="text/css"><![CDATA[ - #errorPageContainer { - background-image: none; - } - - #errorPageContainer:before { - content: url('chrome://browser/content/aboutRobots-icon.png'); - position: absolute; - } - - body[dir=rtl] #icon, - body[dir=rtl] #errorPageContainer:before { - transform: scaleX(-1); - } - ]]></style> - </head> - - <body dir="&locale.dir;"> - - <!-- PAGE CONTAINER (for styling purposes only) --> - <div id="errorPageContainer"> - - <!-- Error Title --> - <div id="errorTitle"> - <h1 id="errorTitleText">&robots.errorTitleText;</h1> - </div> - - <!-- LONG CONTENT (the section most likely to require scrolling) --> - <div id="errorLongContent"> - - <!-- Short Description --> - <div id="errorShortDesc"> - <p id="errorShortDescText">&robots.errorShortDescText;</p> - </div> - - <!-- Long Description (Note: See netError.dtd for used XHTML tags) --> - <div id="errorLongDesc"> - <ul> - <li>&robots.errorLongDesc1;</li> - <li>&robots.errorLongDesc2;</li> - <li>&robots.errorLongDesc3;</li> - <li>&robots.errorLongDesc4;</li> - </ul> - </div> - - <!-- Short Description --> - <div id="errorTrailerDesc"> - <p id="errorTrailerDescText">&robots.errorTrailerDescText;</p> - </div> - - </div> - - <!-- Button --> - <button id="errorTryAgain" - label2="&robots.dontpress;" - onclick="robotButton();">&retry.label;</button> - - <img src="chrome://browser/content/aboutRobots-widget-left.png" - style="position: absolute; bottom: -12px; left: -10px;"/> - <img src="chrome://browser/content/aboutRobots-widget-left.png" - style="position: absolute; bottom: -12px; right: -10px; transform: scaleX(-1);"/> - </div> - - </body> -</html> diff --git a/application/basilisk/base/content/aboutaccounts/aboutaccounts.css b/application/basilisk/base/content/aboutaccounts/aboutaccounts.css deleted file mode 100644 index a2c5cb8f0..000000000 --- a/application/basilisk/base/content/aboutaccounts/aboutaccounts.css +++ /dev/null @@ -1,24 +0,0 @@ -html, body { - height: 100%; -} - -#remote { - width: 100%; - height: 100%; - border: 0; - display: none; -} - -#networkError, #manage, #intro, #stage, #configError { - display: none; -} - -#oldsync { - background: none; - border: 0; - color: #0095dd; -} - -#oldsync:focus { - outline: 1px dotted #0095dd; -} diff --git a/application/basilisk/base/content/aboutaccounts/aboutaccounts.js b/application/basilisk/base/content/aboutaccounts/aboutaccounts.js deleted file mode 100644 index a05c1ea75..000000000 --- a/application/basilisk/base/content/aboutaccounts/aboutaccounts.js +++ /dev/null @@ -1,543 +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/. */ - -"use strict"; - -var {classes: Cc, interfaces: Ci, utils: Cu} = Components; - -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/FxAccounts.jsm"); - -var fxAccountsCommon = {}; -Cu.import("resource://gre/modules/FxAccountsCommon.js", fxAccountsCommon); - -// for master-password utilities -Cu.import("resource://services-sync/util.js"); - -const PREF_LAST_FXA_USER = "identity.fxaccounts.lastSignedInUserHash"; -const PREF_SYNC_SHOW_CUSTOMIZATION = "services.sync-setup.ui.showCustomizationDialog"; - -const ACTION_URL_PARAM = "action"; - -const OBSERVER_TOPICS = [ - fxAccountsCommon.ONVERIFIED_NOTIFICATION, - fxAccountsCommon.ONLOGOUT_NOTIFICATION, -]; - -function log(msg) { - // dump("FXA: " + msg + "\n"); -} - -function error(msg) { - console.log("Firefox Account Error: " + msg + "\n"); -} - -function getPreviousAccountNameHash() { - try { - return Services.prefs.getComplexValue(PREF_LAST_FXA_USER, Ci.nsISupportsString).data; - } catch (_) { - return ""; - } -} - -function setPreviousAccountNameHash(acctName) { - let string = Cc["@mozilla.org/supports-string;1"] - .createInstance(Ci.nsISupportsString); - string.data = sha256(acctName); - Services.prefs.setComplexValue(PREF_LAST_FXA_USER, Ci.nsISupportsString, string); -} - -function needRelinkWarning(acctName) { - let prevAcctHash = getPreviousAccountNameHash(); - return prevAcctHash && prevAcctHash != sha256(acctName); -} - -// Given a string, returns the SHA265 hash in base64 -function sha256(str) { - let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"] - .createInstance(Ci.nsIScriptableUnicodeConverter); - converter.charset = "UTF-8"; - // Data is an array of bytes. - let data = converter.convertToByteArray(str, {}); - let hasher = Cc["@mozilla.org/security/hash;1"] - .createInstance(Ci.nsICryptoHash); - hasher.init(hasher.SHA256); - hasher.update(data, data.length); - - return hasher.finish(true); -} - -function promptForRelink(acctName) { - let sb = Services.strings.createBundle("chrome://browser/locale/syncSetup.properties"); - let continueLabel = sb.GetStringFromName("continue.label"); - let title = sb.GetStringFromName("relinkVerify.title"); - let description = sb.formatStringFromName("relinkVerify.description", - [acctName], 1); - let body = sb.GetStringFromName("relinkVerify.heading") + - "\n\n" + description; - let ps = Services.prompt; - let buttonFlags = (ps.BUTTON_POS_0 * ps.BUTTON_TITLE_IS_STRING) + - (ps.BUTTON_POS_1 * ps.BUTTON_TITLE_CANCEL) + - ps.BUTTON_POS_1_DEFAULT; - let pressed = Services.prompt.confirmEx(window, title, body, buttonFlags, - continueLabel, null, null, null, - {}); - return pressed == 0; // 0 is the "continue" button -} - -// If the last fxa account used for sync isn't this account, we display -// a modal dialog checking they really really want to do this... -// (This is sync-specific, so ideally would be in sync's identity module, -// but it's a little more seamless to do here, and sync is currently the -// only fxa consumer, so... -function shouldAllowRelink(acctName) { - return !needRelinkWarning(acctName) || promptForRelink(acctName); -} - -function updateDisplayedEmail(user) { - let emailDiv = document.getElementById("email"); - if (emailDiv && user) { - emailDiv.textContent = user.email; - } -} - -var wrapper = { - iframe: null, - - init: function (url, urlParams) { - // If a master-password is enabled, we want to encourage the user to - // unlock it. Things still work if not, but the user will probably need - // to re-auth next startup (in which case we will get here again and - // re-prompt) - Utils.ensureMPUnlocked(); - - let iframe = document.getElementById("remote"); - this.iframe = iframe; - this.iframe.QueryInterface(Ci.nsIFrameLoaderOwner); - let docShell = this.iframe.frameLoader.docShell; - docShell.QueryInterface(Ci.nsIWebProgress); - docShell.addProgressListener(this.iframeListener, Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT); - iframe.addEventListener("load", this); - - // Ideally we'd just merge urlParams with new URL(url).searchParams, but our - // URLSearchParams implementation doesn't support iteration (bug 1085284). - let urlParamStr = urlParams.toString(); - if (urlParamStr) { - url += (url.includes("?") ? "&" : "?") + urlParamStr; - } - this.url = url; - // Set the iframe's location with loadURI/LOAD_FLAGS_REPLACE_HISTORY to - // avoid having a new history entry being added. REPLACE_HISTORY is used - // to replace the current entry, which is `about:blank`. - let webNav = iframe.frameLoader.docShell.QueryInterface(Ci.nsIWebNavigation); - webNav.loadURI(url, Ci.nsIWebNavigation.LOAD_FLAGS_REPLACE_HISTORY, null, null, null); - }, - - retry: function () { - let webNav = this.iframe.frameLoader.docShell.QueryInterface(Ci.nsIWebNavigation); - webNav.loadURI(this.url, Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_HISTORY, null, null, null); - }, - - iframeListener: { - QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener, - Ci.nsISupportsWeakReference, - Ci.nsISupports]), - - onStateChange: function(aWebProgress, aRequest, aState, aStatus) { - let failure = false; - - // Captive portals sometimes redirect users - if ((aState & Ci.nsIWebProgressListener.STATE_REDIRECTING)) { - failure = true; - } else if ((aState & Ci.nsIWebProgressListener.STATE_STOP)) { - if (aRequest instanceof Ci.nsIHttpChannel) { - try { - failure = aRequest.responseStatus != 200; - } catch (e) { - failure = aStatus != Components.results.NS_OK; - } - } - } - - // Calling cancel() will raise some OnStateChange notifications by itself, - // so avoid doing that more than once - if (failure && aStatus != Components.results.NS_BINDING_ABORTED) { - aRequest.cancel(Components.results.NS_BINDING_ABORTED); - setErrorPage("networkError"); - } - }, - - onLocationChange: function(aWebProgress, aRequest, aLocation, aFlags) { - if (aRequest && aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_ERROR_PAGE) { - aRequest.cancel(Components.results.NS_BINDING_ABORTED); - setErrorPage("networkError"); - } - }, - - onProgressChange: function() {}, - onStatusChange: function() {}, - onSecurityChange: function() {}, - }, - - handleEvent: function (evt) { - switch (evt.type) { - case "load": - this.iframe.contentWindow.addEventListener("FirefoxAccountsCommand", this); - this.iframe.removeEventListener("load", this); - break; - case "FirefoxAccountsCommand": - this.handleRemoteCommand(evt); - break; - } - }, - - /** - * onLogin handler receives user credentials from the jelly after a - * sucessful login and stores it in the fxaccounts service - * - * @param accountData the user's account data and credentials - */ - onLogin: function (accountData) { - log("Received: 'login'. Data:" + JSON.stringify(accountData)); - - if (accountData.customizeSync) { - Services.prefs.setBoolPref(PREF_SYNC_SHOW_CUSTOMIZATION, true); - } - delete accountData.customizeSync; - // sessionTokenContext is erroneously sent by the content server. - // https://github.com/mozilla/fxa-content-server/issues/2766 - // To avoid having the FxA storage manager not knowing what to do with - // it we delete it here. - delete accountData.sessionTokenContext; - - // We need to confirm a relink - see shouldAllowRelink for more - let newAccountEmail = accountData.email; - // The hosted code may have already checked for the relink situation - // by sending the can_link_account command. If it did, then - // it will indicate we don't need to ask twice. - if (!accountData.verifiedCanLinkAccount && !shouldAllowRelink(newAccountEmail)) { - // we need to tell the page we successfully received the message, but - // then bail without telling fxAccounts - this.injectData("message", { status: "login" }); - // after a successful login we return to preferences - openPrefs(); - return; - } - delete accountData.verifiedCanLinkAccount; - - // Remember who it was so we can log out next time. - setPreviousAccountNameHash(newAccountEmail); - - // A sync-specific hack - we want to ensure sync has been initialized - // before we set the signed-in user. - let xps = Cc["@mozilla.org/weave/service;1"] - .getService(Ci.nsISupports) - .wrappedJSObject; - xps.whenLoaded().then(() => { - updateDisplayedEmail(accountData); - return fxAccounts.setSignedInUser(accountData); - }).then(() => { - // If the user data is verified, we want it to immediately look like - // they are signed in without waiting for messages to bounce around. - if (accountData.verified) { - openPrefs(); - } - this.injectData("message", { status: "login" }); - // until we sort out a better UX, just leave the jelly page in place. - // If the account email is not yet verified, it will tell the user to - // go check their email, but then it will *not* change state after - // the verification completes (the browser will begin syncing, but - // won't notify the user). If the email has already been verified, - // the jelly will say "Welcome! You are successfully signed in as - // EMAIL", but it won't then say "syncing started". - }, (err) => this.injectData("message", { status: "error", error: err }) - ); - }, - - onCanLinkAccount: function(accountData) { - // We need to confirm a relink - see shouldAllowRelink for more - let ok = shouldAllowRelink(accountData.email); - this.injectData("message", { status: "can_link_account", data: { ok: ok } }); - }, - - /** - * onSignOut handler erases the current user's session from the fxaccounts service - */ - onSignOut: function () { - log("Received: 'sign_out'."); - - fxAccounts.signOut().then( - () => this.injectData("message", { status: "sign_out" }), - (err) => this.injectData("message", { status: "error", error: err }) - ); - }, - - handleRemoteCommand: function (evt) { - log('command: ' + evt.detail.command); - let data = evt.detail.data; - - switch (evt.detail.command) { - case "login": - this.onLogin(data); - break; - case "can_link_account": - this.onCanLinkAccount(data); - break; - case "sign_out": - this.onSignOut(data); - break; - default: - log("Unexpected remote command received: " + evt.detail.command + ". Ignoring command."); - break; - } - }, - - injectData: function (type, content) { - return fxAccounts.promiseAccountsSignUpURI().then(authUrl => { - let data = { - type: type, - content: content - }; - this.iframe.contentWindow.postMessage(data, authUrl); - }) - .catch(e => { - console.log("Failed to inject data", e); - setErrorPage("configError"); - }); - }, -}; - - -// Button onclick handlers -function handleOldSync() { - let chromeWin = window - .QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIWebNavigation) - .QueryInterface(Ci.nsIDocShellTreeItem) - .rootTreeItem - .QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDOMWindow) - .QueryInterface(Ci.nsIDOMChromeWindow); - let url = Services.urlFormatter.formatURLPref("app.support.baseURL") + "old-sync"; - chromeWin.switchToTabHavingURI(url, true); -} - -function getStarted() { - show("remote"); -} - -function retry() { - show("remote"); - wrapper.retry(); -} - -function openPrefs() { - // Bug 1199303 calls for this tab to always be replaced with Preferences - // rather than it opening in a different tab. - window.location = "about:preferences#sync"; -} - -function init() { - fxAccounts.getSignedInUser().then(user => { - // tests in particular might cause the window to start closing before - // getSignedInUser has returned. - if (window.closed) { - return Promise.resolve(); - } - - updateDisplayedEmail(user); - - // Ideally we'd use new URL(document.URL).searchParams, but for about: URIs, - // searchParams is empty. - let urlParams = new URLSearchParams(document.URL.split("?")[1] || ""); - let action = urlParams.get(ACTION_URL_PARAM); - urlParams.delete(ACTION_URL_PARAM); - - switch (action) { - case "signin": - if (user) { - // asking to sign-in when already signed in just shows manage. - show("stage", "manage"); - } else { - return fxAccounts.promiseAccountsSignInURI().then(url => { - show("remote"); - wrapper.init(url, urlParams); - }); - } - break; - case "signup": - if (user) { - // asking to sign-up when already signed in just shows manage. - show("stage", "manage"); - } else { - return fxAccounts.promiseAccountsSignUpURI().then(url => { - show("remote"); - wrapper.init(url, urlParams); - }); - } - break; - case "reauth": - // ideally we would only show this when we know the user is in a - // "must reauthenticate" state - but we don't. - // As the email address will be included in the URL returned from - // promiseAccountsForceSigninURI, just always show it. - return fxAccounts.promiseAccountsForceSigninURI().then(url => { - show("remote"); - wrapper.init(url, urlParams); - }); - default: - // No action specified. - if (user) { - show("stage", "manage"); - } else { - // Attempt a migration if enabled or show the introductory page - // otherwise. - return migrateToDevEdition(urlParams).then(migrated => { - if (!migrated) { - show("stage", "intro"); - // load the remote frame in the background - return fxAccounts.promiseAccountsSignUpURI().then(uri => - wrapper.init(uri, urlParams)); - } - return Promise.resolve(); - }); - } - break; - } - return Promise.resolve(); - }).catch(err => { - console.log("Configuration or sign in error", err); - setErrorPage("configError"); - }); -} - -function setErrorPage(errorType) { - show("stage", errorType); -} - -// Causes the "top-level" element with |id| to be shown - all other top-level -// elements are hidden. Optionally, ensures that only 1 "second-level" element -// inside the top-level one is shown. -function show(id, childId) { - // top-level items are either <div> or <iframe> - let allTop = document.querySelectorAll("body > div, iframe"); - for (let elt of allTop) { - if (elt.getAttribute("id") == id) { - elt.style.display = 'block'; - } else { - elt.style.display = 'none'; - } - } - if (childId) { - // child items are all <div> - let allSecond = document.querySelectorAll("#" + id + " > div"); - for (let elt of allSecond) { - if (elt.getAttribute("id") == childId) { - elt.style.display = 'block'; - } else { - elt.style.display = 'none'; - } - } - } -} - -// Migrate sync data from the default profile to the dev-edition profile. -// Returns a promise of a true value if migration succeeded, or false if it -// failed. -function migrateToDevEdition(urlParams) { - let defaultProfilePath; - try { - defaultProfilePath = window.getDefaultProfilePath(); - } catch (e) {} // no default profile. - let migrateSyncCreds = false; - if (defaultProfilePath) { - try { - migrateSyncCreds = Services.prefs.getBoolPref("identity.fxaccounts.migrateToDevEdition"); - } catch (e) {} - } - - if (!migrateSyncCreds) { - return Promise.resolve(false); - } - - Cu.import("resource://gre/modules/osfile.jsm"); - let fxAccountsStorage = OS.Path.join(defaultProfilePath, fxAccountsCommon.DEFAULT_STORAGE_FILENAME); - return OS.File.read(fxAccountsStorage, { encoding: "utf-8" }).then(text => { - let accountData = JSON.parse(text).accountData; - updateDisplayedEmail(accountData); - return fxAccounts.setSignedInUser(accountData); - }).then(() => { - return fxAccounts.promiseAccountsForceSigninURI().then(url => { - show("remote"); - wrapper.init(url, urlParams); - }); - }).then(null, error => { - log("Failed to migrate FX Account: " + error); - show("stage", "intro"); - // load the remote frame in the background - fxAccounts.promiseAccountsSignUpURI().then(uri => { - wrapper.init(uri, urlParams) - }).catch(e => { - console.log("Failed to load signup page", e); - setErrorPage("configError"); - }); - }).then(() => { - // Reset the pref after migration. - Services.prefs.setBoolPref("identity.fxaccounts.migrateToDevEdition", false); - return true; - }).then(null, err => { - Cu.reportError("Failed to reset the migrateToDevEdition pref: " + err); - return false; - }); -} - -// Helper function that returns the path of the default profile on disk. Will be -// overridden in tests. -function getDefaultProfilePath() { - let defaultProfile = Cc["@mozilla.org/toolkit/profile-service;1"] - .getService(Ci.nsIToolkitProfileService) - .defaultProfile; - return defaultProfile.rootDir.path; -} - -document.addEventListener("DOMContentLoaded", function onload() { - document.removeEventListener("DOMContentLoaded", onload, true); - init(); - var buttonGetStarted = document.getElementById('buttonGetStarted'); - buttonGetStarted.addEventListener('click', getStarted); - - var buttonRetry = document.getElementById('buttonRetry'); - buttonRetry.addEventListener('click', retry); - - var oldsync = document.getElementById('oldsync'); - oldsync.addEventListener('click', handleOldSync); - - var buttonOpenPrefs = document.getElementById('buttonOpenPrefs') - buttonOpenPrefs.addEventListener('click', openPrefs); -}, true); - -function initObservers() { - function observe(subject, topic, data) { - log("about:accounts observed " + topic); - if (topic == fxAccountsCommon.ONLOGOUT_NOTIFICATION) { - // All about:account windows get changed to action=signin on logout. - window.location = "about:accounts?action=signin"; - return; - } - - // must be onverified - we want to open preferences. - openPrefs(); - } - - for (let topic of OBSERVER_TOPICS) { - Services.obs.addObserver(observe, topic, false); - } - window.addEventListener("unload", function(event) { - log("about:accounts unloading") - for (let topic of OBSERVER_TOPICS) { - Services.obs.removeObserver(observe, topic); - } - }); -} -initObservers(); diff --git a/application/basilisk/base/content/aboutaccounts/aboutaccounts.xhtml b/application/basilisk/base/content/aboutaccounts/aboutaccounts.xhtml deleted file mode 100644 index 475f0e86f..000000000 --- a/application/basilisk/base/content/aboutaccounts/aboutaccounts.xhtml +++ /dev/null @@ -1,112 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- 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/. --> -<!DOCTYPE html [ - <!ENTITY % htmlDTD PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd"> - %htmlDTD; - <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd"> - %brandDTD; - <!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd"> - %globalDTD; - <!ENTITY % aboutAccountsDTD SYSTEM "chrome://browser/locale/aboutAccounts.dtd"> - %aboutAccountsDTD; - <!ENTITY % syncBrandDTD SYSTEM "chrome://browser/locale/syncBrand.dtd"> - %syncBrandDTD; -]> - -<html xmlns="http://www.w3.org/1999/xhtml" dir="&locale.dir;"> - <head> - <title>&syncBrand.fullName.label;</title> - <meta name="viewport" content="width=device-width"/> - - - <link rel="icon" type="image/png" id="favicon" - href="chrome://branding/content/icon32.png"/> - <link rel="stylesheet" - href="chrome://browser/content/aboutaccounts/normalize.css" - type="text/css" /> - <link rel="stylesheet" - href="chrome://browser/content/aboutaccounts/main.css" - type="text/css" /> - <link rel="stylesheet" - href="chrome://browser/content/aboutaccounts/aboutaccounts.css" - type="text/css" /> - </head> - <body> - <div id="stage"> - - <div id="manage"> - <header> - <h1>&aboutAccounts.connected;</h1> - <div id="email"></div> - </header> - - <section> - <div class="graphic graphic-sync-intro"> </div> - - <div class="button-row"> - <button id="buttonOpenPrefs" class="button" href="#" tabindex="0">&aboutAccountsConfig.syncPreferences.label;</button> - </div> - </section> - </div> - - <div id="intro"> - <header> - <h1>&aboutAccounts.welcome;</h1> - </header> - - <section> - <div class="graphic graphic-sync-intro"> </div> - - <div class="description">&aboutAccountsConfig.description;</div> - - <div class="button-row"> - <button id="buttonGetStarted" class="button" tabindex="1">&aboutAccountsConfig.startButton.label;</button> - </div> - - <div class="links"> - <button id="oldsync" tabindex="2">&aboutAccountsConfig.useOldSync.label;</button> - </div> - </section> - </div> - - <div id="networkError"> - <header> - <h1>&aboutAccounts.noConnection.title;</h1> - </header> - - <section> - <div class="graphic graphic-sync-intro"> </div> - - <div class="description">&aboutAccounts.noConnection.description;</div> - - <div class="button-row"> - <button id="buttonRetry" class="button" tabindex="3">&aboutAccounts.noConnection.retry;</button> - </div> - </section> - </div> - - <div id="configError"> - <header> - <h1>&aboutAccounts.badConfig.title;</h1> - </header> - - <section> - <div class="graphic graphic-sync-intro"> </div> - - <div class="description">&aboutAccounts.badConfig.description;</div> - - </section> - </div> - - </div> - - <iframe mozframetype="content" id="remote" /> - - <script type="application/javascript;version=1.8" - src="chrome://browser/content/utilityOverlay.js"/> - <script type="text/javascript;version=1.8" - src="chrome://browser/content/aboutaccounts/aboutaccounts.js" /> - </body> -</html> diff --git a/application/basilisk/base/content/aboutaccounts/images/fox.png b/application/basilisk/base/content/aboutaccounts/images/fox.png Binary files differdeleted file mode 100644 index 83af78d6c..000000000 --- a/application/basilisk/base/content/aboutaccounts/images/fox.png +++ /dev/null diff --git a/application/basilisk/base/content/aboutaccounts/images/graphic_sync_intro.png b/application/basilisk/base/content/aboutaccounts/images/graphic_sync_intro.png Binary files differdeleted file mode 100644 index ff5f482f0..000000000 --- a/application/basilisk/base/content/aboutaccounts/images/graphic_sync_intro.png +++ /dev/null diff --git a/application/basilisk/base/content/aboutaccounts/images/graphic_sync_intro@2x.png b/application/basilisk/base/content/aboutaccounts/images/graphic_sync_intro@2x.png Binary files differdeleted file mode 100644 index 89fda0681..000000000 --- a/application/basilisk/base/content/aboutaccounts/images/graphic_sync_intro@2x.png +++ /dev/null diff --git a/application/basilisk/base/content/aboutaccounts/main.css b/application/basilisk/base/content/aboutaccounts/main.css deleted file mode 100644 index 8f4c3b34e..000000000 --- a/application/basilisk/base/content/aboutaccounts/main.css +++ /dev/null @@ -1,166 +0,0 @@ -*, -*:before, -*:after { - box-sizing: border-box; -} - -html { - background-color: #F2F2F2; - height: 100%; -} - -body { - color: #424f59; - font: message-box; - font-size: 14px; - height: 100%; -} - -a { - color: #0095dd; - cursor: pointer; /* Use the correct cursor for anchors without an href */ -} - -a:active { - outline: none; -} - -a:focus { - outline: 1px dotted #0095dd; -} - - -a.no-underline { - text-decoration: none; -} - -#stage { - background:#fff; - border-radius: 5px; - box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.25); - margin: 0 auto; - min-height: 300px; - padding: 60px 40px 40px 40px; - position: relative; - text-align: center; - top: 80px; - width: 420px; -} - -header h1 -{ - font-size: 24px; - font-weight: 200; - line-height: 1em; -} - -#intro header h1 { - margin: 0 0 32px 0; -} - -#manage header h1 { - margin: 0 0 12px 0; -} - -#manage header #email { - margin-bottom: 23px; - color: rgb(138, 155, 168); - font-size: 19px; - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; -} - -.description { - font-size: 18px; -} - -.button-row { - margin-top: 45px; - margin-bottom:20px; -} - -.button-row button, -.button-row a.button { - background: #0095dd; - border: none; - border-radius: 5px; - color: #FFFFFF; - cursor: pointer; - font-size: 24px; - padding: 15px 0; - transition-duration: 150ms; - transition-property: background-color; - width: 100%; -} - -.button-row a.button { - display: inline-block; - text-decoration: none; -} - -.button-row a.button:active, -.button-row a.button:hover, -.button-row a.button:focus, -.button-row button:active, -.button-row button:hover, -.button-row button:focus { - background: #08c; -} - - -.graphic-sync-intro { - background-image: url(images/graphic_sync_intro.png); - background-repeat: no-repeat; - background-size: 150px 195px; - height: 195px; - margin: 0 auto; - overflow: hidden; - text-indent: 100%; - white-space: nowrap; - width: 150px; -} - -.description, -.button-row { - margin-top: 30px; -} - -.links { - margin: 20px 0; -} - -@media only screen and (max-width: 500px) { - html { - background: #fff; - } - - #stage { - box-shadow: none; - margin: 30px auto 0 auto; - min-height: none; - min-width: 320px; - padding: 0 10px; - width: 100%; - } - - .button-row { - margin-top: 20px; - } - - .button-row button, - .button-row a.button { - padding: 10px 0; - } - -} - -/* Retina */ -@media -only screen and (min-device-pixel-ratio: 2), -only screen and ( min-resolution: 192dpi), -only screen and ( min-resolution: 2dppx) { - .graphic-sync-intro { - background-image: url(images/graphic_sync_intro@2x.png); - } -} diff --git a/application/basilisk/base/content/aboutaccounts/normalize.css b/application/basilisk/base/content/aboutaccounts/normalize.css deleted file mode 100644 index c02ab25de..000000000 --- a/application/basilisk/base/content/aboutaccounts/normalize.css +++ /dev/null @@ -1,402 +0,0 @@ -/*! normalize.css v2.1.3 | MIT License | git.io/normalize */
-
-/* ==========================================================================
- HTML5 display definitions
- ========================================================================== */
-
-/**
- * Correct `block` display not defined in IE 8/9.
- */
-
-article,
-aside,
-details,
-figcaption,
-figure,
-footer,
-header,
-hgroup,
-main,
-nav,
-section,
-summary {
- display: block;
-}
-
-/**
- * Correct `inline-block` display not defined in IE 8/9.
- */
-
-audio,
-canvas,
-video {
- display: inline-block;
-}
-
-/**
- * Prevent modern browsers from displaying `audio` without controls.
- * Remove excess height in iOS 5 devices.
- */
-
-audio:not([controls]) {
- display: none;
- height: 0;
-}
-
-/**
- * Address `[hidden]` styling not present in IE 8/9.
- * Hide the `template` element in IE, Safari, and Firefox < 22.
- */
-
-[hidden],
-template {
- display: none;
-}
-
-/* ==========================================================================
- Base
- ========================================================================== */
-
-/**
- * 1. Set default font family to sans-serif.
- * 2. Prevent iOS text size adjust after orientation change, without disabling
- * user zoom.
- */
-
-html {
- font-family: sans-serif; /* 1 */
- -ms-text-size-adjust: 100%; /* 2 */
- -webkit-text-size-adjust: 100%; /* 2 */
-}
-
-/**
- * Remove default margin.
- */
-
-body {
- margin: 0;
-}
-
-/* ==========================================================================
- Links
- ========================================================================== */
-
-/**
- * Remove the gray background color from active links in IE 10.
- */
-
-a {
- background: transparent;
-}
-
-/**
- * Address `outline` inconsistency between Chrome and other browsers.
- */
-
-a:focus {
- outline: thin dotted;
-}
-
-/**
- * Improve readability when focused and also mouse hovered in all browsers.
- */
-
-a:active,
-a:hover {
- outline: 0;
-}
-
-/* ==========================================================================
- Typography
- ========================================================================== */
-
-/**
- * Address variable `h1` font-size and margin within `section` and `article`
- * contexts in Firefox 4+, Safari 5, and Chrome.
- */
-
-h1 {
- font-size: 2em;
- margin: 0.67em 0;
-}
-
-/**
- * Address styling not present in IE 8/9, Safari 5, and Chrome.
- */
-
-abbr[title] {
- border-bottom: 1px dotted;
-}
-
-/**
- * Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome.
- */
-
-b,
-strong {
- font-weight: bold;
-}
-
-/**
- * Address styling not present in Safari 5 and Chrome.
- */
-
-dfn {
- font-style: italic;
-}
-
-/**
- * Address differences between Firefox and other browsers.
- */
-
-hr {
- box-sizing: content-box;
- height: 0;
-}
-
-/**
- * Address styling not present in IE 8/9.
- */
-
-mark {
- background: #ff0;
- color: #000;
-}
-
-/**
- * Correct font family set oddly in Safari 5 and Chrome.
- */
-
-code,
-kbd,
-pre,
-samp {
- font-family: monospace, serif;
- font-size: 1em;
-}
-
-/**
- * Improve readability of pre-formatted text in all browsers.
- */
-
-pre {
- white-space: pre-wrap;
-}
-
-/**
- * Set consistent quote types.
- */
-
-q {
- quotes: "\201C" "\201D" "\2018" "\2019";
-}
-
-/**
- * Address inconsistent and variable font size in all browsers.
- */
-
-small {
- font-size: 80%;
-}
-
-/**
- * Prevent `sub` and `sup` affecting `line-height` in all browsers.
- */
-
-sub,
-sup {
- font-size: 75%;
- line-height: 0;
- position: relative;
- vertical-align: baseline;
-}
-
-sup {
- top: -0.5em;
-}
-
-sub {
- bottom: -0.25em;
-}
-
-/* ==========================================================================
- Embedded content
- ========================================================================== */
-
-/**
- * Remove border when inside `a` element in IE 8/9.
- */
-
-img {
- border: 0;
-}
-
-/**
- * Correct overflow displayed oddly in IE 9.
- */
-
-svg:not(:root) {
- overflow: hidden;
-}
-
-/* ==========================================================================
- Figures
- ========================================================================== */
-
-/**
- * Address margin not present in IE 8/9 and Safari 5.
- */
-
-figure {
- margin: 0;
-}
-
-/* ==========================================================================
- Forms
- ========================================================================== */
-
-/**
- * Define consistent border, margin, and padding.
- */
-
-fieldset {
- border: 1px solid #c0c0c0;
- margin: 0 2px;
- padding: 0.35em 0.625em 0.75em;
-}
-
-/**
- * 1. Correct `color` not being inherited in IE 8/9.
- * 2. Remove padding so people aren't caught out if they zero out fieldsets.
- */
-
-legend {
- border: 0; /* 1 */
- padding: 0; /* 2 */
-}
-
-/**
- * 1. Correct font family not being inherited in all browsers.
- * 2. Correct font size not being inherited in all browsers.
- * 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome.
- */
-
-button,
-input,
-select,
-textarea {
- font-family: inherit; /* 1 */
- font-size: 100%; /* 2 */
- margin: 0; /* 3 */
-}
-
-/**
- * Address Firefox 4+ setting `line-height` on `input` using `!important` in
- * the UA stylesheet.
- */
-
-button,
-input {
- line-height: normal;
-}
-
-/**
- * Address inconsistent `text-transform` inheritance for `button` and `select`.
- * All other form control elements do not inherit `text-transform` values.
- * Correct `button` style inheritance in Chrome, Safari 5+, and IE 8+.
- * Correct `select` style inheritance in Firefox 4+ and Opera.
- */
-
-button,
-select {
- text-transform: none;
-}
-
-/**
- * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
- * and `video` controls.
- * 2. Correct inability to style clickable `input` types in iOS.
- * 3. Improve usability and consistency of cursor style between image-type
- * `input` and others.
- */
-
-button,
-html input[type="button"], /* 1 */
-input[type="reset"],
-input[type="submit"] {
- -webkit-appearance: button; /* 2 */
- cursor: pointer; /* 3 */
-}
-
-/**
- * Re-set default cursor for disabled elements.
- */
-
-button[disabled],
-html input[disabled] {
- cursor: default;
-}
-
-/**
- * 1. Address box sizing set to `content-box` in IE 8/9/10.
- * 2. Remove excess padding in IE 8/9/10.
- */
-
-input[type="checkbox"],
-input[type="radio"] {
- box-sizing: border-box; /* 1 */
- padding: 0; /* 2 */
-}
-
-/**
- * 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome.
- * 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome.
- */
-
-input[type="search"] {
- -webkit-appearance: textfield; /* 1 */
- box-sizing: content-box; /* 2 */
-}
-
-/**
- * Remove inner padding and search cancel button in Safari 5 and Chrome
- * on OS X.
- */
-
-input[type="search"]::-webkit-search-cancel-button,
-input[type="search"]::-webkit-search-decoration {
- -webkit-appearance: none;
-}
-
-/**
- * Remove inner padding and border in Firefox 4+.
- */
-
-button::-moz-focus-inner,
-input::-moz-focus-inner {
- border: 0;
- padding: 0;
-}
-
-/**
- * 1. Remove default vertical scrollbar in IE 8/9.
- * 2. Improve readability and alignment in all browsers.
- */
-
-textarea {
- overflow: auto; /* 1 */
- vertical-align: top; /* 2 */
-}
-
-/* ==========================================================================
- Tables
- ========================================================================== */
-
-/**
- * Remove most spacing between table cells.
- */
-
-table {
- border-collapse: collapse;
- border-spacing: 0;
-}
diff --git a/application/basilisk/base/content/abouthome/aboutHome.css b/application/basilisk/base/content/abouthome/aboutHome.css index bc3f9882c..86f74727f 100644 --- a/application/basilisk/base/content/abouthome/aboutHome.css +++ b/application/basilisk/base/content/abouthome/aboutHome.css @@ -283,9 +283,11 @@ body[narrow] #restorePreviousSession { content: url("chrome://browser/content/abouthome/addons.png"); } +%ifdef MOZ_SERVICES_SYNC #sync::before { content: url("chrome://browser/content/abouthome/sync.png"); } +%endif #settings::before { content: url("chrome://browser/content/abouthome/settings.png"); @@ -369,9 +371,11 @@ body[narrow] #restorePreviousSession::before { content: url("chrome://browser/content/abouthome/addons@2x.png"); } +%ifdef MOZ_SERVICES_SYNC #sync::before { content: url("chrome://browser/content/abouthome/sync@2x.png"); } +%endif #settings::before { content: url("chrome://browser/content/abouthome/settings@2x.png"); diff --git a/application/basilisk/base/content/abouthome/aboutHome.xhtml b/application/basilisk/base/content/abouthome/aboutHome.xhtml index 22bf2e7e8..90daad2dc 100644 --- a/application/basilisk/base/content/abouthome/aboutHome.xhtml +++ b/application/basilisk/base/content/abouthome/aboutHome.xhtml @@ -54,7 +54,9 @@ <button class="launchButton" id="bookmarks">&abouthome.bookmarksButton.label;</button> <button class="launchButton" id="history">&abouthome.historyButton.label;</button> <button class="launchButton" id="addons">&abouthome.addonsButton.label;</button> +#ifdef MOZ_SERVICES_SYNC <button class="launchButton" id="sync">&abouthome.syncButton.label;</button> +#endif #ifdef XP_WIN <button class="launchButton" id="settings">&abouthome.preferencesButtonWin.label;</button> #else diff --git a/application/basilisk/base/content/browser-addons.js b/application/basilisk/base/content/browser-addons.js index 1d881536a..733114ba9 100644 --- a/application/basilisk/base/content/browser-addons.js +++ b/application/basilisk/base/content/browser-addons.js @@ -145,10 +145,6 @@ const gXPInstallObserver = { for (let install of installInfo.installs) install.install(); installInfo = null; - - Services.telemetry - .getHistogramById("SECURITY_UI") - .add(Ci.nsISecurityUITelemetry.WARNING_CONFIRM_ADDON_INSTALL_CLICK_THROUGH); }; break; } @@ -208,10 +204,6 @@ const gXPInstallObserver = { options); removeNotificationOnEnd(popup, installInfo.installs); - - Services.telemetry - .getHistogramById("SECURITY_UI") - .add(Ci.nsISecurityUITelemetry.WARNING_CONFIRM_ADDON_INSTALL); }, observe: function (aSubject, aTopic, aData) @@ -262,8 +254,6 @@ const gXPInstallObserver = { messageString = gNavigatorBundle.getFormattedString("xpinstallPromptMessage", [brandShortName]); - let secHistogram = Components.classes["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry).getHistogramById("SECURITY_UI"); - secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_ADDON_ASKING_PREVENTED); let popup = PopupNotifications.show(browser, notificationID, messageString, anchorID, null, null, options); @@ -273,17 +263,14 @@ const gXPInstallObserver = { messageString = gNavigatorBundle.getFormattedString("xpinstallPromptMessage", [brandShortName]); - let secHistogram = Components.classes["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry).getHistogramById("SECURITY_UI"); action = { label: gNavigatorBundle.getString("xpinstallPromptAllowButton"), accessKey: gNavigatorBundle.getString("xpinstallPromptAllowButton.accesskey"), callback: function() { - secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_ADDON_ASKING_PREVENTED_CLICK_THROUGH); installInfo.install(); } }; - secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_ADDON_ASKING_PREVENTED); let popup = PopupNotifications.show(browser, notificationID, messageString, anchorID, action, null, options); diff --git a/application/basilisk/base/content/browser-context.inc b/application/basilisk/base/content/browser-context.inc index 36e0478af..d400cd0b2 100644 --- a/application/basilisk/base/content/browser-context.inc +++ b/application/basilisk/base/content/browser-context.inc @@ -51,23 +51,11 @@ label="&openLinkCmdInCurrent.label;" accesskey="&openLinkCmdInCurrent.accesskey;" oncommand="gContextMenu.openLinkInCurrent();"/> -# label and data-usercontextid are dynamically set. - <menuitem id="context-openlinkincontainertab" - accesskey="&openLinkCmdInTab.accesskey;" - oncommand="gContextMenu.openLinkInTab(event);"/> +# label is dynamically set. <menuitem id="context-openlinkintab" label="&openLinkCmdInTab.label;" accesskey="&openLinkCmdInTab.accesskey;" - data-usercontextid="0" - oncommand="gContextMenu.openLinkInTab(event);"/> - - <menu id="context-openlinkinusercontext-menu" - label="&openLinkCmdInContainerTab.label;" - accesskey="&openLinkCmdInContainerTab.accesskey;" - hidden="true"> - <menupopup oncommand="gContextMenu.openLinkInTab(event);" - onpopupshowing="return gContextMenu.createContainerMenu(event);" /> - </menu> + oncommand="gContextMenu.openLinkInTab();"/> <menuitem id="context-openlink" label="&openLinkCmd.label;" @@ -261,13 +249,6 @@ accesskey="&savePageCmd.accesskey2;" oncommand="gContextMenu.savePageAs();"/> <menuseparator id="context-sep-sendpagetodevice" hidden="true"/> - <menu id="context-sendpagetodevice" - label="&sendPageToDevice.label;" - accesskey="&sendPageToDevice.accesskey;" - hidden="true"> - <menupopup id="context-sendpagetodevice-popup" - onpopupshowing="(() => { let browser = gBrowser || getPanelBrowser(); gFxAccounts.populateSendTabToDevicesMenu(event.target, browser.currentURI.spec, browser.contentTitle); })()"/> - </menu> <menuseparator id="context-sep-viewbgimage"/> <menuitem id="context-viewbgimage" label="&viewBGImageCmd.label;" @@ -308,13 +289,6 @@ <menuitem id="context-searchselect" oncommand="BrowserSearch.loadSearchFromContext(this.searchTerms);"/> <menuseparator id="context-sep-sendlinktodevice" hidden="true"/> - <menu id="context-sendlinktodevice" - label="&sendLinkToDevice.label;" - accesskey="&sendLinkToDevice.accesskey;" - hidden="true"> - <menupopup id="context-sendlinktodevice-popup" - onpopupshowing="gFxAccounts.populateSendTabToDevicesMenu(event.target, gContextMenu.linkURL, gContextMenu.linkTextStr);"/> - </menu> <menuseparator id="frame-sep"/> <menu id="frame" label="&thisFrameMenu.label;" accesskey="&thisFrameMenu.accesskey;"> <menupopup> diff --git a/application/basilisk/base/content/browser-doctype.inc b/application/basilisk/base/content/browser-doctype.inc index ad08f4b03..30d70ccea 100644 --- a/application/basilisk/base/content/browser-doctype.inc +++ b/application/basilisk/base/content/browser-doctype.inc @@ -19,7 +19,9 @@ #endif <!ENTITY % aboutHomeDTD SYSTEM "chrome://browser/locale/aboutHome.dtd"> %aboutHomeDTD; +#ifdef MOZ_SERVICES_SYNC <!ENTITY % syncBrandDTD SYSTEM "chrome://browser/locale/syncBrand.dtd"> %syncBrandDTD; +#endif ]> diff --git a/application/basilisk/base/content/browser-fxaccounts.js b/application/basilisk/base/content/browser-fxaccounts.js deleted file mode 100644 index e1d556bff..000000000 --- a/application/basilisk/base/content/browser-fxaccounts.js +++ /dev/null @@ -1,314 +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/. */ - -var gFxAccounts = { - - _initialized: false, - _inCustomizationMode: false, - _cachedProfile: null, - - get weave() { - delete this.weave; - return this.weave = Cc["@mozilla.org/weave/service;1"] - .getService(Ci.nsISupports) - .wrappedJSObject; - }, - - get topics() { - // Do all this dance to lazy-load FxAccountsCommon. - delete this.topics; - return this.topics = [ - "weave:service:ready", - "weave:service:login:change", - "weave:service:setup-complete", - "weave:service:sync:error", - "weave:ui:login:error", - this.FxAccountsCommon.ONLOGIN_NOTIFICATION, - this.FxAccountsCommon.ONLOGOUT_NOTIFICATION, - this.FxAccountsCommon.ON_PROFILE_CHANGE_NOTIFICATION, - ]; - }, - - get panelUIFooter() { - delete this.panelUIFooter; - return this.panelUIFooter = document.getElementById("PanelUI-footer-fxa"); - }, - - get panelUIStatus() { - delete this.panelUIStatus; - return this.panelUIStatus = document.getElementById("PanelUI-fxa-status"); - }, - - get panelUIAvatar() { - delete this.panelUIAvatar; - return this.panelUIAvatar = document.getElementById("PanelUI-fxa-avatar"); - }, - - get panelUILabel() { - delete this.panelUILabel; - return this.panelUILabel = document.getElementById("PanelUI-fxa-label"); - }, - - get panelUIIcon() { - delete this.panelUIIcon; - return this.panelUIIcon = document.getElementById("PanelUI-fxa-icon"); - }, - - get strings() { - delete this.strings; - return this.strings = Services.strings.createBundle( - "chrome://browser/locale/accounts.properties" - ); - }, - - get loginFailed() { - // Referencing Weave.Service will implicitly initialize sync, and we don't - // want to force that - so first check if it is ready. - let service = Cc["@mozilla.org/weave/service;1"] - .getService(Components.interfaces.nsISupports) - .wrappedJSObject; - if (!service.ready) { - return false; - } - // LOGIN_FAILED_LOGIN_REJECTED explicitly means "you must log back in". - // All other login failures are assumed to be transient and should go - // away by themselves, so aren't reflected here. - return Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED; - }, - - init: function () { - // Bail out if we're already initialized and for pop-up windows. - if (this._initialized || !window.toolbar.visible) { - return; - } - - for (let topic of this.topics) { - Services.obs.addObserver(this, topic, false); - } - - gNavToolbox.addEventListener("customizationstarting", this); - gNavToolbox.addEventListener("customizationending", this); - - EnsureFxAccountsWebChannel(); - this._initialized = true; - - this.updateUI(); - }, - - uninit: function () { - if (!this._initialized) { - return; - } - - for (let topic of this.topics) { - Services.obs.removeObserver(this, topic); - } - - this._initialized = false; - }, - - observe: function (subject, topic, data) { - switch (topic) { - case this.FxAccountsCommon.ON_PROFILE_CHANGE_NOTIFICATION: - this._cachedProfile = null; - // Fallthrough intended - default: - this.updateUI(); - break; - } - }, - - handleEvent: function (event) { - this._inCustomizationMode = event.type == "customizationstarting"; - this.updateAppMenuItem(); - }, - - updateUI: function () { - // It's possible someone signed in to FxA after seeing our notification - // about "Legacy Sync migration" (which now is actually "Legacy Sync - // auto-disconnect") so kill that notification if it still exists. - let nb = window.document.getElementById("global-notificationbox"); - let n = nb.getNotificationWithValue(this.SYNC_MIGRATION_NOTIFICATION_TITLE); - if (n) { - nb.removeNotification(n, true); - } - - this.updateAppMenuItem(); - }, - - // Note that updateAppMenuItem() returns a Promise that's only used by tests. - updateAppMenuItem: function () { - let profileInfoEnabled = false; - try { - profileInfoEnabled = Services.prefs.getBoolPref("identity.fxaccounts.profile_image.enabled"); - } catch (e) { } - - this.panelUIFooter.hidden = false; - - // Make sure the button is disabled in customization mode. - if (this._inCustomizationMode) { - this.panelUIStatus.setAttribute("disabled", "true"); - this.panelUILabel.setAttribute("disabled", "true"); - this.panelUIAvatar.setAttribute("disabled", "true"); - this.panelUIIcon.setAttribute("disabled", "true"); - } else { - this.panelUIStatus.removeAttribute("disabled"); - this.panelUILabel.removeAttribute("disabled"); - this.panelUIAvatar.removeAttribute("disabled"); - this.panelUIIcon.removeAttribute("disabled"); - } - - let defaultLabel = this.panelUIStatus.getAttribute("defaultlabel"); - let errorLabel = this.panelUIStatus.getAttribute("errorlabel"); - let unverifiedLabel = this.panelUIStatus.getAttribute("unverifiedlabel"); - let settingslabel = this.panelUIStatus.getAttribute("settingslabel"); - // The localization string is for the signed in text, but it's the default text as well - let defaultTooltiptext = this.panelUIStatus.getAttribute("signedinTooltiptext"); - - let updateWithUserData = (userData) => { - // Window might have been closed while fetching data. - if (window.closed) { - return; - } - - // Reset the button to its original state. - this.panelUILabel.setAttribute("label", defaultLabel); - this.panelUIStatus.setAttribute("tooltiptext", defaultTooltiptext); - this.panelUIFooter.removeAttribute("fxastatus"); - this.panelUIFooter.removeAttribute("fxaprofileimage"); - this.panelUIAvatar.style.removeProperty("list-style-image"); - - if (Weave.Status.service == Weave.CLIENT_NOT_CONFIGURED) { - // Leave the default state - return; - } - - if (this.loginFailed) { - this.panelUIFooter.setAttribute("fxastatus", "error"); - this.panelUILabel.setAttribute("label", errorLabel); - } else { - this.panelUIFooter.setAttribute("fxastatus", "signedin"); - this.panelUILabel.setAttribute("label", settingslabel); - this.panelUIStatus.setAttribute("tooltiptext", ""); - } - } - - let updateWithProfile = (profile) => { - if (profileInfoEnabled) { - if (profile.displayName) { - this.panelUILabel.setAttribute("label", profile.displayName); - } - if (profile.avatar) { - this.panelUIFooter.setAttribute("fxaprofileimage", "set"); - let bgImage = "url(\"" + profile.avatar + "\")"; - this.panelUIAvatar.style.listStyleImage = bgImage; - - let img = new Image(); - img.onerror = () => { - // Clear the image if it has trouble loading. Since this callback is asynchronous - // we check to make sure the image is still the same before we clear it. - if (this.panelUIAvatar.style.listStyleImage === bgImage) { - this.panelUIFooter.removeAttribute("fxaprofileimage"); - this.panelUIAvatar.style.removeProperty("list-style-image"); - } - }; - img.src = profile.avatar; - } - } - } - - return fxAccounts.getSignedInUser().then(userData => { - // userData may be null here when the user is not signed-in, but that's expected - updateWithUserData(userData); - // unverified users cause us to spew log errors fetching an OAuth token - // to fetch the profile, so don't even try in that case. - if (!userData || !userData.verified || !profileInfoEnabled) { - return null; // don't even try to grab the profile. - } - if (this._cachedProfile) { - return this._cachedProfile; - } - return fxAccounts.getSignedInUserProfile().catch(err => { - // Not fetching the profile is sad but the FxA logs will already have noise. - return null; - }); - }).then(profile => { - if (!profile) { - return; - } - updateWithProfile(profile); - this._cachedProfile = profile; // Try to avoid fetching the profile on every UI update - }).catch(error => { - // This is most likely in tests, were we quickly log users in and out. - // The most likely scenario is a user logged out, so reflect that. - // Bug 995134 calls for better errors so we could retry if we were - // sure this was the failure reason. - this.FxAccountsCommon.log.error("Error updating FxA account info", error); - updateWithUserData(null); - }); - }, - - onMenuPanelCommand: function () { - - switch (this.panelUIFooter.getAttribute("fxastatus")) { - case "signedin": - this.openPreferences(); - break; - case "error": - if (this.panelUIFooter.getAttribute("unverified")) { - this.openPreferences(); - } else { - this.openSignInAgainPage("menupanel"); - } - break; - default: - this.openPreferences(); - break; - } - - PanelUI.hide(); - }, - - openPreferences: function () { - openPreferences("paneSync", { urlParams: { entrypoint: "menupanel" } }); - }, - - openAccountsPage: function (action, urlParams={}) { - let params = new URLSearchParams(); - if (action) { - params.set("action", action); - } - for (let name in urlParams) { - if (urlParams[name] !== undefined) { - params.set(name, urlParams[name]); - } - } - let url = "about:accounts?" + params; - switchToTabHavingURI(url, true, { - replaceQueryString: true - }); - }, - - openSignInAgainPage: function (entryPoint) { - this.openAccountsPage("reauth", { entrypoint: entryPoint }); - }, - - updateTabContextMenu: function (aPopupMenu) { - // STUB - }, - - initPageContextMenu: function (contextMenu) { - // STUB - } -}; - -XPCOMUtils.defineLazyGetter(gFxAccounts, "FxAccountsCommon", function () { - return Cu.import("resource://gre/modules/FxAccountsCommon.js", {}); -}); - -XPCOMUtils.defineLazyModuleGetter(gFxAccounts, "fxaMigrator", - "resource://services-sync/FxaMigrator.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "EnsureFxAccountsWebChannel", - "resource://gre/modules/FxAccountsWebChannel.jsm"); diff --git a/application/basilisk/base/content/browser-menubar.inc b/application/basilisk/base/content/browser-menubar.inc index 41734711c..b6ab23be5 100644 --- a/application/basilisk/base/content/browser-menubar.inc +++ b/application/basilisk/base/content/browser-menubar.inc @@ -11,19 +11,12 @@ style="border:0px;padding:0px;margin:0px;-moz-appearance:none"> <menu id="file-menu" label="&fileMenu.label;" accesskey="&fileMenu.accesskey;"> - <menupopup id="menu_FilePopup" - onpopupshowing="updateUserContextUIVisibility();"> + <menupopup id="menu_FilePopup"> <menuitem id="menu_newNavigatorTab" label="&tabCmd.label;" command="cmd_newNavigatorTab" key="key_newNavigatorTab" accesskey="&tabCmd.accesskey;"/> - <menu id="menu_newUserContext" - label="&newUserContext.label;" - accesskey="&newUserContext.accesskey;" - hidden="true"> - <menupopup onpopupshowing="return createUserContextMenu(event);" /> - </menu> <menuitem id="menu_newNavigator" label="&newNavigatorCmd.label;" accesskey="&newNavigatorCmd.accesskey;" @@ -202,9 +195,6 @@ key="key_gotoHistory" observes="viewHistorySidebar" label="&historyButton.label;"/> - <menuitem id="menu_tabsSidebar" - observes="viewTabsSidebar" - label="&syncedTabs.sidebar.label;"/> </menupopup> </menu> <menuseparator/> @@ -324,11 +314,13 @@ key="key_sanitize" command="Tools:Sanitize"/> <menuseparator id="sanitizeSeparator"/> +#ifdef MOZ_SERVICES_SYNC <menuitem id="sync-tabs-menuitem" class="syncTabsMenuItem" - label="&syncTabsMenu3.label;" + label="&syncTabsMenu2.label;" oncommand="BrowserOpenSyncTabs();" - hidden="true"/> + disabled="true"/> +#endif <menuitem id="historyRestoreLastSession" label="&historyRestoreLastSession.label;" command="Browser:RestoreLastSession"/> @@ -447,11 +439,10 @@ accesskey="&toolsMenu.accesskey;" onpopupshowing="mirrorShow(this)"> <menupopup id="menu_ToolsPopup" -# We have to use setTimeout() here to avoid a flickering menu bar when opening -# the Tools menu, see bug 970769. This can be removed once we got rid of the -# event loop spinning in Weave.Status._authManager. - onpopupshowing="setTimeout(() => gSyncUI.updateUI());" - > +#ifdef MOZ_SERVICES_SYNC + onpopupshowing="gSyncUI.updateUI();" +#endif + > <menuitem id="menu_openDownloads" label="&downloads.label;" accesskey="&downloads.accesskey;" @@ -462,23 +453,19 @@ accesskey="&addons.accesskey;" key="key_openAddons" command="Tools:Addons"/> - - <!-- only one of sync-setup, sync-syncnowitem or sync-reauthitem will be showing at once --> +#ifdef MOZ_SERVICES_SYNC + <!-- only one of sync-setup or sync-menu will be showing at once --> <menuitem id="sync-setup" - label="&syncSignIn.label;" - accesskey="&syncSignIn.accesskey;" + label="&syncSetup.label;" + accesskey="&syncSetup.accesskey;" observes="sync-setup-state" - oncommand="gSyncUI.openSetup(null, 'menubar')"/> + oncommand="gSyncUI.openSetup()"/> <menuitem id="sync-syncnowitem" label="&syncSyncNowItem.label;" accesskey="&syncSyncNowItem.accesskey;" observes="sync-syncnow-state" oncommand="gSyncUI.doSync(event);"/> - <menuitem id="sync-reauthitem" - label="&syncReAuthItem.label;" - accesskey="&syncReAuthItem.accesskey;" - observes="sync-reauth-state" - oncommand="gSyncUI.openSignInAgainPage('menubar');"/> +#endif <menuseparator id="devToolsSeparator"/> <menu id="webDeveloperMenu" label="&webDeveloperMenu.label;" diff --git a/application/basilisk/base/content/browser-places.js b/application/basilisk/base/content/browser-places.js index 83c737977..87734140f 100644 --- a/application/basilisk/base/content/browser-places.js +++ b/application/basilisk/base/content/browser-places.js @@ -804,18 +804,29 @@ HistoryMenu.prototype = { }, toggleTabsFromOtherComputers: function PHM_toggleTabsFromOtherComputers() { + // This is a no-op if MOZ_SERVICES_SYNC isn't defined +#ifdef MOZ_SERVICES_SYNC // Enable/disable the Tabs From Other Computers menu. Some of the menus handled // by HistoryMenu do not have this menuitem. let menuitem = this._rootElt.getElementsByClassName("syncTabsMenuItem")[0]; if (!menuitem) return; - if (!PlacesUIUtils.shouldShowTabsFromOtherComputersMenuitem()) { + // If Sync isn't configured yet, then don't show the menuitem. + if (Weave.Status.checkSetup() == Weave.CLIENT_NOT_CONFIGURED || + Weave.Svc.Prefs.get("firstSync", "") == "notReady") { menuitem.setAttribute("hidden", true); return; } + // The tabs engine might never be inited (if services.sync.registerEngines + // is modified), so make sure we avoid undefined errors. + let enabled = Weave.Service.isLoggedIn && + Weave.Service.engineManager.get("tabs") && + Weave.Service.engineManager.get("tabs").enabled; + menuitem.setAttribute("disabled", !enabled); menuitem.setAttribute("hidden", false); +#endif }, _onPopupShowing: function HM__onPopupShowing(aEvent) { diff --git a/application/basilisk/base/content/browser-sets.inc b/application/basilisk/base/content/browser-sets.inc index 6ea057d93..d6a9310ed 100644 --- a/application/basilisk/base/content/browser-sets.inc +++ b/application/basilisk/base/content/browser-sets.inc @@ -163,16 +163,13 @@ <!-- A broadcaster of a number of attributes suitable for "sync now" UI - A 'syncstatus' attribute is set while actively syncing, and the label attribute which changes from "sync now" to "syncing" etc. --> +#ifdef MOZ_SERVICES_SYNC <broadcaster id="sync-status"/> <!-- broadcasters of the "hidden" attribute to reflect setup state for menus --> <broadcaster id="sync-setup-state"/> <broadcaster id="sync-syncnow-state" hidden="true"/> - <broadcaster id="sync-reauth-state" hidden="true"/> - <broadcaster id="viewTabsSidebar" autoCheck="false" sidebartitle="&syncedTabs.sidebar.label;" - type="checkbox" group="sidebar" - sidebarurl="chrome://browser/content/syncedtabs/sidebar.xhtml" - oncommand="SidebarUI.toggle('viewTabsSidebar');"/> +#endif <broadcaster id="workOfflineMenuitemState"/> <broadcaster id="devtoolsMenuBroadcaster_ErrorConsole" diff --git a/application/basilisk/base/content/browser-syncui.js b/application/basilisk/base/content/browser-syncui.js index 3a57140f2..f57472658 100644 --- a/application/basilisk/base/content/browser-syncui.js +++ b/application/basilisk/base/content/browser-syncui.js @@ -1,63 +1,37 @@ -/* 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 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/. -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); - -#ifdef MOZ_SERVICES_CLOUDSYNC -XPCOMUtils.defineLazyModuleGetter(this, "CloudSync", - "resource://gre/modules/CloudSync.jsm"); -#endif - -XPCOMUtils.defineLazyModuleGetter(this, "fxAccounts", - "resource://gre/modules/FxAccounts.jsm"); - -const MIN_STATUS_ANIMATION_DURATION = 1600; - -// gSyncUI handles updating the tools menu and displaying notifications. +// gSyncUI handles updating the tools menu var gSyncUI = { _obs: ["weave:service:sync:start", - "weave:service:sync:finish", - "weave:service:sync:error", + "weave:service:sync:delayed", "weave:service:quota:remaining", "weave:service:setup-complete", "weave:service:login:start", "weave:service:login:finish", - "weave:service:login:error", "weave:service:logout:finish", "weave:service:start-over", - "weave:service:start-over:finish", "weave:ui:login:error", "weave:ui:sync:error", "weave:ui:sync:finish", "weave:ui:clear-error", - "weave:engine:sync:finish" ], _unloaded: false, - // The last sync start time. Used to calculate the leftover animation time - // once syncing completes (bug 1239042). - _syncStartTime: 0, - _syncAnimationTimer: 0, - - init: function () { - Cu.import("resource://services-common/stringbundle.js"); + init: function SUI_init() { // Proceed to set up the UI if Sync has already started up. // Otherwise we'll do it when Sync is firing up. - if (this.weaveService.ready) { + let xps = Components.classes["@mozilla.org/weave/service;1"] + .getService(Components.interfaces.nsISupports) + .wrappedJSObject; + if (xps.ready) { this.initUI(); return; } - // Sync isn't ready yet, but we can still update the UI with an initial - // state - we haven't called initUI() yet, but that's OK - that's more - // about observers for state changes, and will be called once Sync is - // ready to start sending notifications. - this.updateUI(); - Services.obs.addObserver(this, "weave:service:ready", true); - Services.obs.addObserver(this, "quit-application", true); // Remove the observer if the window is closed before the observer // was triggered. @@ -65,7 +39,6 @@ var gSyncUI = { gSyncUI._unloaded = true; window.removeEventListener("unload", onUnload, false); Services.obs.removeObserver(gSyncUI, "weave:service:ready"); - Services.obs.removeObserver(gSyncUI, "quit-application"); if (Weave.Status.ready) { gSyncUI._obs.forEach(function(topic) { @@ -85,161 +58,136 @@ var gSyncUI = { Services.obs.addObserver(this, topic, true); }, this); - // initial label for the sync buttons. - let broadcaster = document.getElementById("sync-status"); - broadcaster.setAttribute("label", this._stringBundle.GetStringFromName("syncnow.label")); - - this.maybeMoveSyncedTabsButton(); - + if (gBrowser && Weave.Notifications.notifications.length) { + this.initNotifications(); + } this.updateUI(); }, + initNotifications: function SUI_initNotifications() { + const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; + let notificationbox = document.createElementNS(XULNS, "notificationbox"); + notificationbox.id = "sync-notifications"; + notificationbox.setAttribute("flex", "1"); - // Returns a promise that resolves with true if Sync needs to be configured, - // false otherwise. - _needsSetup() { - // If Sync is configured for FxAccounts then we do that promise-dance. - if (this.weaveService.fxAccountsEnabled) { - return fxAccounts.getSignedInUser().then(user => { - // We want to treat "account needs verification" as "needs setup". - return !(user && user.verified); - }); - } - // We are using legacy sync - check that. - let firstSync = ""; - try { - firstSync = Services.prefs.getCharPref("services.sync.firstSync"); - } catch (e) { } - - return Promise.resolve(Weave.Status.checkSetup() == Weave.CLIENT_NOT_CONFIGURED || - firstSync == "notReady"); + let bottombox = document.getElementById("browser-bottombox"); + bottombox.insertBefore(notificationbox, bottombox.firstChild); + + // Force a style flush to ensure that our binding is attached. + notificationbox.clientTop; + + // notificationbox will listen to observers from now on. + Services.obs.removeObserver(this, "weave:notification:added"); }, - // Returns a promise that resolves with true if the user currently signed in - // to Sync needs to be verified, false otherwise. - _needsVerification() { - // For callers who care about the distinction between "needs setup" and - // "needs verification" - if (this.weaveService.fxAccountsEnabled) { - return fxAccounts.getSignedInUser().then(user => { - // If there is no user, they can't be in a "needs verification" state. - if (!user) { - return false; - } - return !user.verified; - }); - } + _wasDelayed: false, - // Otherwise we are configured for legacy Sync, which has no verification - // concept. - return Promise.resolve(false); + _needsSetup: function SUI__needsSetup() { + let firstSync = Services.prefs.getCharPref("services.sync.firstSync", ""); + return Weave.Status.checkSetup() == Weave.CLIENT_NOT_CONFIGURED || + firstSync == "notReady"; }, - // Note that we don't show login errors in a notification bar here, but do - // still need to track a login-failed state so the "Tools" menu updates - // with the correct state. - _loginFailed: function () { - // If Sync isn't already ready, we don't want to force it to initialize - // by referencing Weave.Status - and it isn't going to be accurate before - // Sync is ready anyway. - if (!this.weaveService.ready) { - this.log.debug("_loginFailed has sync not ready, so returning false"); - return false; + updateUI: function SUI_updateUI() { + let needsSetup = this._needsSetup(); + document.getElementById("sync-setup-state").hidden = !needsSetup; + document.getElementById("sync-syncnow-state").hidden = needsSetup; + + if (!gBrowser) { + return; } - this.log.debug("_loginFailed has sync state=${sync}", - { sync: Weave.Status.login}); - return Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED; - }, - // Kick off an update of the UI - does *not* return a promise. - updateUI() { - this._promiseUpdateUI().catch(err => { - this.log.error("updateUI failed", err); - }) - }, + let button = document.getElementById("sync-button"); + if (!button) { + return; + } - // Updates the UI - returns a promise. - _promiseUpdateUI() { - return this._needsSetup().then(needsSetup => { - if (!gBrowser) - return Promise.resolve(); - - let loginFailed = this._loginFailed(); - - // Start off with a clean slate - document.getElementById("sync-reauth-state").hidden = true; - document.getElementById("sync-setup-state").hidden = true; - document.getElementById("sync-syncnow-state").hidden = true; - -#ifdef MOZ_SERVICES_CLOUDSYNC - if (CloudSync && CloudSync.ready && CloudSync().adapters.count) { - document.getElementById("sync-syncnow-state").hidden = false; - } else if (loginFailed) { -#else - if (loginFailed) { -#endif - // unhiding this element makes the menubar show the login failure state. - document.getElementById("sync-reauth-state").hidden = false; - } else if (needsSetup) { - document.getElementById("sync-setup-state").hidden = false; - } else { - document.getElementById("sync-syncnow-state").hidden = false; - } + button.removeAttribute("status"); + + this._updateLastSyncTime(); - return this._updateSyncButtonsTooltip(); - }); + if (needsSetup) { + button.removeAttribute("tooltiptext"); + button.setAttribute("label", this._stringBundle.GetStringFromName("setupsync.label")); + } else { + button.setAttribute("label", this._stringBundle.GetStringFromName("syncnow.label")); + } }, + // Functions called by observers - onActivityStart() { + onActivityStart: function SUI_onActivityStart() { if (!gBrowser) return; - this.log.debug("onActivityStart"); + let button = document.getElementById("sync-button"); + if (!button) + return; - clearTimeout(this._syncAnimationTimer); - this._syncStartTime = Date.now(); + button.setAttribute("status", "active"); + button.setAttribute("label", this._stringBundle.GetStringFromName("syncing2.label")); + }, - let broadcaster = document.getElementById("sync-status"); - broadcaster.setAttribute("syncstatus", "active"); - broadcaster.setAttribute("label", this._stringBundle.GetStringFromName("syncing2.label")); - broadcaster.setAttribute("disabled", "true"); + onSyncDelay: function SUI_onSyncDelay() { + // basically, we want to just inform users that stuff is going to take a while + let title = this._stringBundle.GetStringFromName("error.sync.no_node_found.title"); + let description = this._stringBundle.GetStringFromName("error.sync.no_node_found"); + let buttons = [new Weave.NotificationButton( + this._stringBundle.GetStringFromName("error.sync.serverStatusButton.label"), + this._stringBundle.GetStringFromName("error.sync.serverStatusButton.accesskey"), + function() { gSyncUI.openServerStatus(); return true; } + )]; + let notification = new Weave.Notification( + title, description, null, Weave.Notifications.PRIORITY_INFO, buttons); + Weave.Notifications.replaceTitle(notification); + this._wasDelayed = true; + }, - this.updateUI(); + onLoginFinish: function SUI_onLoginFinish() { + // Clear out any login failure notifications + let title = this._stringBundle.GetStringFromName("error.login.title"); + this.clearError(title); }, - _updateSyncStatus() { - if (!gBrowser) - return; - let broadcaster = document.getElementById("sync-status"); - broadcaster.removeAttribute("syncstatus"); - broadcaster.removeAttribute("disabled"); - broadcaster.setAttribute("label", this._stringBundle.GetStringFromName("syncnow.label")); - this.updateUI(); + onSetupComplete: function SUI_onSetupComplete() { + this.onLoginFinish(); }, - onActivityStop() { - if (!gBrowser) + onLoginError: function SUI_onLoginError() { + // if login fails, any other notifications are essentially moot + Weave.Notifications.removeAll(); + + // if we haven't set up the client, don't show errors + if (this._needsSetup()) { + this.updateUI(); return; - this.log.debug("onActivityStop"); + } - let now = Date.now(); - let syncDuration = now - this._syncStartTime; + let title = this._stringBundle.GetStringFromName("error.login.title"); - if (syncDuration < MIN_STATUS_ANIMATION_DURATION) { - let animationTime = MIN_STATUS_ANIMATION_DURATION - syncDuration; - clearTimeout(this._syncAnimationTimer); - this._syncAnimationTimer = setTimeout(() => this._updateSyncStatus(), animationTime); + let description; + if (Weave.Status.sync == Weave.PROLONGED_SYNC_FAILURE) { + // Convert to days + let lastSync = + Services.prefs.getIntPref("services.sync.errorhandler.networkFailureReportTimeout") / 86400; + description = + this._stringBundle.formatStringFromName("error.sync.prolonged_failure", [lastSync], 1); } else { - this._updateSyncStatus(); + let reason = Weave.Utils.getErrorString(Weave.Status.login); + description = + this._stringBundle.formatStringFromName("error.sync.description", [reason], 1); } - }, - onLoginError: function SUI_onLoginError() { - this.log.debug("onLoginError: login=${login}, sync=${sync}", Weave.Status); + let buttons = []; + buttons.push(new Weave.NotificationButton( + this._stringBundle.GetStringFromName("error.login.prefs.label"), + this._stringBundle.GetStringFromName("error.login.prefs.accesskey"), + function() { gSyncUI.openPrefs(); return true; } + )); - // We don't show any login errors here; browser-fxaccounts shows them in - // the hamburger menu. + let notification = new Weave.Notification(title, description, null, + Weave.Notifications.PRIORITY_WARNING, buttons); + Weave.Notifications.replaceTitle(notification); this.updateUI(); }, @@ -247,6 +195,10 @@ var gSyncUI = { this.updateUI(); }, + onStartOver: function SUI_onStartOver() { + this.clearError(); + }, + onQuotaNotice: function onQuotaNotice(subject, data) { let title = this._stringBundle.GetStringFromName("warning.sync.quota.label"); let description = this._stringBundle.GetStringFromName("warning.sync.quota.description"); @@ -262,40 +214,26 @@ var gSyncUI = { Weave.Notifications.replaceTitle(notification); }, - _getAppName: function () { - let brand = new StringBundle("chrome://branding/locale/brand.properties"); - return brand.get("brandShortName"); + openServerStatus: function () { + let statusURL = Services.prefs.getCharPref("services.sync.statusURL"); + window.openUILinkIn(statusURL, "tab"); }, // Commands - // doSync forces a sync - it *does not* return a promise as it is called - // via the various UI components. - doSync() { - this._needsSetup().then(needsSetup => { - if (!needsSetup) { - setTimeout(() => Weave.Service.errorHandler.syncAndReportErrors(), 0); - } - Services.obs.notifyObservers(null, "cloudsync:user-sync", null); - }).catch(err => { - this.log.error("Failed to force a sync", err); - }); + doSync: function SUI_doSync() { + setTimeout(function() Weave.Service.errorHandler.syncAndReportErrors(), 0); }, - // Handle clicking the toolbar button - which either opens the Sync setup - // pages or forces a sync now. Does *not* return a promise as it is called - // via the UI. - handleToolbarButton() { - this._needsSetup().then(needsSetup => { - if (needsSetup || this._loginFailed()) { - this.openSetup(); - } else { - this.doSync(); - } - }).catch(err => { - this.log.error("Failed to handle toolbar button command", err); - }); + handleToolbarButton: function SUI_handleStatusbarButton() { + if (this._needsSetup()) + this.openSetup(); + else + this.doSync(); }, + //XXXzpao should be part of syncCommon.js - which we might want to make a module... + // To be fixed in a followup (bug 583366) + /** * Invoke the Sync setup wizard. * @@ -304,11 +242,9 @@ var gSyncUI = { * null -- regular set up wizard * "pair" -- pair a device first * "reset" -- reset sync - * @param entryPoint - * Indicates the entrypoint from where this method was called. */ - openSetup: function SUI_openSetup(wizardType, entryPoint = "syncbutton") { + openSetup: function SUI_openSetup(wizardType) { let win = Services.wm.getMostRecentWindow("Weave:AccountSetup"); if (win) win.focus(); @@ -319,7 +255,6 @@ var gSyncUI = { } }, - // Open the legacy-sync device pairing UI. Note used for FxA Sync. openAddDevice: function () { if (!Weave.Utils.ensureMPUnlocked()) return; @@ -332,202 +267,181 @@ var gSyncUI = { "syncAddDevice", "centerscreen,chrome,resizable=no"); }, - openPrefs: function (entryPoint) { - openPreferences("paneSync", { urlParams: { entrypoint: entryPoint } }); + openQuotaDialog: function SUI_openQuotaDialog() { + let win = Services.wm.getMostRecentWindow("Sync:ViewQuota"); + if (win) + win.focus(); + else + Services.ww.activeWindow.openDialog( + "chrome://browser/content/sync/quota.xul", "", + "centerscreen,chrome,dialog,modal"); }, - openSignInAgainPage: function (entryPoint = "syncbutton") { - gFxAccounts.openSignInAgainPage(entryPoint); + openPrefs: function SUI_openPrefs() { + openPreferences("paneSync"); }, - /* After Sync is initialized we perform a once-only check for the sync - button being in "customize purgatory" and if so, move it to the panel. - This is done primarily for profiles created before SyncedTabs landed, - where the button defaulted to being in that purgatory. - We use a preference to ensure we only do it once, so people can still - customize it away and have it stick. - */ - maybeMoveSyncedTabsButton() { - const prefName = "browser.migrated-sync-button"; - let migrated = false; - try { - migrated = Services.prefs.getBoolPref(prefName); - } catch (_) {} - if (migrated) { + // Helpers + _updateLastSyncTime: function SUI__updateLastSyncTime() { + if (!gBrowser) return; - } - if (!CustomizableUI.getPlacementOfWidget("sync-button")) { - CustomizableUI.addWidgetToArea("sync-button", CustomizableUI.AREA_PANEL); - } - Services.prefs.setBoolPref(prefName, true); - }, - /* Update the tooltip for the sync-status broadcaster (which will update the - Sync Toolbar button and the Sync spinner in the FxA hamburger area.) - If Sync is configured, the tooltip is when the last sync occurred, - otherwise the tooltip reflects the fact that Sync needs to be - (re-)configured. - */ - _updateSyncButtonsTooltip: Task.async(function* () { - if (!gBrowser) + let syncButton = document.getElementById("sync-button"); + if (!syncButton) return; - let email; - try { - email = Services.prefs.getCharPref("services.sync.username"); - } catch (ex) {} - - let needsSetup = yield this._needsSetup(); - let needsVerification = yield this._needsVerification(); - let loginFailed = this._loginFailed(); - // This is a little messy as the Sync buttons are 1/2 Sync related and - // 1/2 FxA related - so for some strings we use Sync strings, but for - // others we reach into gFxAccounts for strings. - let tooltiptext; - if (needsVerification) { - // "needs verification" - tooltiptext = gFxAccounts.strings.formatStringFromName("verifyDescription", [email], 1); - } else if (needsSetup) { - // "needs setup". - tooltiptext = this._stringBundle.GetStringFromName("signInToSync.description"); - } else if (loginFailed) { - // "need to reconnect/re-enter your password" - tooltiptext = gFxAccounts.strings.formatStringFromName("reconnectDescription", [email], 1); - } else { - // Sync appears configured - format the "last synced at" time. - try { - let lastSync = new Date(Services.prefs.getCharPref("services.sync.lastSync")); - tooltiptext = this.formatLastSyncDate(lastSync); - } - catch (e) { - // pref doesn't exist (which will be the case until we've seen the - // first successful sync) or is invalid (which should be impossible!) - // Just leave tooltiptext as the empty string in these cases, which - // will cause the tooltip to be removed below. - } + let lastSync = Services.prefs.getCharPref("services.sync.lastSync", ""); + if (!lastSync || this._needsSetup()) { + syncButton.removeAttribute("tooltiptext"); + return; } - // We've done all our promise-y work and ready to update the UI - make - // sure it hasn't been torn down since we started. - if (!gBrowser) - return; + // Show the day-of-week and time (HH:MM) of last sync + let lastSyncDate = new Date(lastSync).toLocaleFormat("%a %H:%M"); + let lastSyncLabel = + this._stringBundle.formatStringFromName("lastSync2.label", [lastSyncDate], 1); - let broadcaster = document.getElementById("sync-status"); - if (broadcaster) { - if (tooltiptext) { - broadcaster.setAttribute("tooltiptext", tooltiptext); - } else { - broadcaster.removeAttribute("tooltiptext"); - } - } - }), - - formatLastSyncDate: function(date) { - let dateFormat; - let sixDaysAgo = (() => { - let date = new Date(); - date.setDate(date.getDate() - 6); - date.setHours(0, 0, 0, 0); - return date; - })(); - // It may be confusing for the user to see "Last Sync: Monday" when the last sync was a indeed a Monday but 3 weeks ago - if (date < sixDaysAgo) { - dateFormat = {month: 'long', day: 'numeric'}; - } else { - dateFormat = {weekday: 'long', hour: 'numeric', minute: 'numeric'}; - } - let lastSyncDateString = date.toLocaleDateString(undefined, dateFormat); - return this._stringBundle.formatStringFromName("lastSync2.label", [lastSyncDateString], 1); + syncButton.setAttribute("tooltiptext", lastSyncLabel); }, - onClientsSynced: function() { - let broadcaster = document.getElementById("sync-syncnow-state"); - if (broadcaster) { - if (Weave.Service.clientsEngine.stats.numClients > 1) { - broadcaster.setAttribute("devices-status", "multi"); - } else { - broadcaster.setAttribute("devices-status", "single"); - } + clearError: function SUI_clearError(errorString) { + Weave.Notifications.removeAll(errorString); + this.updateUI(); + }, + + onSyncFinish: function SUI_onSyncFinish() { + let title = this._stringBundle.GetStringFromName("error.sync.title"); + + // Clear out sync failures on a successful sync + this.clearError(title); + + if (this._wasDelayed && Weave.Status.sync != Weave.NO_SYNC_NODE_FOUND) { + title = this._stringBundle.GetStringFromName("error.sync.no_node_found.title"); + this.clearError(title); + this._wasDelayed = false; } }, onSyncError: function SUI_onSyncError() { - this.log.debug("onSyncError: login=${login}, sync=${sync}", Weave.Status); let title = this._stringBundle.GetStringFromName("error.sync.title"); - let error = Weave.Utils.getErrorString(Weave.Status.sync); - let description = + + if (Weave.Status.login != Weave.LOGIN_SUCCEEDED) { + this.onLoginError(); + return; + } + + let description; + if (Weave.Status.sync == Weave.PROLONGED_SYNC_FAILURE) { + // Convert to days + let lastSync = + Services.prefs.getIntPref("services.sync.errorhandler.networkFailureReportTimeout") / 86400; + description = + this._stringBundle.formatStringFromName("error.sync.prolonged_failure", [lastSync], 1); + } else { + let error = Weave.Utils.getErrorString(Weave.Status.sync); + description = this._stringBundle.formatStringFromName("error.sync.description", [error], 1); + } let priority = Weave.Notifications.PRIORITY_WARNING; let buttons = []; - if (Weave.Status.sync == Weave.OVER_QUOTA) { - description = this._stringBundle.GetStringFromName("error.sync.quota.description"); + // Check if the client is outdated in some way + let outdated = Weave.Status.sync == Weave.VERSION_OUT_OF_DATE; + for (let [engine, reason] in Iterator(Weave.Status.engines)) + outdated = outdated || reason == Weave.VERSION_OUT_OF_DATE; + + if (outdated) { + description = this._stringBundle.GetStringFromName( + "error.sync.needUpdate.description"); + buttons.push(new Weave.NotificationButton( + this._stringBundle.GetStringFromName("error.sync.needUpdate.label"), + this._stringBundle.GetStringFromName("error.sync.needUpdate.accesskey"), + function() { + window.openUILinkIn(Services.prefs.getCharPref("services.sync.outdated.url"), "tab"); + return true; + } + )); + } + else if (Weave.Status.sync == Weave.OVER_QUOTA) { + description = this._stringBundle.GetStringFromName( + "error.sync.quota.description"); buttons.push(new Weave.NotificationButton( - this._stringBundle.GetStringFromName("error.sync.viewQuotaButton.label"), - this._stringBundle.GetStringFromName("error.sync.viewQuotaButton.accesskey"), + this._stringBundle.GetStringFromName( + "error.sync.viewQuotaButton.label"), + this._stringBundle.GetStringFromName( + "error.sync.viewQuotaButton.accesskey"), function() { gSyncUI.openQuotaDialog(); return true; } ) ); - // Only show the notification bar on Quota error. the panel will show the rest. - let notification = - new Weave.Notification(title, description, null, priority, buttons); - Weave.Notifications.replaceTitle(notification); + } + else if (Weave.Status.enforceBackoff) { + priority = Weave.Notifications.PRIORITY_INFO; + buttons.push(new Weave.NotificationButton( + this._stringBundle.GetStringFromName("error.sync.serverStatusButton.label"), + this._stringBundle.GetStringFromName("error.sync.serverStatusButton.accesskey"), + function() { gSyncUI.openServerStatus(); return true; } + )); + } + else { + priority = Weave.Notifications.PRIORITY_INFO; + buttons.push(new Weave.NotificationButton( + this._stringBundle.GetStringFromName("error.sync.tryAgainButton.label"), + this._stringBundle.GetStringFromName("error.sync.tryAgainButton.accesskey"), + function() { gSyncUI.doSync(); return true; } + )); + } + + let notification = + new Weave.Notification(title, description, null, priority, buttons); + Weave.Notifications.replaceTitle(notification); + + if (this._wasDelayed && Weave.Status.sync != Weave.NO_SYNC_NODE_FOUND) { + title = this._stringBundle.GetStringFromName("error.sync.no_node_found.title"); + Weave.Notifications.removeAll(title); + this._wasDelayed = false; } this.updateUI(); }, - observe: function SUI_observe(subject, topic, data) { - this.log.debug("observed", topic); if (this._unloaded) { Cu.reportError("SyncUI observer called after unload: " + topic); return; } - // Unwrap, just like Svc.Obs, but without pulling in that dependency. - if (subject && typeof subject == "object" && - ("wrappedJSObject" in subject) && - ("observersModuleSubjectWrapper" in subject.wrappedJSObject)) { - subject = subject.wrappedJSObject.object; - } - - // First handle "activity" only. switch (topic) { case "weave:service:sync:start": this.onActivityStart(); break; - case "weave:service:sync:finish": - case "weave:service:sync:error": - this.onActivityStop(); - break; - } - // Now non-activity state (eg, enabled, errors, etc) - // Note that sync uses the ":ui:" notifications for errors because sync. - switch (topic) { case "weave:ui:sync:finish": - // Do nothing. + this.onSyncFinish(); break; case "weave:ui:sync:error": this.onSyncError(); break; - case "weave:service:setup-complete": - case "weave:service:login:finish": - case "weave:service:login:start": - case "weave:service:start-over": - this.updateUI(); + case "weave:service:sync:delayed": + this.onSyncDelay(); break; case "weave:service:quota:remaining": this.onQuotaNotice(); break; + case "weave:service:setup-complete": + this.onSetupComplete(); + break; + case "weave:service:login:start": + this.onActivityStart(); + break; + case "weave:service:login:finish": + this.onLoginFinish(); + break; case "weave:ui:login:error": - case "weave:service:login:error": this.onLoginError(); break; case "weave:service:logout:finish": this.onLogout(); break; - case "weave:service:start-over:finish": - this.updateUI(); + case "weave:service:start-over": + this.onStartOver(); break; case "weave:service:ready": this.initUI(); @@ -535,16 +449,8 @@ var gSyncUI = { case "weave:notification:added": this.initNotifications(); break; - case "weave:engine:sync:finish": - if (data != "clients") { - return; - } - this.onClientsSynced(); - break; - case "quit-application": - // Stop the animation timer on shutdown, since we can't update the UI - // after this. - clearTimeout(this._syncAnimationTimer); + case "weave:ui:clear-error": + this.clearError(); break; } }, @@ -556,19 +462,10 @@ var gSyncUI = { }; XPCOMUtils.defineLazyGetter(gSyncUI, "_stringBundle", function() { - // XXXzpao these strings should probably be moved from /services to /browser... (bug 583381) + //XXXzpao these strings should probably be moved from /services to /browser... (bug 583381) // but for now just make it work return Cc["@mozilla.org/intl/stringbundle;1"]. getService(Ci.nsIStringBundleService). createBundle("chrome://weave/locale/services/sync.properties"); }); -XPCOMUtils.defineLazyGetter(gSyncUI, "log", function() { - return Log.repository.getLogger("browserwindow.syncui"); -}); - -XPCOMUtils.defineLazyGetter(gSyncUI, "weaveService", function() { - return Components.classes["@mozilla.org/weave/service;1"] - .getService(Components.interfaces.nsISupports) - .wrappedJSObject; -}); diff --git a/application/basilisk/base/content/browser.css b/application/basilisk/base/content/browser.css index 517c1c5eb..a2c2559d6 100644 --- a/application/basilisk/base/content/browser.css +++ b/application/basilisk/base/content/browser.css @@ -687,6 +687,18 @@ window[chromehidden~="toolbar"] toolbar:not(#nav-bar):not(#TabsToolbar):not(#pri min-width: 1px; } +%ifdef MOZ_SERVICES_SYNC +/* Sync notification UI */ +#sync-notifications { + -moz-binding: url("chrome://browser/content/sync/notification.xml#notificationbox"); + overflow-y: visible !important; +} + +#sync-notifications notification { + -moz-binding: url("chrome://browser/content/sync/notification.xml#notification"); +} +%endif + /* History Swipe Animation */ #historySwipeAnimationContainer { diff --git a/application/basilisk/base/content/browser.js b/application/basilisk/base/content/browser.js index 336670fa0..1dee19a1d 100644 --- a/application/basilisk/base/content/browser.js +++ b/application/basilisk/base/content/browser.js @@ -8,7 +8,6 @@ var Cu = Components.utils; var Cc = Components.classes; Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/ContextualIdentityService.jsm"); Cu.import("resource://gre/modules/NotificationDB.jsm"); // lazy module getters @@ -47,7 +46,6 @@ Cu.import("resource://gre/modules/NotificationDB.jsm"); ["Task", "resource://gre/modules/Task.jsm"], ["UpdateUtils", "resource://gre/modules/UpdateUtils.jsm"], ["Weave", "resource://services-sync/main.js"], - ["fxAccounts", "resource://gre/modules/FxAccounts.jsm"], #ifdef MOZ_DEVTOOLS // Note: Do not delete! It is used for: base/content/nsContextMenu.js ["gDevTools", "resource://devtools/client/framework/gDevTools.jsm"], @@ -104,6 +102,12 @@ XPCOMUtils.defineLazyGetter(this, "PageMenuParent", function() { return new tmp.PageMenuParent(); }); +#ifdef MOZ_SERVICES_SYNC +XPCOMUtils.defineLazyModuleGetter(this, "Weave", + "resource://services-sync/main.js"); +#endif + + XPCOMUtils.defineLazyGetter(this, "PopupNotifications", function () { let tmp = {}; Cu.import("resource://gre/modules/PopupNotifications.jsm", tmp); @@ -209,6 +213,10 @@ var gInitialPages = [ "about:logopage" ]; +#ifdef MOZ_SERVICES_SYNC +#include browser-syncui.js +#endif + function* browserWindows() { let windows = Services.wm.getEnumerator("navigator:browser"); while (windows.hasMoreElements()) @@ -827,10 +835,6 @@ function _loadURIWithFlags(browser, uri, params) { } try { if (!mustChangeProcess) { - if (params.userContextId) { - browser.webNavigation.setOriginAttributesBeforeLoading({ userContextId: params.userContextId }); - } - browser.webNavigation.loadURIWithOptions(uri, flags, referrer, referrerPolicy, postData, null, null, triggeringPrincipal); @@ -856,10 +860,6 @@ function _loadURIWithFlags(browser, uri, params) { postData: postData } - if (params.userContextId) { - loadParams.userContextId = params.userContextId; - } - LoadInOtherProcess(browser, loadParams); } } catch (e) { @@ -872,10 +872,6 @@ function _loadURIWithFlags(browser, uri, params) { Cu.reportError(e); gBrowser.updateBrowserRemotenessByURL(browser, uri); - if (params.userContextId) { - browser.webNavigation.setOriginAttributesBeforeLoading({ userContextId: params.userContextId }); - } - browser.webNavigation.loadURIWithOptions(uri, flags, referrer, referrerPolicy, postData, null, null, triggeringPrincipal); } else { @@ -939,16 +935,6 @@ addEventListener("DOMContentLoaded", function onDCL() { let initBrowser = document.getAnonymousElementByAttribute(gBrowser, "anonid", "initialBrowser"); - // The window's first argument is a tab if and only if we are swapping tabs. - // We must set the browser's usercontextid before updateBrowserRemoteness(), - // so that the newly created remote tab child has the correct usercontextid. - if (window.arguments) { - let tabToOpen = window.arguments[0]; - if (tabToOpen instanceof XULElement && tabToOpen.hasAttribute("usercontextid")) { - initBrowser.setAttribute("usercontextid", tabToOpen.getAttribute("usercontextid")); - } - } - gBrowser.updateBrowserRemoteness(initBrowser, gMultiProcessBrowser); }); @@ -1133,13 +1119,6 @@ var gBrowserInit = { // make sure it has a docshell gBrowser.docShell; - // We must set usercontextid before updateBrowserRemoteness() - // so that the newly created remote tab child has correct usercontextid - if (tabToOpen.hasAttribute("usercontextid")) { - let usercontextid = tabToOpen.getAttribute("usercontextid"); - gBrowser.selectedBrowser.setAttribute("usercontextid", usercontextid); - } - // If the browser that we're swapping in was remote, then we'd better // be able to support remote browsers, and then make our selectedTab // remote. @@ -1165,9 +1144,8 @@ var gBrowserInit = { // [3]: postData (nsIInputStream) // [4]: allowThirdPartyFixup (bool) // [5]: referrerPolicy (int) - // [6]: userContextId (int) - // [7]: originPrincipal (nsIPrincipal) - // [8]: triggeringPrincipal (nsIPrincipal) + // [6]: originPrincipal (nsIPrincipal) + // [7]: triggeringPrincipal (nsIPrincipal) else if (window.arguments.length >= 3) { let referrerURI = window.arguments[2]; if (typeof(referrerURI) == "string") { @@ -1179,13 +1157,11 @@ var gBrowserInit = { } let referrerPolicy = (window.arguments[5] != undefined ? window.arguments[5] : Ci.nsIHttpChannel.REFERRER_POLICY_DEFAULT); - let userContextId = (window.arguments[6] != undefined ? - window.arguments[6] : Ci.nsIScriptSecurityManager.DEFAULT_USER_CONTEXT_ID); loadURI(uriToLoad, referrerURI, window.arguments[3] || null, - window.arguments[4] || false, referrerPolicy, userContextId, + window.arguments[4] || false, referrerPolicy, // pass the origin principal (if any) and force its use to create // an initial about:blank viewer if present: - window.arguments[7], !!window.arguments[7], window.arguments[8]); + window.arguments[6], !!window.arguments[6], window.arguments[7]); window.focus(); } // Note: loadOneOrMoreURIs *must not* be called if window.arguments.length >= 3. @@ -1277,7 +1253,7 @@ var gBrowserInit = { // Setup click-and-hold gestures access to the session history // menus if global click-and-hold isn't turned on - if (!getBoolPref("ui.click_hold_context_menus", false)) + if (!Services.prefs.getBoolPref("ui.click_hold_context_menus", false)) SetClickAndHoldHandlers(); let NP = {}; @@ -1338,13 +1314,14 @@ var gBrowserInit = { FullScreen.init(); PointerLock.init(); - // initialize the sync UI - gSyncUI.init(); - gFxAccounts.init(); - if (AppConstants.MOZ_DATA_REPORTING) gDataNotificationInfoBar.init(); +#ifdef MOZ_SERVICES_SYNC + // initialize the sync UI + gSyncUI.init(); +#endif + gBrowserThumbnails.init(); gMenuButtonBadgeManager.init(); @@ -1478,8 +1455,6 @@ var gBrowserInit = { FullScreen.uninit(); - gFxAccounts.uninit(); - Services.obs.removeObserver(gPluginHandler.NPAPIPluginCrashed, "plugin-crashed"); try { @@ -1640,8 +1615,10 @@ if (AppConstants.platform == "macosx") { // initialize the private browsing UI gPrivateBrowsingUI.init(); +#ifdef MOZ_SERVICES_SYNC // initialize the sync UI gSyncUI.init(); +#endif }; gBrowserInit.nonBrowserWindowShutdown = function() { @@ -1868,7 +1845,7 @@ function BrowserGoHome(aEvent) { case "tabshifted": case "tab": urls = homePage.split("|"); - var loadInBackground = getBoolPref("browser.tabs.loadBookmarksInBackground", false); + var loadInBackground = Services.prefs.getBoolPref("browser.tabs.loadBookmarksInBackground", false); gBrowser.loadTabs(urls, loadInBackground); break; case "window": @@ -2070,7 +2047,7 @@ function BrowserTryToCloseWindow() } function loadURI(uri, referrer, postData, allowThirdPartyFixup, referrerPolicy, - userContextId, originPrincipal, forceAboutBlankViewerInCurrent, + originPrincipal, forceAboutBlankViewerInCurrent, triggeringPrincipal) { try { openLinkIn(uri, "current", @@ -2078,7 +2055,6 @@ function loadURI(uri, referrer, postData, allowThirdPartyFixup, referrerPolicy, referrerPolicy: referrerPolicy, postData: postData, allowThirdPartyFixup: allowThirdPartyFixup, - userContextId: userContextId, originPrincipal, triggeringPrincipal, forceAboutBlankViewerInCurrent, @@ -2613,15 +2589,9 @@ var gMenuButtonUpdateBadge = { cancelObserverRegistered: false, init: function () { - try { - this.enabled = Services.prefs.getBoolPref("app.update.badge"); - } catch (e) {} + this.enabled = Services.prefs.getBoolPref("app.update.badge", false); if (this.enabled) { - try { - this.badgeWaitTime = Services.prefs.getIntPref("app.update.badgeWaitTime"); - } catch (e) { - this.badgeWaitTime = 345600; // 4 days - } + this.badgeWaitTime = Services.prefs.getIntPref("app.update.badgeWaitTime", 345600); // 4 days Services.obs.addObserver(this, "update-staged", false); Services.obs.addObserver(this, "update-downloaded", false); } @@ -2838,15 +2808,10 @@ var BrowserOnClick = { }, onCertError: function (browser, elementId, isTopFrame, location, securityInfoAsString) { - let secHistogram = Services.telemetry.getHistogramById("SECURITY_UI"); let securityInfo; switch (elementId) { case "exceptionDialogButton": - if (isTopFrame) { - secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_BAD_CERT_TOP_CLICK_ADD_EXCEPTION); - } - securityInfo = getSecurityInfo(securityInfoAsString); let sslStatus = securityInfo.QueryInterface(Ci.nsISSLStatusProvider) .SSLStatus; @@ -2874,64 +2839,27 @@ var BrowserOnClick = { break; case "returnButton": - if (isTopFrame) { - secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_BAD_CERT_TOP_GET_ME_OUT_OF_HERE); - } goBackFromErrorPage(); break; - - case "advancedButton": - if (isTopFrame) { - secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_BAD_CERT_TOP_UNDERSTAND_RISKS); - } - - break; } }, onAboutBlocked: function (elementId, reason, isTopFrame, location) { // Depending on what page we are displaying here (malware/phishing/unwanted) // use the right strings and links for each. - let bucketName = ""; - let sendTelemetry = false; - if (reason === 'malware') { - sendTelemetry = true; - bucketName = "WARNING_MALWARE_PAGE_"; - } else if (reason === 'phishing') { - sendTelemetry = true; - bucketName = "WARNING_PHISHING_PAGE_"; - } else if (reason === 'unwanted') { - sendTelemetry = true; - bucketName = "WARNING_UNWANTED_PAGE_"; - } - let secHistogram = Services.telemetry.getHistogramById("SECURITY_UI"); - let nsISecTel = Ci.nsISecurityUITelemetry; - bucketName += isTopFrame ? "TOP_" : "FRAME_"; switch (elementId) { case "getMeOutButton": - if (sendTelemetry) { - secHistogram.add(nsISecTel[bucketName + "GET_ME_OUT_OF_HERE"]); - } getMeOutOfHere(); break; case "reportButton": // This is the "Why is this site blocked" button. We redirect // to the generic page describing phishing/malware protection. - - // We log even if malware/phishing/unwanted info URL couldn't be found: - // the measurement is for how many users clicked the WHY BLOCKED button - if (sendTelemetry) { - secHistogram.add(nsISecTel[bucketName + "WHY_BLOCKED"]); - } openHelpLink("phishing-malware", false, "current"); break; case "ignoreWarningButton": if (gPrefService.getBoolPref("browser.safebrowsing.allowOverride")) { - if (sendTelemetry) { - secHistogram.add(nsISecTel[bucketName + "IGNORE_WARNING"]); - } this.ignoreWarningButton(reason); } break; @@ -3215,12 +3143,14 @@ var PrintPreviewListener = { this._chromeState.globalNotificationsOpen = !globalNotificationBox.notificationsHidden; globalNotificationBox.notificationsHidden = true; +#ifdef MOZ_SERVICES_SYNC this._chromeState.syncNotificationsOpen = false; var syncNotifications = document.getElementById("sync-notifications"); if (syncNotifications) { this._chromeState.syncNotificationsOpen = !syncNotifications.notificationsHidden; syncNotifications.notificationsHidden = true; } +#endif }, _showChrome: function () { if (this._chromeState.notificationsOpen) @@ -3232,8 +3162,10 @@ var PrintPreviewListener = { if (this._chromeState.globalNotificationsOpen) document.getElementById("global-notificationbox").notificationsHidden = false; +#ifdef MOZ_SERVICES_SYNC if (this._chromeState.syncNotificationsOpen) document.getElementById("sync-notifications").notificationsHidden = false; +#endif if (this._chromeState.sidebarOpen) SidebarUI.show(this._sidebarCommand); @@ -3951,66 +3883,6 @@ function updateEditUIVisibility() } /** - * Opens a new tab with the userContextId specified as an attribute of - * sourceEvent. This attribute is propagated to the top level originAttributes - * living on the tab's docShell. - * - * @param event - * A click event on a userContext File Menu option - */ -function openNewUserContextTab(event) -{ - openUILinkIn(BROWSER_NEW_TAB_URL, "tab", { - userContextId: parseInt(event.target.getAttribute('data-usercontextid')), - }); -} - -/** - * Updates File Menu User Context UI visibility depending on - * privacy.userContext.enabled pref state. - */ -function updateUserContextUIVisibility() -{ - let menu = document.getElementById("menu_newUserContext"); - menu.hidden = !Services.prefs.getBoolPref("privacy.userContext.enabled"); - if (PrivateBrowsingUtils.isWindowPrivate(window)) { - menu.setAttribute("disabled", "true"); - } -} - -/** - * Updates the User Context UI indicators if the browser is in a non-default context - */ -function updateUserContextUIIndicator() -{ - let hbox = document.getElementById("userContext-icons"); - - let userContextId = gBrowser.selectedBrowser.getAttribute("usercontextid"); - if (!userContextId) { - hbox.setAttribute("data-identity-color", ""); - hbox.hidden = true; - return; - } - - let identity = ContextualIdentityService.getIdentityFromId(userContextId); - if (!identity) { - hbox.setAttribute("data-identity-color", ""); - hbox.hidden = true; - return; - } - - hbox.setAttribute("data-identity-color", identity.color); - - let label = document.getElementById("userContext-label"); - label.setAttribute("value", ContextualIdentityService.getUserContextLabel(userContextId)); - - let indicator = document.getElementById("userContext-indicator"); - indicator.setAttribute("data-identity-icon", identity.icon); - - hbox.hidden = false; -} - -/** * Makes the Character Encoding menu enabled or disabled as appropriate. * To be called when the View menu or the app menu is opened. */ @@ -4690,7 +4562,6 @@ nsBrowserAccess.prototype = { _openURIInNewTab: function(aURI, aReferrer, aReferrerPolicy, aIsPrivate, aIsExternal, aForceNotRemote=false, - aUserContextId=Ci.nsIScriptSecurityManager.DEFAULT_USER_CONTEXT_ID, aOpener = null, aTriggeringPrincipal = null) { let win, needToFocusWin; @@ -4719,7 +4590,6 @@ nsBrowserAccess.prototype = { triggeringPrincipal: aTriggeringPrincipal, referrerURI: aReferrer, referrerPolicy: aReferrerPolicy, - userContextId: aUserContextId, fromExternal: aIsExternal, inBackground: loadInBackground, forceNotRemote: aForceNotRemote, @@ -4796,13 +4666,10 @@ nsBrowserAccess.prototype = { // will do the job of shuttling off the newly opened browser to run in // the right process once it starts loading a URI. let forceNotRemote = !!aOpener; - let userContextId = aOpener && aOpener.document - ? aOpener.document.nodePrincipal.originAttributes.userContextId - : Ci.nsIScriptSecurityManager.DEFAULT_USER_CONTEXT_ID; let openerWindow = (aFlags & Ci.nsIBrowserDOMWindow.OPEN_NO_OPENER) ? null : aOpener; let browser = this._openURIInNewTab(aURI, referrer, referrerPolicy, isPrivate, isExternal, - forceNotRemote, userContextId, + forceNotRemote, openerWindow, triggeringPrincipal); if (browser) newWindow = browser.contentWindow; @@ -4834,16 +4701,10 @@ nsBrowserAccess.prototype = { var isExternal = !!(aFlags & Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL); - var userContextId = aParams.openerOriginAttributes && - ("userContextId" in aParams.openerOriginAttributes) - ? aParams.openerOriginAttributes.userContextId - : Ci.nsIScriptSecurityManager.DEFAULT_USER_CONTEXT_ID - let browser = this._openURIInNewTab(aURI, aParams.referrer, aParams.referrerPolicy, aParams.isPrivate, isExternal, false, - userContextId, null, aParams.triggeringPrincipal); if (browser) return browser.QueryInterface(Ci.nsIFrameLoaderOwner); @@ -5400,11 +5261,6 @@ function handleLinkClick(event, href, linkNode) { triggeringPrincipal: doc.nodePrincipal, }; - // The new tab/window must use the same userContextId - if (doc.nodePrincipal.originAttributes.userContextId) { - params.userContextId = doc.nodePrincipal.originAttributes.userContextId; - } - openLinkIn(href, where, params); event.preventDefault(); return true; @@ -5476,8 +5332,6 @@ function handleDroppedLink(event, urlOrLinks, name) let lastLocationChange = gBrowser.selectedBrowser.lastLocationChange; - let userContextId = gBrowser.selectedBrowser.getAttribute("usercontextid"); - // event is null if links are dropped in content process. // inBackground should be false, as it's loading into current browser. let inBackground = false; @@ -5501,7 +5355,6 @@ function handleDroppedLink(event, urlOrLinks, name) replace: true, allowThirdPartyFixup: false, postDatas, - userContextId, }); } }); @@ -6351,9 +6204,14 @@ function checkEmptyPageOrigin(browser = gBrowser.selectedBrowser, return ssm.isSystemPrincipal(contentPrincipal); } +#ifdef MOZ_SERVICES_SYNC function BrowserOpenSyncTabs() { - switchToTabHavingURI("about:sync-tabs", true); + if (gSyncUI._needsSetup()) + gSyncUI.openSetup(); + else + switchToTabHavingURI("about:sync-tabs", true); } +#endif /** * Format a URL @@ -7653,8 +7511,6 @@ var TabContextMenu = { this.contextTab.addEventListener("TabAttrModified", this, false); aPopupMenu.addEventListener("popuphiding", this, false); - - gFxAccounts.updateTabContextMenu(aPopupMenu); }, handleEvent(aEvent) { switch (aEvent.type) { diff --git a/application/basilisk/base/content/browser.xul b/application/basilisk/base/content/browser.xul index be64f1bac..91299de29 100644 --- a/application/basilisk/base/content/browser.xul +++ b/application/basilisk/base/content/browser.xul @@ -8,7 +8,6 @@ <?xml-stylesheet href="chrome://browser/content/browser.css" type="text/css"?> <?xml-stylesheet href="chrome://browser/content/places/places.css" type="text/css"?> -<?xml-stylesheet href="chrome://browser/content/usercontext/usercontext.css" type="text/css"?> #ifdef MOZ_DEVTOOLS <?xml-stylesheet href="chrome://devtools/skin/devtools-browser.css" type="text/css"?> #endif @@ -101,11 +100,6 @@ tbattr="tabbrowser-multiple" oncommand="gBrowser.replaceTabWithWindow(TabContextMenu.contextTab);"/> <menuseparator id="context_sendTabToDevice_separator" hidden="true"/> - <menu id="context_sendTabToDevice" label="&sendTabToDevice.label;" - accesskey="&sendTabToDevice.accesskey;" hidden="true"> - <menupopup id="context_sendTabToDevicePopupMenu" - onpopupshowing="gFxAccounts.populateSendTabToDevicesMenu(event.target, TabContextMenu.contextTab.linkedBrowser.currentURI.spec, TabContextMenu.contextTab.linkedBrowser.contentTitle);"/> - </menu> <menuseparator/> <menuitem id="context_reloadAllTabs" label="&reloadAllTabs.label;" accesskey="&reloadAllTabs.accesskey;" tbattr="tabbrowser-multiple-visible" @@ -391,59 +385,6 @@ <tooltip id="dynamic-shortcut-tooltip" onpopupshowing="UpdateDynamicShortcutTooltipText(this);"/> - - <menupopup id="SyncedTabsSidebarContext"> - <menuitem label="&syncedTabs.context.open.label;" - accesskey="&syncedTabs.context.open.accesskey;" - id="syncedTabsOpenSelected" where="current"/> - <menuitem label="&syncedTabs.context.openInNewTab.label;" - accesskey="&syncedTabs.context.openInNewTab.accesskey;" - id="syncedTabsOpenSelectedInTab" where="tab"/> - <menuitem label="&syncedTabs.context.openInNewWindow.label;" - accesskey="&syncedTabs.context.openInNewWindow.accesskey;" - id="syncedTabsOpenSelectedInWindow" where="window"/> - <menuitem label="&syncedTabs.context.openInNewPrivateWindow.label;" - accesskey="&syncedTabs.context.openInNewPrivateWindow.accesskey;" - id="syncedTabsOpenSelectedInPrivateWindow" where="window" private="true"/> - <menuseparator/> - <menuitem label="&syncedTabs.context.bookmarkSingleTab.label;" - accesskey="&syncedTabs.context.bookmarkSingleTab.accesskey;" - id="syncedTabsBookmarkSelected"/> - <menuitem label="&syncedTabs.context.copy.label;" - accesskey="&syncedTabs.context.copy.accesskey;" - id="syncedTabsCopySelected"/> - <menuseparator/> - <menuitem label="&syncSyncNowItem.label;" - accesskey="&syncSyncNowItem.accesskey;" - id="syncedTabsRefresh"/> - </menupopup> - <menupopup id="SyncedTabsSidebarTabsFilterContext" - class="textbox-contextmenu"> - <menuitem label="&undoCmd.label;" - accesskey="&undoCmd.accesskey;" - cmd="cmd_undo"/> - <menuseparator/> - <menuitem label="&cutCmd.label;" - accesskey="&cutCmd.accesskey;" - cmd="cmd_cut"/> - <menuitem label="©Cmd.label;" - accesskey="©Cmd.accesskey;" - cmd="cmd_copy"/> - <menuitem label="&pasteCmd.label;" - accesskey="&pasteCmd.accesskey;" - cmd="cmd_paste"/> - <menuitem label="&deleteCmd.label;" - accesskey="&deleteCmd.accesskey;" - cmd="cmd_delete"/> - <menuseparator/> - <menuitem label="&selectAllCmd.label;" - accesskey="&selectAllCmd.accesskey;" - cmd="cmd_selectAll"/> - <menuseparator/> - <menuitem label="&syncSyncNowItem.label;" - accesskey="&syncSyncNowItem.accesskey;" - id="syncedTabsRefreshFilter"/> - </menupopup> </popupset> #ifdef CAN_DRAW_IN_TITLEBAR @@ -551,12 +492,7 @@ key="key_undoCloseTab" label="&undoCloseTab.label;" observes="History:UndoCloseTab"/> - <menuseparator id="alltabs-popup-separator-1"/> - <menu id="alltabs_containersTab" - label="&newUserContext.label;"> - <menupopup id="alltabs_containersMenuTab" /> - </menu> - <menuseparator id="alltabs-popup-separator-2"/> + <menuseparator id="alltabs-popup-separator"/> </menupopup> </toolbarbutton> @@ -970,6 +906,18 @@ type="checkbox" label="&fullScreenCmd.label;" tooltip="dynamic-shortcut-tooltip"/> + +#ifdef MOZ_SERVICES_SYNC + <toolbarbutton id="sync-button" + class="toolbarbutton-1 chromeclass-toolbar-additional" + label="&syncToolbarButton.label;" + oncommand="gSyncUI.handleToolbarButton();"/>> + + <toolbarbutton id="sync-tabs-button" + class="toolbarbutton-1 chromeclass-toolbar-additional" + label="&syncTabsToolbarButton.label;" + oncommand="BrowserOpenSyncTabs();"/> +#endif </toolbarpalette> </toolbox> diff --git a/application/basilisk/base/content/content.js b/application/basilisk/base/content/content.js index 5accbdf7b..d2a70ba11 100644 --- a/application/basilisk/base/content/content.js +++ b/application/basilisk/base/content/content.js @@ -162,9 +162,6 @@ var handleContentContextMenu = function (event) { let selectionInfo = BrowserUtils.getSelectionDetails(content); - let loadContext = docShell.QueryInterface(Ci.nsILoadContext); - let userContextId = loadContext.originAttributes.userContextId; - if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT) { let editFlags = SpellCheckHelper.isEditable(event.target, content); let spellInfo; @@ -188,7 +185,7 @@ var handleContentContextMenu = function (event) { principal, docLocation, charSet, baseURI, referrer, referrerPolicy, contentType, contentDisposition, frameOuterWindowID, selectionInfo, disableSetDesktopBg, - loginFillInfo, parentAllowsMixedContent, userContextId }, + loginFillInfo, parentAllowsMixedContent }, { event, popupNode: event.target }); } else { @@ -212,7 +209,6 @@ var handleContentContextMenu = function (event) { disableSetDesktopBackground: disableSetDesktopBg, loginFillInfo, parentAllowsMixedContent, - userContextId, }; } } diff --git a/application/basilisk/base/content/global-scripts.inc b/application/basilisk/base/content/global-scripts.inc index eef21e15e..db8496cfc 100644 --- a/application/basilisk/base/content/global-scripts.inc +++ b/application/basilisk/base/content/global-scripts.inc @@ -27,7 +27,6 @@ <script type="application/javascript" src="chrome://browser/content/browser-safebrowsing.js"/> #endif <script type="application/javascript" src="chrome://browser/content/browser-sidebar.js"/> -<script type="application/javascript" src="chrome://browser/content/browser-syncui.js"/> <script type="application/javascript" src="chrome://browser/content/browser-tabsintitlebar.js"/> <script type="application/javascript" src="chrome://browser/content/browser-thumbnails.js"/> <script type="application/javascript" src="chrome://browser/content/browser-trackingprotection.js"/> @@ -36,4 +35,3 @@ <script type="application/javascript" src="chrome://browser/content/browser-data-submission-info-bar.js"/> #endif -<script type="application/javascript" src="chrome://browser/content/browser-fxaccounts.js"/> diff --git a/application/basilisk/base/content/newtab/alternativeDefaultSites.json b/application/basilisk/base/content/newtab/alternativeDefaultSites.json deleted file mode 100644 index 018d3edcc..000000000 --- a/application/basilisk/base/content/newtab/alternativeDefaultSites.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "directory": [ - { - "bgColor": "#ffffff", - "directoryId": 10000000, - "imageURI": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAIX0lEQVR4nO1afXDbZh1+sxbWsbGvsrLbuBt36766sR3sOEgiuU4kx2vTpFGKm0SKsyyOlI8laUZTulLojQEHx4CyAaNnt72yrivklo1YSpxcW7YVbKXHgCvduCvroDt6o6OtLSWN1MRWX/5I4imyJMu2bPNHnrvfSZbf6P09z+/jfV+3ACxhCUsoAEouNWGlMRLri5GuZwUSe1Ug8bcFEjsjUPgHAoX/UyCxkyKJjQoU/iOhCd8WJSvW/8vpXFFsx7PGeaJsVaytul+g8KMiic+IFA7NTNB/rggk/jeRcu26RGFris3JEqIUtkFsdo2KFK6kI52pCSR2UmirZgY9YFmxeaYg1uyqFSj8lMXI5mofRb3rOwEAJcXmDS72ex8QvO43skjv3MeT2DtRX2150cgLzVUDIonF8xBh64KQ2FWRwncPejyFK4tYq/Nmoa1mPE/pnZ1ILe4TFxpdd+SdvOhxrhabXaeLTVjfsHfzSj5K4V8QKfyjnGs3P2UiCt/v/1LeyAsNlXebkbeRSOZ/Q+JCrBH/Yt7IX+qlbhS96dM+Y+dJLC6S+BWRwmazFizf5AEAQPRtHLEhukqMwo8KTfg2oamy8t+e0uvUczwDwDWxhopHBBLvElrc+wUSm/r/IN9a3ZtrbYqUe9eHTc7PZDLvoAcsi/lq2wQSO1M88k93r7ayjzdI76sxEv/5hdryT+foRknM696q9qMg5AEAQHx83WhWtU5i56PtG1E7fYkO+B4SKNd7AoWLBSEv9G3Asol8zOs+ddFTeWc+fDrXgq2MNmEP5+PdKZB/XR4RvRnWe8tjJ8+1ECsL4mA+EQ+vcCg8gHHuPjjZvc5S6guU6/3/POG5rdi+24IEv+KwEgFQ4QFU/rAKTu90pal5fCY60PlQsf22BefHwfUKD2YVfl6ACIAKfx2UX0QNBYj6arqL7bdtSIQBnYy+2iIAzg49Cid9bm3qv11sn21FggeHUwSILGQCgIljd8Kpreq+4Koqts+2QuGBmBL9FLsFSj+sgAKFnyq2v7ZCDoO7dKOvvc7fS3vcW4rts61I8OBxXdI6/UCJADgVvmGVHfMSAelgfUA6VBeQDqmv2nuzZ3rf6Y2r3SM7DB1RwmCnOsLaiGuenbWD/JwAcqI+IEPCL8H6gAwX7omADIn5z/Wqe0Iz1sgI3edSv6EjcR78OEk4jQiJCNhnlwD1ATlBmDqdCUHzcYRf3mXoSCIMXjdK95SeEAbfslUAk4iaEc1EsLnx0vNmAhw3q3mNAFvtFCBd2i8i4bdWAgYCDBkLwIMJw8antTDos12ARSTNM8JK5Amd8URAPmosQAS8Zdr41N/lIQOS0Z2/pkZe0iWoS35+rIY8rPfLvzcWgAdDljMgAr5tlwCEWgArjUxnnJXSmX8eMnQkPrH8OasCJMJgfyEE0KZxMrJ+i2WgyZq6gHTQ0BGFv+abujs//ab4gV0CqEvAar1n0gQXizj9PUNHEmHgTSFt1At4O3eCH+8D0tW2YUmoMkKvfyQzwC/vMHREegN8Tpe4zjIY55fD14+X9tgiwC8mV2ZrHS/LGOGXRd3y8aeKVee/3GrqjBIGMcMsmL/GJu6AW4+1QZRl/mKHADmipD4gz1jJHCIgw9oXJ+8zfVsi/ImXU7bDquvfI2ugZ7wHoiwDUY6BTrbTWRie+ti0d7rGrHTU5UD45StpX5iILPMZrQTD4Q0QG+2GKMckzcF28AXgaYiv7ZNesdokCb90PO0LP2TBpxQezKpFkPmb4Q/ebFlEHOWYZBY8FtriKwDXFDAHhLvr/bJi9TzQtPeycQNUI3HihkML5M9NfB4+caRTl/jHRsvtb333gTzzTUHDPonNZFkkfjVl7Zfr+MRtiMID+McICqtDvfrE2cWfHRxz2j321K155pxE84HLLWb7BK0odX75TEYTBI43hB1ch0HE554h7GJhKrkn/4wPMjfliXMSO4alcsIvx/UanZE17pcGMppkU2iL2zDt9QSZtwqu66/Okdbb88Qd7PydVFYfkGVthLWHHk1JyOteuHRjxpNh3JNjRtE3EgDlGIiwzLlqrq/MbvKtLwkewi/PalPc8PyQPDdIP8lqQvdw92qEZWbNyBqJgnD0VTTI7H74Je/1uRL/8mDr7VWjfYeJkecgdfC/6c8JavPL0+6fitn3JtdIzxbdqLPqiNMmwtAxR7BzZ+mgL2MnHGzHPQhL/wzlmCsLc64PbYPU4Xd1zwN6WdCwT/p61uQXsH6sL5TS/dOUgY4QCZRlxsuD9EDZsM/x4KDnk5ppSsqGfHehw3QjytHfQVj6HaP+U8F1wZbhMf1Dkerzpr3Sn4Ad/5/Yc2T7TQ6OOW2YBWZimAsVRzlaRoL0DMLRV/WW19SVh05+v5nbAxsPCPpZ4Jclwj95b87kF+BgO+5Bg8yFFHKZZkO68XqimoyvGd0FqUNnU/pA1yvTdbaRXwDCtj2CsszFjFLfSjZoRbEiqEqoqtE+6H2VT5LfvPfydtvJJ0V4jb537QhzxjLRdMSsimIhq5q538DNgSnbfqs0FoHrusUd6j2ScdTNyGZTNovfHa8Z6/fmnbwaTq5r+1wj0ziZrjlmvIKYP3ew9Hvk+NOPFpT8AjxHd6ypGOl607Z+YDUL5s4iChpkdq8b7b22KOTVQIPtGxet3bmQtVA6eKhnyBP6hvnPW8UAwvpq1nIdoeS6bpWY0fK3aMfJTCMc/csqtuf+YvNMi68Mt38WDTJPoSx9DGHpmaxLI8hcqBzpCiDB9ibnM87lxeaVLUrKg+1fRVimby3LPItw9G9Rlj6Bssw/EI4+i3DM+0iQPomy9JiD69hdztI7SoPtTWWvddry7w5LWIIx/gdCuvcjoZqlLQAAAABJRU5ErkJggg==", - "type": "affiliate", - "title": "Google", - "url": "https://www.google.com/" - }, - { - "bgColor": "#E62117", - "directoryId": 10000001, - "imageURI": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAACd0lEQVR4nO3av0tVYRzH8WOIBEVDUUIGCa32FwQ5OrS42NKeRUOTdGmoqUGiLVBqa5UG+7WUREGiEqhTDkVJEA2iYZBkxKvhHumo96o3uM9z0ucNZ7zn834+XO59znm+WZZIJBKJRCKRSGwCx3AWfbiIaxjEPYzgOd7gLWbwIb8WsFjjWrU9q3U+u1C4/0yeOZ47jOROg6jkrn25e3uji27NbzC9A9n/hWnVNbVut/hOTMZ1bSqT6Ky3+A58jOsXhE/o2Lj4FryILBaSF2gpFtAT2ygCPcUCHse2icDTtcW3YSW2TQRW0JahK7ZJRLoy9Ma2iEhvhoHYFhEZyDAU2yIiwxkeBgj6FSDjXxjN8CpA0A1cxucAWY0wkeFdgKBK/pe7H1fxNUDmTpjLMB8gqLJh631A9dF6IUD2Vsxn+BYgaF0BhSIO4WYgh1osZVgOEFSzgEIRh3EL3wO4FFnOAgVtWUChiKO4gx+BvJSqgEIRx3EXP5stVsoCCkWcxH1N3EeUuoBCEafwshlipS8AJzTxW1DaAnAEtzX5B7F0BeAgrmMphFhpClB9M3UFXwI5oQQFYB8u4H0gl3VE3QninOoxVyyWozwL4AxeB8jdjqWgT4M4jUcB8nbKfKj3AUN4gN8BshphLtQbobIyEeqdYFkZzTAc2yIiw+lcQDoZSmeDe/t0ON+gPIltE4Fnxa3pnp8QacFYbKOAjCnOCOUldKhOUO12Nk+JFUroxFRkwWYypd6cYKGEVvTbfZOil2w3KVqjjHZ047xqKRWbZ4XHVed2Z/2d5a0167vYgHC9z6/df9bWs8L9uXO3RmeFE4lEIpFIJPYKfwAcall+TY3q/wAAAABJRU5ErkJggg==", - "type": "affiliate", - "title": "YouTube", - "url": "https://www.youtube.com/" - }, - { - "directoryId": 10000002, - "imageURI": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAACT0lEQVR4nO3bzWsTQRgG8PlPHMVLqRVMoQiFehJyUBAFtRCFHspExaaSoFg8CMGPSg+R3kQhh3osIbOlMVrbGKtrsbYESTbB0gqNVGu1WCkWutnXg+ihQjqxi7Oz8w481533+V32iyGEEEIZ76Rho0SZ4ewOG+D3UMatXSx9nPwqb5ySPZC0dPMzhDJelD6IrDCjQijjtvRBJIWGeY3IHkJ2EED2ALKDALIHkB2lAJoujkIwnoNQwoQL96aha3AKQgkTTtyZhKM383D4+gQEoll/AQRiWbg1XILZ+VWwaw6IrE3bgZbejNoAe8+PwEC6DOsbm0Klt679lxQGCESzMD335Z+KKw+wrzcDpcVvOyqvNMCwubjj8soCnBx44Up5ZQGeFZf1BWi7/BhqjthtzpcAseRsQwVrjgNzS9/hZWUFJq3Pf6U5MqoWQHJ8Qbh8aqoKB688cWVfzwBMvP0kVN6srMCec+7t6xmAmfmvQgCRBzOu7usZgHJ1TQjgyI283gCHrj3VG6C9bwwBEAABEEAtgAPRR9A3VKibpdUfQgD9KWvba529+8pbAMF4TqicW+th/r3eAP0pS2+Anvtv9AY4dvu53gCtMfGfI74DWN+wG5rNdwDl6preAGOFj3oDJMcXvAfQHMlAKGHWTeWD2KPw1aFC3et0NPi9wDPvAq/fif0LDMZzru6LALKLIwACIAACIAACIAACIAACIAACIAACIAACIMD/BvDKwUkZAJRx2zNHZyUBFAntTp+WXV4iQCf5c3yecUsXAMq49bv8Txsl6ZCTabOAAAAAAElFTkSuQmCC", - "title": "Facebook", - "type": "affiliate", - "url": "https://www.facebook.com/" - }, - { - "bgColor": "#ffffff", - "directoryId": 10000003, - "imageURI": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAAA/CAYAAABQHc7KAAAEyUlEQVRoge2abYhVRRjHf7veVqSFhIQwa7E3ojXNpSiNgl0S+tAHKUjohbQohUgqKKwMSXpbsATdqOgFU4zKpAzMioploxI/WFBZmhRlL/S2lbpsudvd24dzjve5c58558ycey9B84MB95x5/vM/d+bMzDNHCAQCgUAgEAgE/rf0AOd6lJmKVrdDfI8SfxawIKNcEscfa8TOzBFrlj6Aimd5XnmAbx01TD5xiL3IiH3Y8zm4DXgaGALGMip/DDwHDACXKQ9wA/AiMJyi8T3wAnCvEr841t9tiR2JY/uB443YC4BHgA3ApyntTxD90FuAlaaBU4EfLIHvKIZtnAT8ZtE5O6fGCiNuFJiTM7YNWKe0PQScmRV8ncX4+zkbT1hq0bkyZ/wyI+5ux/bPM+I/ACbnCSyhv8tloMvBQAnYr+h8mDP+PRHzGXCMQ9sA14j4ceAMl+A70HtvjaMJ22jqy4i70Kh/sWO7AO+K+Jdcg6cCh6k3/gfQ6aBTAr5UdN7OiHtL1H3NxXhMN9Fkl2jM89BgPXrv3eKoc71Fx2ZqvqhTJv+kKRkQGjs94gE4PTZgGt9DNMvmpQR8pehst9R/Q9TZ5OG7EzgkNK720DjKNvTeu9RRZ4miMUH9bnCeuH8EOMXD881C40egw0PjKL3oP8Cbjjq2FWGrUW+HuDfg6XmP0NA2W060GYKy97odtbQVoQzMiu+fL66PACd4+O0VGqPANA+NOm5CHwVPOeqUgH2Kzub4/uvi2gOeXrcU8GdlCtG7ZBr/C5juqHWtojMOXCX+HgaO8/B5YqyV6GjZpjf3oI+C+x11JgF7FZ1/xL/v9PS4WmgMempYsW2MfsdtYwTRsqT9mBXgANGIc6WD2lG60EMjk0fRTS931GkHPrdo3ejpbZHQ2B+30XC6iNZm0/Q3RBOcC7Yc4WRPb0NC43ZPjVxsRDe+yFHHHLJJWevhabaIP0z0ujaNWdQmGUn5yEPrPkVnBPe1+0kRv97DhzPb0UdBr6OObZv9kIOGnJzLRPlL0+lFN+6yPe5BH0kV4E/yD+PlIm6bQ/uF2Um98Qlgbs74V5V4WVbl0GgDvsB/BBbiCnTj2lG5yVyqvX+QaOSYOsNk7y8WiPo+c1Ah2tFPesbJTmFfEfX7qU2BZVmRoSPnkMU+D1EUW5L0WErMHKq9P0o149NeqZ+w7wq7qO77f02p11Qmo6/laWnoVlFvnbh+uaJTAW616Dwo6rjmIw3lLnTjminZ+38DM8Q92yv1HfUnOh3AL/H9I7hnpA1lKrXnb0nRkqSXxf0nFC3bK7XMqCdT6o2NeIiirEE3Lvfks6kesI6hf1m2nTt8TW2uIeeLhub8vsxAT5IOUB2+8qTm2RStlYqOnOV7xLXBRj5EUWxJ0hKic/2k98dJ367azh32Es0Tz4hrTcn5fZE9I8s+ajc6m20CgrUWrdVEK0yFJub8RRhEN56UMjk+TVO7xtuK6yFMS1hIuuk82+SETSk6h3A/hmsJ7egfPypEh555ej/hHOzZYktyfl9keiqLzzc+LUlqWc7vSyfRJ3Rpegw4zUOrj/ofoKU5vy/91Jp+vIDWLkPL/J9h/0mmAT9TXa58vvIkzKe6ydpQ3FogEAgEAoFAIBCI+Rf5q90lTPZHIwAAAABJRU5ErkJggg==", - "title": "Wikipedia", - "type": "affiliate", - "url": "https://www.wikipedia.org/" - }, - { - "bgColor": "#400090", - "directoryId": 10000004, - "imageURI": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAD3ElEQVR4nO3bS4xecxjH8WmLBVVEx63JBIkEISkhJqURpAsZQioWqpeNSxraYlKpSwiDIRY0aSakqgS9qHRBIhKxYdFFFxWXIGkilYZEUCKj4zLzsfi/LN55zpiZc/lr+/6Ss3nfc57ze77n9r88/y7swxaswgLM7jpMhTlYiNWtnPd1Ga9RfIVtuB+L0J3b/FSFeejDQ9iBvRhrTzYCUKTv8RFewlrcgAtxQsYk5+Ii3IQHsBm78ONkk5oKgIn0Mz7BO3gBA7gHS3EtLsXZre1UnITj2pI5vvV7D85BL67DCvRjEJvwHj7HcBXGqwJwyKoDILeB3OoAyG0gt8oAGMYj0qdnJ17DY3i2vK1CPYmn8Cq2YwgP4rfpBix7BwwE3+aZ2F0ybqQPMSM439NlgpYFMILzAlO9glZXCf2F+cF5LsafZQJX8Q4oujKbK4j9j4aC+EdhT9nAVb0Ebw8MduNABbF/wMlB/LUVxK4MwE84JTC5uoLYK4O48/BrBbEr/Qy+XnCbfloi5h7MCuJurcSxagGMYWFg9qr/SbxQVTeEiq7Ym9OI9UYQ52ipJ1iZ6mgJ3h0Y7zG17usvOC2I01+12ToAHBCMIGHdFGKsCo4/QwJTqerqC2wMEjgGX0zi2KLH6JU6jNYFYBSXBElc/R/HjaE3OO4y1bYs/1WdvcFd4hbilgmOie6cGa1Ytaju7vDSIKHTxc9yUYtvWZ0G6wawH8cGSa0J9r0t2G92K0ZtamJA5PEgsfaOTNHjMlC3uSYADKMnSG6B9GIr6uqehYN1m2tqSGxre4KtJDdhfcF/O5ow1hSAMVweJNmNOcHvlbb3J1KTg6K7MTO62m3Jz1LBQMdk1fSo8IpJALizSUNNA/jWBNPvOFGahG1MOeYFnpgAwHNNm8kB4CDODJI/F380bSbXzNAzAYD1OYzkAjAYABjKYaQDIMdJxQDqnFMsVC4A6wIAgzmMdADkOKkYwKM5jOQCcFcAYCqjxpUpF4Bovu+IB3BfDiO5AIzrFWJlDiO5ACzpABgP4I4cRnIBWBwAWJLDSC4AfR0A4wHcksNILgCLAgB9OYzkAnDFkQ5gDZbj3ta2XCp5bVydYuncBnKrAyC3gdzqAMhtILfqBDCCb6SZ3velatGXsUFa5NC+vdjatrf2/QAfSyUyv9dlsgyAEXyGt/G8VBl+PS7A3PaGTllJCy7n40Zp8GQD3sWXSgCaDIBRqcBxGx7GYmll57hixlySaojPx83SuqW3pLXC0wKwX7oF+3GloILjUJE03X6NtAh8J76LAOzFRtwqKGY63CStX14mLen5+m9Vgqdbrd+9cgAAAABJRU5ErkJggg==", - "title": "Yahoo!", - "type": "affiliate", - "url": "https://www.yahoo.com/" - }, - { - "directoryId": 10000005, - "imageURI": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAJdklEQVR4nO1ba1QTZwL9iCY8hCDxDUpYOIUDBOVZAlJ5NQXRFlEQ8YGiRaqESlhxeRQ3FAWURRC6FYglqBHTEaI8Eg+CRMRatfKwLNL6oqer1h57XEWYbwJK9sdKixiSmRCCbrnn3D8w351770wy3zd8ADCJSUxiPMHhcPS3bdv2/tq1a9MWL16MODs7t5iamt4zMjLq0dfX76VSqU8sLCzueHt7S+3t7QtjYmLWJyYmzp1o32NGSUmJd0BAQLmRkVEPAEBOhCQS6bm3t7c0MjIyHACgMyEB1AGCILTY2NgUOzu7fwGCoUfj/Pnz/x0XF/fXgoICXW3nIYTs7Owlpqam94CGgo+ktbX1j4mJiY7azIQbMTExu3V0dF6AcQo/RF1dXYggSIj2kuFAfHx8Lhjn4ODVElCxWOygpXjKkZWVxQZaDD9EOp3eXV9fb6yVkKOho6Njgb6+fp8ig9pgfHx8gjZyjgYdX1/fhtHMqSKJRHpOJpNl6o4HAMidnJxatJJUEWpraz3xmBxOExOT30JDQ/+elpZmD14+26uqqubExcVFzJs3T53H5uCJEydMtZN4BKKiovKJmA0KChLu3bt3zmh6Bw4c0F+3bl0BEU0AgLygoCByXAKqgq2tbSdek0FBQTV4dZlM5kW8ugAAOZPJ/IeGIuHH9evXp+no6DzHa7K+vt4Lr3ZiYuIOvLoAALmnp6dQQ7HwIzc31xqvQRsbmy5AYC6fnJzsjlcbACD38/M7p5lUBBEeHp5lbm7+E4lEUnonREdHpxPRLSwsNFWmN5Kurq5XNZNITfj4+EwtLCw0dXFxcebz+UFhYWFbmExm6qZNm/IjIiKyampqDIjonTp1ajp4mwrQNP70BfD5/D9PAcXFxQZcLteOwWCw9u/f/3FwcHC6paVlOfg/K4CUlpbmEB0dvSEkJCTLxsamwtnZuXXmzJmPAACDgEBYRXxjC8jJyfFYtmzZYWNj48dgjCGV8Y0qICsryyQiIiKVTqf/BMYxNHgTC8jPz/+ISqU+AVoKDt6kAnbs2MGeMmXKANByePAmFBAbG5utyJi2OKEFJCcnx+MxqYizZs361d/fvyw9PX0bg8FgZWRk2FZVVc1pampaQERnwgoQi8VLVK0DRpJMJstWrlx5hMPhvMflckmKdN+amSDRdbuenl5fRkaGnyrdt6KAsrKyD4iYpFKpTy9cuPAuHu23ogAmk9lIxGRCQsLneLVLS0tnEdHWegFisXgu0b8ANTc3W+LVT0pKsiSirfUCDh06tJyIQSsrq5tE9PPy8jyI6Gu9gMDAQA5Bg9VE9Hfu3BlFRJ/BYHSMPRUBsNnsfUQMksnkciL6q1ev5hHRNzQ07AHa3D9A9N19QEAA7lfiAAAdOp3eTUQfACBHEMR87MlwgmgBZmZm9wHOK1RUVLSFiPYQd+/eHaOheKrB4XCyiBrk8XguqnTb29vNDAwMeolqAwDkCxcuvKbBiMoREhLyKVGDy5cvr1Cm2d3dPd3Ly+sCUd3h3LNnT7xGg46GoqKiQHUMbt68uZjL5VJG6qWkpPjS6fS76miO4Ivm5maVd9qYUV5ePlPdtb+FhUV3cHBwkbm5efrGjRvz7O3tr2og+O90dHRslUqlUxX5lkq5U7HmJEtUsnTxwG0kEJ7b4Cer32ArlXIVHq8ULBarVpPGNcng4GDP4V6xloxArNq3oq+M9hTlUeSvsfwvPxMuoKGhwWO8N0RRKBSM6Bg6nf4jgiC0zk6Egl3czsYQhxsKQ48g4QIAAMDf3//0eIWn0WiPjh075jx79uyHeMfY2dl1IAgyFwAAZA1rjqE8ihw9rPscrXRp7xO5lckaN6X0t+dt7m/LiYanPI+iPPLgmApoa2t75+W7fY2GX7RoUcvx48fpAAAgEom88NwJLBbr65ycnGlD3gZuli15VhfC6JZy9Ubzj1W6to6pAAAAEAgEDsbGxv/RVHh3d/ezEomEOvwcqamp6crGsNns/NHeLg0HPPOhV98Pf2ynQRHG+ZcFDKpdAAAAFBcX+6qzF3gkly5dqjCIVCrVs7e3v6RozKpVqw6q8idrybCFonfrUB5FDqsWfzv0c1jh2IHyKHIotL0J+lsyY7CqJXmyO4hamw/Ly8vnhIeH51Op1KdEQtNotN9WrFjxpVAodFOmv337dkMmk1k9NI5CoWCZmZk7EQSZouj4bilfT/ZtUjhW4yNCDxv0ozyKHJaZ9Mq+S1sDAACdnQgF8o1RlEeRy5picsDA3dPv9QnMHqI88iAUudYNdJV4q1NEXFyc7q5duzZ4eXmdtLKyukUikV6ZL1Cp1CeOjo6tHh4eRVwudwWfzx/1MzoSXC53alRUVCaLxapjs9kBio55fC3bGPvm0wRUQL/3yjc9n9Yz0HX090zolTSP//2OPIjdEVkDAAB42nmYJjsbWjo0CEMcfoCNkXvR5lh3BAlT2LQqhIWFTZFIJFSJRELdunUrWR0NVXhc/zdj9MxHa6B4qRAemfHasx6rYUnQjn8uGD5G9k3CHpRHkcvqQk+8Joh1lX2AHl9wf+RkAWtYvx9eSvaWSn2Iz5w0jId1O6fJLn8Wila6iVCe/oCiZ3sff8YT7CLnE6BgJQoRhxtoqcmz3l8vK9629+xW6Sx4dnUmLJv55DXxo3MeQ8ThDKxlfS77Pm8F1pxkqegkmsItSZxu75nAhf1NMZFY47ov4MlFzejLz69ClhrB/vObc3uuZM5QpIf9fM4K5VHk/W25sSpP3tdaaArPrBSgJbovlM6m+LQeWO13HqtwO4i1Zn0CRZ5+2Hf7bB5cK8a9P6hbytfDOgqsMJErC7vyWRw87VUERR5X0VJDiGc2h/IocljL+rr3Klfpv9pg9xttsLOrVIcfDtltEQOtcP0CFZg/wGvmjysyvQ8VmP8ChTa3McThBiZya8NEbm3YSUYXFNrcRgXmv8Ay2jOUp0tMd9gdidWHFsiuH2QQCqUOuFwuSXY5ZT1a6dyullkNEiKMLky6NaYTeX2JrRXILqcslIkDk2GFYyP6lSE27oGPzHiKVTiJZdV+qf2dh50mJPRo6Jby9bBLycvRSpcCeNLpe7SEovw7Aw+/MpDBUx5XsNqAbHgp2buzc4KutDp4dHGXEVq3xh02fbwFq2Htg5WuQljlcwFWLOqAJ97p7hOYPewTmD2EQuu76Emn67DauxmtdEawap8ceH5TNFofznxQs5XQBstJTGISk1AX/wUPVWOeSpK50AAAAABJRU5ErkJggg==", - "title": "Amazon", - "type": "affiliate", - "url": "https://www.amazon.com/" - } - ] -} diff --git a/application/basilisk/base/content/newtab/customize.js b/application/basilisk/base/content/newtab/customize.js index 39724fa91..bc4903f6c 100644 --- a/application/basilisk/base/content/newtab/customize.js +++ b/application/basilisk/base/content/newtab/customize.js @@ -9,7 +9,6 @@ var gCustomize = { "blank", "button", "classic", - "enhanced", "panel", "overlay", "learn" @@ -83,13 +82,10 @@ var gCustomize = { } switch (event.currentTarget.id) { case "newtab-customize-blank": - sendAsyncMessage("NewTab:Customize", {enabled: false, enhanced: false}); + sendAsyncMessage("NewTab:Customize", {enabled: false}); break; case "newtab-customize-classic": - sendAsyncMessage("NewTab:Customize", {enabled: true, enhanced: false}); - break; - case "newtab-customize-enhanced": - sendAsyncMessage("NewTab:Customize", {enabled: true, enhanced: !gAllPages.enhanced}); + sendAsyncMessage("NewTab:Customize", {enabled: true}); break; case "newtab-customize-learn": this.showLearn(); diff --git a/application/basilisk/base/content/newtab/grid.js b/application/basilisk/base/content/newtab/grid.js index b6f98fa17..726150a6c 100644 --- a/application/basilisk/base/content/newtab/grid.js +++ b/application/basilisk/base/content/newtab/grid.js @@ -9,7 +9,6 @@ */ const GRID_BOTTOM_EXTRA = 7; // title's line-height extends 7px past the margin const GRID_WIDTH_EXTRA = 1; // provide 1px buffer to allow for rounding error -const SPONSORED_TAG_BUFFER = 2; // 2px buffer to clip off top of sponsored tag /** * This singleton represents the grid that contains all sites. @@ -142,13 +141,9 @@ var gGrid = { // Create sites. let numLinks = Math.min(links.length, cells.length); - let hasHistoryTiles = false; for (let i = 0; i < numLinks; i++) { if (links[i]) { this.createSite(links[i], cells[i]); - if (links[i].type == "history") { - hasHistoryTiles = true; - } } } @@ -157,9 +152,6 @@ var gGrid = { this._gridDefaultContent.nextSibling.remove(); } this._node.appendChild(fragment); - - document.getElementById("topsites-heading").textContent = - hasHistoryTiles ? "Your Top Sites" : "Top Sites"; }, /** @@ -182,18 +174,15 @@ var gGrid = { // Create the site's inner HTML code. site.innerHTML = - '<span class="newtab-sponsored">' + newTabString("sponsored.button") + '</span>' + '<a class="newtab-link">' + ' <span class="newtab-thumbnail placeholder"/>' + ' <span class="newtab-thumbnail thumbnail"/>' + - ' <span class="newtab-thumbnail enhanced-content"/>' + ' <span class="newtab-title"/>' + '</a>' + '<input type="button" title="' + newTabString("pin") + '"' + ' class="newtab-control newtab-control-pin"/>' + '<input type="button" title="' + newTabString("block") + '"' + - ' class="newtab-control newtab-control-block"/>' + - '<span class="newtab-suggested"/>'; + ' class="newtab-control newtab-control-block"/>'; this._siteFragment = document.createDocumentFragment(); this._siteFragment.appendChild(site); @@ -274,6 +263,6 @@ var gGrid = { this._node.style.maxWidth = gGridPrefs.gridColumns * this._cellWidth + GRID_WIDTH_EXTRA + "px"; this._node.style.height = this._computeHeight() + "px"; - this._node.style.maxHeight = this._computeHeight(gridRows) - SPONSORED_TAG_BUFFER + "px"; + this._node.style.maxHeight = this._computeHeight(gridRows) + "px"; } }; diff --git a/application/basilisk/base/content/newtab/newTab.css b/application/basilisk/base/content/newtab/newTab.css index 658ad2ed3..64b3ed7ef 100644 --- a/application/basilisk/base/content/newtab/newTab.css +++ b/application/basilisk/base/content/newtab/newTab.css @@ -122,10 +122,6 @@ input[type=button] { pointer-events: none; } -body:not(.compact) #topsites-heading { - display: none; -} - /* * If you change the sizes here, make sure you * change the preferences: @@ -140,12 +136,6 @@ body:not(.compact) #topsites-heading { width: 290px; } -body.compact .newtab-cell { - width: 110px; - height: 110px; - margin: 12px; -} - /* SITES */ .newtab-site { position: relative; @@ -175,16 +165,13 @@ body.compact .newtab-cell { } /* TITLES */ -.newtab-sponsored, -.newtab-title, -.newtab-suggested { +.newtab-title { overflow: hidden; position: absolute; right: 0; text-align: center; } -.newtab-sponsored, .newtab-title { bottom: 0; white-space: nowrap; @@ -192,103 +179,11 @@ body.compact .newtab-cell { vertical-align: middle; } -.newtab-suggested { - border: 1px solid transparent; - border-radius: 2px; - font-size: 12px; - height: 17px; - line-height: 17px; - margin-bottom: -1px; - padding: 2px 8px; - display: none; - margin-left: auto; - margin-right: auto; - left: 0; - top: 215px; - -moz-user-select: none; -} - -.newtab-suggested-bounds { - max-height: 34px; /* 34 / 17 = 2 lines maximum */ -} - .newtab-title { left: 0; padding: 0 4px; } -.newtab-sponsored { - background-color: #FFFFFF; - border: 1px solid #E2E2E2; - border-radius: 3px; - color: #4A4A4A; - cursor: pointer; - display: none; - font-family: Arial; - font-size: 9px; - height: 17px; - left: 0; - line-height: 6px; - padding: 4px; - right: auto; - top: -15px; -} - -.newtab-site[suggested=true] > .newtab-sponsored { - background-color: #E2E2E2; - border: none; -} - -.newtab-site > .newtab-sponsored:-moz-any(:hover, [active]) { - background-color: #4A90E2; - border: 0; - color: white; -} - -.newtab-site > .newtab-sponsored[active] { - background-color: #000000; -} - -.newtab-sponsored:dir(rtl) { - right: 0; - left: auto; -} - -.newtab-site:-moz-any([type=enhanced], [type=sponsored], [suggested]) .newtab-sponsored { - display: block; -} - -.newtab-site[suggested] .newtab-suggested { - display: table; -} - -.sponsored-explain, -.sponsored-explain a, -.suggested-explain, -.suggested-explain a { - color: white; -} - -.sponsored-explain, -.suggested-explain { - background-color: rgba(51, 51, 51, 0.95); - bottom: 30px; - line-height: 20px; - padding: 15px 10px; - position: absolute; - text-align: start; -} - -.sponsored-explain input, -.suggested-explain input { - background-size: 18px; - height: 18px; - opacity: 1; - pointer-events: none; - position: static; - width: 18px; -} - /* CONTROLS */ .newtab-control { position: absolute; @@ -333,11 +228,6 @@ body.compact .newtab-cell { margin: 40px 0 15px; } -body.compact #newtab-search-container { - margin-top: 0; - margin-bottom: 80px; -} - #newtab-search-container[page-disabled] { opacity: 0; pointer-events: none; diff --git a/application/basilisk/base/content/newtab/newTab.inadjacent.json b/application/basilisk/base/content/newtab/newTab.inadjacent.json deleted file mode 100644 index 53fb542af..000000000 --- a/application/basilisk/base/content/newtab/newTab.inadjacent.json +++ /dev/null @@ -1,3209 +0,0 @@ -{ - "domains": [ - "rp5slFCxq/e7hYhXJCd0vQ==", - "2rEimAJDNX5g8HPZehOrGg==", - "nvLEpj6ZZF3LWH3wUB6lKg==", - "9Cqd4Lm3VvXuJxz79Bbqyg==", - "vNRy4LR+7TOKTixqsr5ybw==", - "N4zSgsZCo6Z4XRwZ4fu8WQ==", - "jsDtRfVbMsFg3KkEl2UiZQ==", - "TckkKpiq0a6J6NTw7uOZqw==", - "9Or7IAYuuIgZA370w9rNIg==", - "ul8WvOjCkxTz9LjT4RqTHg==", - "ZGJrbwb5878Nsqm0z+A7nQ==", - "5iT64HTeeG5SIFXG7A9o3w==", - "YSeSEghPe1kV6g8ghFcNAA==", - "0jIUl1NDmJZQkDY12VDeIQ==", - "aos6UyDyIw0R1nTK5wTawA==", - "G1xxubsq65ugK06UT2DO5A==", - "lbhavoDrDPP/8m0onwo63w==", - "ObcLsjW0SkdvY0nkZmiTGQ==", - "FHZ5084LC0nTAzZlnSKN3Q==", - "cdEr+0Fv5iaVZzalZToseg==", - "Co8WbNYbCPTFPcHpeK3hRQ==", - "qXSzhCEhByLQq9N84tqV+Q==", - "h3ufhRk5IEFaNH11rIACtQ==", - "fQ1PJ/JwazIaYoy/zy49QQ==", - "zAJqfbn54Nsm2ddGtkb59A==", - "ixPM9T8ik/gWGZ7BRIcaig==", - "/E9pwA3E3hVAZoYq3FmCyw==", - "U6ygonI8CxpruhpGB2+Q6A==", - "Igi4voB8oVMVw6WUeDSjZg==", - "jtuHIJhwoTGzavFpM7ilNw==", - "eBvTV27n6Gs+ZsBkpVynvw==", - "sFbzw0AUOGG0NEzkaSxVDg==", - "yAkIS+Ezj6woEff9YvdO7Q==", - "IP1+BwG6q60QzDADi8j7oA==", - "Q/teQEBFepHtwZ7UHa2TEA==", - "B1vDep5a1Gok5Gnth39+LA==", - "cyEIyQ2MZaPGf+K1x9Bbkg==", - "aaM+oEJnF4/nwMWyXJU8rA==", - "qpDNIpxah8FUiqXm5IRaUg==", - "ZTeJ35gMPqIv2WWbeNyIEg==", - "nzoAGQAnC/Xgg5PmOgXqkA==", - "J5pJDuNi3cqQiyaRJAJk4g==", - "2vqN53BXhXzPrKYsh6QH1A==", - "QlrzHNYxCwCBMVENvbXjQA==", - "Ou2HGn43nmsL3RWSNvMdXw==", - "3qk9lsvGTMqVMAZW+xihfw==", - "RncMe42RB2bhmUbYtGVnKQ==", - "hzNXR6dqPq1+vf4Qh5ByWA==", - "sRq3S2ZRs3H39cEQHv4Vig==", - "B4ThUBTVJOUPyOsHxikHXA==", - "A2lU9GkAdSibLO1JJfFnIA==", - "ef3HNkSvuWQrAzkuty2iqg==", - "yKDiRM6bf2xc0QXIwHYuaA==", - "AdCk4ccJuhA0bIT/61J+RQ==", - "UXvAZ7ULCVz2f505K0Wkvg==", - "ueKWblrOwVJNgiOvkXKLBQ==", - "s8u/jPuBAxu1d18HfV5Z0g==", - "hUT0Uc5YMUdNZQEGLz4hJw==", - "6jo/phmMTrEXKrNRsionGQ==", - "s/Ea/3fkyJ9honzPJkgEQQ==", - "hgu2/Jf+WrQAHfO+asW2zw==", - "kiVuTNwZ1r2lqYEZxIHyiQ==", - "24T5KVrVE2mYwJ5Goj3xJw==", - "fiWBVlfj97GGjEvf/Q9Spg==", - "5VWdlvJe7eoXMGkTtHzCUg==", - "+cFQxKa5RWVtc1z00Jujew==", - "nVa+rLH5p+yXBksLwQsjRQ==", - "5tyI6bMdb3tMIi4ewvr/SQ==", - "S6Roj31yS5bZbSFcd3f4Hg==", - "uW1Zl8iuEF8ZT/gwCBEqwA==", - "YwL+FJgxlZ8JVig+9iP5Cw==", - "ThIYK/mQsp9cMf8+rws/4Q==", - "w0oSxOhRG6kE9B868aoYVQ==", - "DJUDGQ0J32dF1kfItyxALg==", - "34/ab69lPkuAKt6WBxJPpA==", - "25jH4C9apgqWZGZP15lM6Q==", - "GxvwleSaSwILD1pG9k9buA==", - "YRAMt2ArEINo83ms6AqJ0A==", - "15HyTJNoMYzi3XCkeU5Z7A==", - "/SqjXGD+TKC90uz1vsjqUw==", - "karhKOknkhtg/LSFo9BGRA==", - "+tD1d0t3vfJvc1hUAvTT4Q==", - "rkaKbtlnyVr53D0rexLqdQ==", - "fAugw4rtnXzzRXfC1wRgOQ==", - "RgxoepF/XOwIsGat5r5HpQ==", - "Y49/EnzVz3ugXCYxFjFN7g==", - "tHMyzBm/2wNDw7TeNeujbg==", - "LlqzYV4uZpiJy4ORWPSekA==", - "M3Huar7/ded9OGgDwJhZgw==", - "QkNNATSx/PJ1XjgZyTtkUQ==", - "skVw0v6Wx00sfHAScPK1Bw==", - "v1gsIvg+C68T9wixMzL2sQ==", - "hDL75EXhl7BaYnAxkoGwbw==", - "tReG97snx2ESpXbfllCL7Q==", - "EiZBXR15dT1TMrkgkzmkvw==", - "5hRHirfD90/sdp0ILJQU8A==", - "rabElvtYtG0jW6dxAOHofg==", - "JpxoTRKWN+SEeBQ453R1YQ==", - "Faz4Lm0cpjvF0IjVkHiZMg==", - "jGErFAIoXx+50KFpVIGZiA==", - "5GzBkduKpUX7u1uwtYIFug==", - "cRBe0J9/KWRX19N2vPkCiw==", - "t/7g8t4Kr3/+SCnOn3XFWQ==", - "sd08c6jUXs5/hxND0fBkPA==", - "nTxKpqIdnHNdpDk7Dx3TEg==", - "5l+RALcce+lTDnmXI+Wqqg==", - "pzJ4QmEBGRNiiX6z0xHh8g==", - "Vfl3YbqR6JRR7SIdsUA/vA==", - "cgfhOdB376a4GAcuACADvA==", - "inAefsQM6tiIhQCMtcPcyA==", - "FTSULGL8CMhmcc7Cyf/X8A==", - "9XSWpaZyHEy7V/tuw5uZEw==", - "+VtM1opKlgb/jrCwc4YjFA==", - "oF46xheuI/NUxUOnOttzvA==", - "Qy+lvhDbJCumr6kiPLd1oA==", - "swps7UEKpIbVBJ9SnPK3zQ==", - "b7wyIiJvJs+29QePxsdWtQ==", - "x3iDZxYyuHtG/9rNW5HMYg==", - "r1dx1g5UOksywvOaQTamfA==", - "KvVF3Si/fr4JQtr7jCJiog==", - "spvZ7hhtG5QY7JXs96lBUg==", - "ECL8mA5B6CswyDH6yJ4hVw==", - "7Uu+YsdS69dMSDYUr6vTag==", - "Rnm9pSvQRRbkHpOijraLZw==", - "aQJqpnXdzqNSFhMn3EJA2Q==", - "TctnXpd7Wd5ZXKMnOFHAQA==", - "+lPqG8l6mf2FWVGWflyF/g==", - "mPmnmL2oRRJmKYjQ6TfN3g==", - "fyXFcT5ZCawDBg74n1WSpg==", - "uq5Zrxq10pO1HoPxReT5og==", - "3eoCsOKXY8RDrHSdlXqmrA==", - "9nQv2BFG56xsHViN5UpHYw==", - "RtP/nJgy/ItyuDrpBbAotg==", - "5E/drRptfHmBhJ7qplujGg==", - "cUxyZvoqXbQ0a/0I9s6Zbg==", - "womzqSigwEF30V422YmxKw==", - "FPvZqDfN8dTFHLVOuYEbUA==", - "YZMXx+scKXp/v9GaJjb1bA==", - "bjURu5MRsNIZavG5HV0eZw==", - "iY0C9uSMEOn8ikT+J7+/Eg==", - "aXkD6BzsdkMEv7A+eYqQQQ==", - "dOcOfEDGHYG2kgmrglDkPw==", - "c7GjtY05Mh+cp6SNuWY3Ig==", - "lM1uY1oVncHXNzKs/cCEtQ==", - "7jXnQJkutLsi+r9aYmrMxw==", - "NgrugWWduj2qdWnEQf9dLA==", - "faYjmy/yn5iXdS28QCIdWw==", - "68XbaOvIZpCGb4G1gaKErA==", - "Yi67HkOLtGYXeL7WD4GPrA==", - "Puo8gXuUkwcoQViaXwkdSQ==", - "L202Et5aZh60Vl20LTKNFg==", - "4agAzQ5+dnTmLZEjsZs26g==", - "LegGM1ft8Y7Ka3CUxpObvg==", - "KRdILc1QDOpow5im/qY+Kw==", - "peMW+rpwmXrSwplVuB/gTA==", - "Pic1ncr+Zn6wv75zjAdzQA==", - "ilSPlWYbiPzIC13vQUBlOw==", - "GUlDufLoTalBqrG/h3mZ6w==", - "5twANNlT57T9BG4r2D9+Hw==", - "ENrnM8HlMi+5y8Hsu4Pn4A==", - "K/DzpLEbz1MpRjA6qyYn4Q==", - "yN1cHJRHDXoFxFZacL6wsw==", - "Rc6r+KqIePH+dnj1aNYCsQ==", - "8u/z5htgqXVU5Dqwd9whJQ==", - "jV575O42EYoqDNxCm9643Q==", - "xCxGo0h3lS8N6X+ivKfpjA==", - "us+2nfpj2gjI7s14Hw0gmA==", - "bp90A/rbESwVU7eh9xRTfQ==", - "5QtMXzbTafvKDQOWZP7M8w==", - "1gFCxPLjQlQGKmSGmHwmJQ==", - "m+/dnOIe6SaIFhfvg+ybDg==", - "9Dcg87+RPq9U+swRg4dH3Q==", - "mnjbL7WFmrWp0RUqS8AMGA==", - "/0e0E+NFmq8GeE5+y2Gekw==", - "y11mbpHHtka9Ep8cr2nEvQ==", - "GdmjRyliw+W21Q+dHO4CWA==", - "X65wWQTpkg756V/Nfn92kQ==", - "xj06KvacQOxRSofbhzBNgA==", - "nVDxVhaa2o38gd1XJgE3aw==", - "4IV+JOGXrltpkQamBRXMgA==", - "jIfp8LqaYXT88r/K3a8gNw==", - "vhT4dDtbMFVyevS6yCGy0g==", - "zMs7/x8hDt8xj2FFc5+6vA==", - "1J7u2N62JGb2VrnCRlJIrw==", - "3hJs9P/RRxB0CO4q0Icb+g==", - "ZpuVY1ZyoKD3hqosdsfT6Q==", - "6KIM7C7eWgxZtqZboiJvZQ==", - "vtb6fdqirkuUkqITAmXTlw==", - "C/rEVr22mw2u/1dwUx9VTg==", - "NrY4Q5C67haCWLK8HXHq9g==", - "X9qvEftCEFWX3gBU5hXy+Q==", - "0zgw7xNB3xVGaH48TyxaNQ==", - "g7J9Jy/PJrAGRgVdvA+bEg==", - "9zb+anAyZVBzuU9rW4cJtg==", - "6Zc5FzT/m0YIjxEPYA6zDQ==", - "R2YPNlvCbVK0EodTR7czIw==", - "gsI6EGgXMtDu+1u364A8mw==", - "Bg2wBFb1/xaxeEiHfBHX+A==", - "64aapfVI6dV3LpTK56KZlg==", - "HdgcJU0W3yVnH69VYStmug==", - "qTDCcv+LK3JPFB/++t66IQ==", - "P0HEIXMnAmbvq+QYREwFzw==", - "aaU7CAmtyE35jNKTkyXOkg==", - "r9G97WKDiQ48qJHP9LBRNg==", - "8mPgQhYVDn8KshDDvvf5SA==", - "GCQiiOLDguXLiYwuLcFPsA==", - "R2Use39If2C0FVBP7KDerA==", - "23C4eh3yBb5n/RNZeTyJkA==", - "2QQtKtBAm2AjJ5c0WQ6BQA==", - "Qc+XYy2qyWJ5VVwd2PExbw==", - "zJ7ScHNxr2leCDNNcuDApA==", - "vFtC0B2oe1gck28JOM1dyg==", - "bLEntCrCHFy9pg3T3gbBzg==", - "G3PmmPGHaWHpPW30xQgm3Q==", - "me61ST+JrXM5k3/a11gRAA==", - "+LJYVZl1iPrdMU3L5+nxZw==", - "CLPzjXKGGpJ0VrkSJp7wPQ==", - "Pc+u0MAzp4lndTz4m6oQ5w==", - "cwBNvZc0u4bGABo88YUsVQ==", - "q7m/EtZySBjZNBjQ5m1hKw==", - "8ZBiwr842ZMKphlqmNngHw==", - "LMCZqd3UoF/kHHwzTdj7Tw==", - "0ODJyWKJSfObo+FNdRQkkA==", - "ViweSJuNWbx5Lc49ETEs/A==", - "x+8rwkqKCv0juoT5m1A4eg==", - "pxuSWn1u+bHtRjyh2Z8veA==", - "GKzs8mlnQQc58CyOBTlfIg==", - "Owg8qCpjZa+PmbhZew6/sw==", - "YLz+HA6qIneP+4naavq44Q==", - "9ajIS45NTicqRANzRhDWFA==", - "DjeSrUoWW2QAZOAybeLGJg==", - "qxALQrqHoDq9d91nU0DckA==", - "yPIeWcW8+3HjDagegrN8bw==", - "ocpLRASvTgqfkY20YlVFHQ==", - "RuLeQHP1wHsxhdmYMcgtrQ==", - "3WwITQML938W9+MUM56a3A==", - "ZbLVNTQSVZQWTNgC4ZGfQg==", - "X6Ln4si8G5aKar52ZH/FEQ==", - "+gbitI/gpxebN/rK7qj8Fw==", - "7cnUHeaPO8txZGGWHL9tKg==", - "epY+dsm5EMoXnZCnO4WSHw==", - "nf8x+F03kOpMhsCSUWEhVg==", - "VE4sLM5bKlLdk85sslxiLQ==", - "Hs3vUOOs2TWQdQZHs+FaQQ==", - "hkOBNoHbno2iNR7t3/d4vg==", - "Ar9N1VYgE7riwmcrM3bA2Q==", - "SbMjjI8/P8B9a9H2G0wHEQ==", - "tU31r8zla146sqczdKXufg==", - "tFmWYH82I3zb+ymk5dhepA==", - "XHjrTLXkm/bBY/BewmJcCQ==", - "FV/D5uSco+Iz8L+5t7E8SA==", - "yKLLiqzxfrCsr6+Rm6kx1Q==", - "B6reUwMkQFaCHb9BYZExpw==", - "5jyuDp82Fux+B0+zlx8EXw==", - "WGKFTWJac8uehn3N59yHJw==", - "JQf9UmutPh3tAnu7FDk3nA==", - "hv5GrLEIjPb4bGOi8RSO0w==", - "p3V7NfveB6cNxFW7+XQNeQ==", - "DinJuuBX9OKsK5fUtcaTcQ==", - "UEMwF4kwgIGxGT4jrBhMPQ==", - "Y78dviyBS3Jq9zoRD5sZtQ==", - "zbjXhZaeyMfdTb2zxvmRMg==", - "kydoXVaNcx1peR5g6i588g==", - "M2suCoFHJ5fh9oKEpUG3xA==", - "/VnKh/NDv7y/bfO6CWsLaQ==", - "S+b37XhKRm8cDwRb1gSsKQ==", - "jz7QlwxCIzysP39Cgro8jg==", - "IjmLaf3stWDAwvjzNbJpQA==", - "cHSj5dpQ04h/WyefjABfmQ==", - "+gO0bg8LY+py2dLM1sM7Ag==", - "fSANOaHD0Koaqg7AoieY9A==", - "vqYHQ3MnHrAIAr1QHwfIag==", - "Uh1mvZNGehK1AaI4a1auKQ==", - "HCbHUfsTDl6+bxPjT57lrA==", - "S7Vjy/gOWp0HozPP1RUOZw==", - "KPh6TwYpspne4KZA6NyMbw==", - "cfh5VZFmIqJH/bKboDvtlA==", - "H1zH9I8RwfEy5DGz3z+dHw==", - "2ksediOVrh4asSBxKcudTg==", - "+jVN/3ASc2O44sX6ab8/cg==", - "uvKYnKE01D5r7kR9UQyo5A==", - "BB9PTlwKAWkExt3kKC/Wog==", - "yqQPU4jT9XvRABZgNQXjgg==", - "6v3eTZtPYBfKFSjfOo2UaA==", - "49z/15Nx9Og7dN9ebVqIzg==", - "VjclDY8HN4fSpB263jsEiQ==", - "vSKsa0JhLCe9QFZKkcj58Q==", - "PolhKCedOsplEcaX4hQ0YQ==", - "D0Qt9sRlMaPnOv1xaq+XUg==", - "gBgJF0PiGEfcUnXF0RO7/w==", - "sC11Rf/mau3FG5SnON4+vQ==", - "rKb3TBM4EPx/RErFOFVCnQ==", - "+n0K7OB2ItzhySZ4rhUrMg==", - "Epm0d/DvXkOFeM4hoPCBrg==", - "K8PVQhEJCEH1ghwOdztjRw==", - "xjA21QjNdThLW3VV7SCnrg==", - "nE72uQToQFVLOzcu/nMjww==", - "2Hc5oyl0AYRy2VzcDKy+VA==", - "Y7XpxIwsGK3Lm/7jX/rRmg==", - "MK7AqlJIGqK2+K5mCvMXRQ==", - "mXycPfF5zOvcj1p4hnikWw==", - "V1fvtnJ0L3sluj9nI5KzRw==", - "TahqPgS7kEg+y6Df0HBASw==", - "EKU3OVlT4b/8j3MTBqpMNg==", - "EdvIAKdRAXj7e42mMlFOGQ==", - "uPm+cF4Jq08S5pQhYFjU8A==", - "CnIwpRVC2URVfoiymnsdYQ==", - "wyx5mnUMgP5wjykjAfTO7w==", - "OwIGvTh8FPFqa4ijNkguAw==", - "4ID0PHTzIMZz2rQqDGBVfA==", - "rlXt6zKE7DswUl0oWGOQUQ==", - "4NP8EFFJyPcuQKnBSxzKgQ==", - "bJgsuw29cO2WozqsGZxl7w==", - "b3q8kjHJPj9DWrz3yNgwjQ==", - "QGYFMpkv37CS2wmyp42ppg==", - "Kzs+/IZJO8v4uIv9mlyJ2Q==", - "ZJY+hujfd58mTKTdsmHoQQ==", - "R8FxgXWKBpEVbnl41+tWEw==", - "+CvLiih/gf2ugXAF+LgWqw==", - "BDbfe/xa9Mz1lVD82ZYRGA==", - "Dz90OhYEjpaJ/pxwg1Qxhg==", - "MLHt6Ak288G0RGhCVaOeqA==", - "r0QffVKB9OD9yGsOtqzlhA==", - "hK8KhTFcR06onlIJjTji/Q==", - "wMum67lfk5E1ohUObJgrOg==", - "JKmZqz9cUnj6eTsWnFaB0A==", - "rtJdfki8fG6CB36CADp0QA==", - "cUyqCa7Oue934riyC17F8g==", - "y4Y4mSSTw/WrIdRpktc5Hw==", - "r36kVMpF+9J+sfI3GeGqow==", - "ydVj2odhergi+2zGUwK4/A==", - "J2NFyb8cXEpZyxWDthYQiA==", - "qYuo5vY8V3tZx41Kh9/4Dw==", - "jrfRznO0nAz6tZM1mHOKIA==", - "JSr/lqDej81xqUvd/O2s7w==", - "vHGjRRSlZHJIliCwIkCAmQ==", - "sQAxqWXeiu/Su0pnnXgI9A==", - "xPe76nHyHmald6kmMQsKdg==", - "50jASqzGm4VyHJbFv8qVRA==", - "uuiJ+yB7JLDh2ulthM0mjg==", - "TI90EuS/bHq/CAlX32UFXg==", - "JgxNrUlL8wutG04ogKFPvw==", - "aMa1yVA71/w6Uf1Szc9rMA==", - "k/Aou2Jmyh8Bu3k8/+ndsQ==", - "iANKiuMqWzrHSk9nbPe3bQ==", - "7GgNLBppgAKcgJCDSsRqOQ==", - "bzVeU2qM9zHuzf7cVIsSZw==", - "rkeLYwMZ1/pW2EmIibALfA==", - "91+Yms6Oy/rP0rVjha5z9w==", - "JgXSPXDqaS1G9NqmJXZG0A==", - "ZzduJxTnXLD9EPKMn1LI4Q==", - "6W79FmpUN1ByNtv5IEXY4w==", - "Y1Nm3omeWX2MXaCjDDYnWQ==", - "ejfikwrSPMqEHjZAk3DMkA==", - "WNfDNaWUOqABQ6c6kR+eyw==", - "4BkqgraeXY7yaI1FE07Evw==", - "AjHz9GkRTFPjrqBokCDzFw==", - "T/6gSz2HwWJDFIVrmcm8Ug==", - "VWy9lB5t4fNCp4O/4n8S4w==", - "/FdZzSprPnNDPwbhV1C0Cg==", - "LUWxfy4lfgB5wUrqCOUisw==", - "r1VGXWeqGeGbfKjigaAS+Q==", - "ztULoqHvCOE6qV7ocqa4/w==", - "QCpzCTReHxGm5lcLsgwPCA==", - "Hst3yfyTB7yBUinvVzYROQ==", - "gf1Ypna/Tt+TZ08Y+GcvGg==", - "3rbml1D0gfXnwOs5jRZ3gA==", - "2vm7g3rk1ACJOTCXkLB3zA==", - "11FE2kknwYi2Qu0JUKMn3A==", - "1b2uf+CdVjufqiVpUShvHw==", - "0a4SafpDIe8V4FlFWYkMHw==", - "7btpMFgeGkUsiTtsmNxGQA==", - "dUx1REyXKiDFAABooqrKEA==", - "knYKU74onR6NkGVjQLezZg==", - "Scto+9TWxj1eZgvNKo+a9A==", - "cvZT1pvNbIL8TWg+SoTZdA==", - "1nXByug2eKq0kR3H3VjnWQ==", - "tG+rpfJBXlyGXxTmkceiKA==", - "7W9aF7dxnL+E8lbS/F7brg==", - "8vr+ERVrM99dp+IGnCWDGQ==", - "oFNMOKbQXcydxnp8fUNOHw==", - "uJZGw3IY2nCcdVeWW1geNQ==", - "q6LG0VzO1oxiogAAU63hyg==", - "f0H/AFSx2KLZi9kVx5BAZg==", - "1RQZ2pWSxT+RKyhBigtSFg==", - "scCQPl0em2Zmv/RQYar60g==", - "A2ODff+ImIkreJtDPUVrlg==", - "vRgkZZGVN7YZrlml0vxrKA==", - "68jPYo3znYoU4uWI7FH3/g==", - "iJ2nT8w8LuK11IXYqBK+YA==", - "54XELlPm8gBvx8D5bN3aUg==", - "PTAm/jGkie7OlgVOvPKpaA==", - "v7BrkRmK0FfWSHunTRHQFQ==", - "dVh/XMTUIx1nYN4q1iH1bA==", - "TSGL3iQYUgVg/O9SBKP9EA==", - "wTO49YX/ePHMWtcoxUAHpw==", - "bMb1ia0rElr2ZpZVhva0Jw==", - "sNmW2b2Ud7dZi3qOF8O8EQ==", - "3djRJvkZk9O2bZeUTe+7xQ==", - "I9KNZC1tijiG1T72C4cVqQ==", - "sQzCwNDlRsSH7iB9cTbBcg==", - "mk1CKDah7EzDJEdhL22B7w==", - "lON3WM0uMJ30F8poBMvAjQ==", - "88PNi9+yn3Bp4/upgxtWGA==", - "C+Ssp+v1r+00+qiTy2d7kA==", - "11U5XEwfMI7avx014LfC8g==", - "xsf0m31Am0W9eLhopAkfnA==", - "d13Rj3NJdcat0K/kxlHLFw==", - "UP7NXAE0uxHRXUAWPhto0w==", - "ZKXxq9yr7NGBOHidht34uQ==", - "Fd2fYFs8vtjws2kx1gf6Rw==", - "ojf6uL85EuEYgLvHoGhUrw==", - "KjnL3x+56r3M2pDj1pPihA==", - "WdCWezJU4JK43EOZ9YHVdg==", - "/jH6imhTPZ/tHI4gYz2+HA==", - "+OLntmlsMBBYPREPnS6iVw==", - "5lfLJAk1L3QzGMML3fOuSw==", - "AZs3v4KJYxdi8T1gjVjI2Q==", - "7pkUY2UzSbGnwLvyRrbxfA==", - "BjfOelfc1IBgmUxMJFjlbQ==", - "TcGhAJHRr7eMwGeFgpFBhg==", - "Y7iDCWYrO1coopM3RZWIPg==", - "mnalaO6xJucSiZ0+99r3Cg==", - "plXHHzA8X9QGwWzlJxhLRw==", - "Zqd6+81TwYuiIgLrToFOTQ==", - "1Pmnur6TbZ9cmemvu0+dSA==", - "OaNpzwshdHUZMphQXa6i8w==", - "WKehT4nGF2T7aKuzABDMlA==", - "4LvQSicqsgxQFWauqlcEjw==", - "BMZB1FwvAuEqyrd0rZrEzw==", - "YfbfE3WyYOW7083Y8sGfwQ==", - "46FCwqh+eMkf+czjhjworw==", - "734u4Y1R3u7UNUnD+wWUoA==", - "yf06Slv9l3IZEjVqvxP2aA==", - "bIk7Fa6SW7X18hfDjTKowg==", - "DnF6TYSJxlc+cwdfevLYng==", - "ionqS0piAOY2LeSReAz4zg==", - "hlMumZ7RJFpILuKs09ABtw==", - "NjeDgQ1nzH1XGRnLNqCmSg==", - "o7y4zQXQAryST2cak4gVbw==", - "29EybnMEO95Ng4l/qK4NWQ==", - "udU65VtsvJspYmamiOsgXw==", - "v1AWe5qb5y3vSKFb7ADeEw==", - "wK6Srd83eLigZ11Q20XGrg==", - "GmC+0rNDMIR+YbUudoNUXw==", - "W4utAK3ws0zjiba/3i91YA==", - "MlKWxeEh8404vXenBLq4bw==", - "Gdf4VEDLBrKJNQ8qzDsIyw==", - "Z9bDWIgcq6XwMoU2ECDR5Q==", - "VIkS30v268x+M1GCcq/A8A==", - "iPwX3SbbG9ez9HoHsrHbKw==", - "yKrsKX4/1B1C0TyvciNz5w==", - "BophnnMszW5o+ywgb+3Qbw==", - "eJLrGwPRa6NgWiOrw1pA7w==", - "eV+RwWPiGEB+76bqvw+hbA==", - "oad5SwflzN0vfNcyEyF4EA==", - "Uw6Iw+TP9ZdZGm2b/DAmkg==", - "9qWLbRLXWIBJUXYjYhY2pg==", - "dxWv00FN/2Cgmgq9U3NVDQ==", - "AX1HxQKXD12Yv5HWi39aPQ==", - "J0NauydfKsACUUEpMhQg8A==", - "mxug34EekabLz0JynutfBg==", - "bNq/hj0Cjt4lkLQeVxDVdQ==", - "nW3zZshjZEoM8KVJoVfnuQ==", - "ghp8sWGKWw20S/z1tbTxFg==", - "S4rFuiKLFKZ+cL7ldiTwpg==", - "8ZqmPJDnQSOFXvNMRQYG2Q==", - "6XYqR2WvDzx4fWO7BIOTjA==", - "Uo+FIhw1mfjF6/M8cE1c/Q==", - "bsHIShcLS134C+dTxFQHyA==", - "19yQHaBemtlgo2QkU5M6jQ==", - "sWLcS+m4aWk31BiBF+vfJQ==", - "BlCgDd7EYDIqnoAiKOXX6Q==", - "MrxR3cJaDHp0t3jQNThEyg==", - "cMo6l1EQESx1rIo+R4Vogg==", - "VOvrzqiZ1EHw+ZzzTWtpsw==", - "1/ZheMsbojazxt31j/l3iA==", - "0QxPAqRF8inBuFEEzNmLjA==", - "UXUNYEOffgW3AdBs7zTMFA==", - "lOPJhHqCtMRFZfWMX/vFZQ==", - "rXSbbRABEf4Ymtda45w8Fw==", - "jfegbZSZWkDoPulFomVntA==", - "hfcH5Az2M7rp+EjtVpPwsg==", - "VsXEBIaMkVftkxt1kIh7TA==", - "M20iX2sUfw5SXaZLZYlTaA==", - "VUDsc9RMS1fSM43c+Jo9dQ==", - "itPtn+JaO4i7wz2wOPOmDQ==", - "rCxoo4TP/+fupXMuIM0sDA==", - "cSHSg9xJz/3F6kc+hKXkwg==", - "b4BoZmzVErvuynxirLxn0w==", - "e4B3HmWjW+6hQzcOLru6Xg==", - "lTE6u9G/RzvmbuAzq2J2/Q==", - "897ptlztTjr7yk+pk8MT0Q==", - "jd6IpPJwOJW1otHKtKZ5Gw==", - "b4aFwwcWMXsSdgS1AdFOXA==", - "FltEN+7NKvzt+XAktHpfHA==", - "ZyDh3vCQWzS5DI1zSasXWA==", - "kcJ1acgBv6FtUhV8KuWoow==", - "zgEyxj/sCs63O98sZS94Yw==", - "/kGxvyEokQsVz0xlKzCn2A==", - "cxqHS4UbPolcYUwMMzgoOA==", - "62RHCbpGU8Hb+Ubn+SCTBg==", - "ePlsM/iOMme2jEUYwi15ng==", - "0fN+eHlbRS6mVZBbH/B9FQ==", - "k0XIjxp2vFG7sTrKcfAihA==", - "0rfG4gRugAwVP0i3AGVxxg==", - "M98hjSxCwvZ27aBaJTGozQ==", - "kzGNkWh3fz27cZer4BspUQ==", - "3CJbrUdW68E3Drhe4ahUnQ==", - "NGApiVkDSwzO45GT57GDQw==", - "lMjip5hbCjkD9JQjuhewDg==", - "GrSbnecYAC3j5gtoKntL0A==", - "9dbn0Kzwr9adCEfBJh78uQ==", - "64QzHOYX0A9++FqRzZRHlQ==", - "YZt6HwCvdI5DRQqndA/hBQ==", - "6GXHGF62/+jZ7PfIBlMxZw==", - "PBULPuFXb6V3Di713n3Gug==", - "8Cm19vJW8ivhFPy0oQXVNA==", - "zDSQ3NJuUGkVOlvVCATRwA==", - "6QAtjOK9enNLRhcVa2iaTg==", - "v/PshI6JjkL9nojLlMNfhg==", - "yTgN5xFIdz1MzFS6xMl5uQ==", - "SCO9nQncEcyVXGCtx30Jdg==", - "7b0oo4+qphu6HRvJq6qkHQ==", - "ol9xhVTG9e1wNo50JdZbOA==", - "hIABph+vhtSF5kkZQtOCTA==", - "k+IBS52XdOe5/hLp28ufnA==", - "6HnWgYNKohqhoa1tnjjU3A==", - "HDxGhvdQwGh0aLRYEGFqnw==", - "LDuBcL5r3PUuzKKZ9x6Kfw==", - "HPvYV94ufwiNHEImu4OYvQ==", - "h2cnQQF2/R3Mq2hWdDdrTg==", - "nqpKfidczdgrNaAyPi7BOQ==", - "2ywo4t5PPSVUCWDwUlOVwQ==", - "jZMDIu95ITTjaUX0pk4V5g==", - "bA2kaTpeXflTElTnQRp6GQ==", - "lwYQm2ynA3ik2gE1m11IEg==", - "5ugVOraop5P5z5XLlYPJyQ==", - "l2NppPcweAtmA1V2CNdk2Q==", - "DbWQI3H2tcJsVJThszfHGA==", - "H6HPFAcdHFbQUNrYnB74dA==", - "H1NJEI+fvOQbI51kaNQQjQ==", - "53UccFNzMi9mKmdeD82vAw==", - "lffapwUUgaQOIqLz2QPbAg==", - "rSvhrHyIlnIBlfNJqemEbw==", - "BLJk9wA88z6e0IQNrWJIVw==", - "5m1ijXEW+4RTNGZsDA/rxQ==", - "GG8a3BlwGrYIwZH9j3cnPA==", - "HhBHt5lQauNl7EZXpsDHJA==", - "/XjB6c5fxFGcKVAQ4o+OMw==", - "+tuUmnRDRWVLA+1k0dcUvg==", - "SM7E98MyViSSS9G0Pwzwyw==", - "c5q/8n7Oeffv3B1snHM/lA==", - "kwlAQhR2jPMmfLTAwcmoxw==", - "0b/xj6fd0x+aB8EB0LC4SA==", - "S8jlvuYuankCnvIvMVMzmg==", - "kZkmDatUOdIqs7GzH3nI1A==", - "obW3kzv2KBvuckU7F+tfjA==", - "pa8nkpAAzDKUldWjIvYMYg==", - "m+eh+ZqS74w2q0vejBkjaw==", - "LcoJBEPTlSsQwfuoKQUxEw==", - "KO2XVYyNZadcQv8aCNn5JA==", - "uvzmRcvgepW6mZbMfYgcNw==", - "KhUT2buOXavGCpcDOcbOYg==", - "fo3JL+2kPgDWfP+CCrFlFw==", - "wIfvvLKC61gOpsddUFjVog==", - "SPHU6ES1WVm0Mu2LB+YjrA==", - "LWWfRqgtph1XrpxF4N64TA==", - "LCvz/h9hbouXCmdWDPGWqg==", - "PXC6ZpdMH0ATis/jGW12iA==", - "z920R8eahJPiTsifrPYdxA==", - "GIHKW6plyLra0BmMOurFgA==", - "k6OmSlaSZ5CB0i7SD9LczQ==", - "YZ39RIXpeLAhyMgmW2vfkQ==", - "bs2QG8yYWxPzhtyMqO6u3A==", - "pKaTI+TfcV3p/sxbd2e7YQ==", - "xWYecfzAtXT9WyQ8NYY/hw==", - "Fz8EI+ZpYlbcttSHs5PfpA==", - "wfwuxn+Vja1DNwiDwL2pcQ==", - "wux5Y8AipBnc5tJapTzgEQ==", - "U+oTpcjhc0E+6UjP11OE/Q==", - "yTVJKBn72RjakMBXDoBKHg==", - "0TxcYwG72dT7Tg+eG8pP1w==", - "imZ+mwiT22sW2M9alcUFfg==", - "CkDIoAFLlIRXra78bxT/ZA==", - "4qMSNAxichi3ori/pR+o0w==", - "zNLlWGW/aKBhUwQZ4DZWoQ==", - "D31ZticrjGWAO45l5hFh7A==", - "HdXg64DBy5WcL5fRRiUVOg==", - "yhI5jHlfFJxu4eV5VJO2zQ==", - "e9GqAEnk8XI5ix6kJuieNQ==", - "EC0+iUdSZvmIEzipXgj7Gg==", - "chwv4+xbEAa93PHg8q9zgQ==", - "B1VVUbl8pU0Phyl1RYrmBg==", - "A+DLpIlYyCb9DaarpLN76g==", - "wHA+D5cObfV3kGORCdEknw==", - "+Mp+JIyO0XC5urvMyi3wvQ==", - "vUE8Iw3NyWXURpXyoNJdaw==", - "ParhxI6RtLETBSwB0vwChQ==", - "NxSdT2+MUkQN49pyNO2bJw==", - "JSyhTcHLTfzHsPrxJyiVrA==", - "PAlx9+U+yQCAc5Fi0BOG0w==", - "W/0s1x3Qm+wN8DhROk6FrQ==", - "L3Jt5dHQpWQk74IAuDOL8g==", - "VWb8U4jF/Ic0+wpoXi/y/g==", - "1wBuHqS1ciup31WTfm3NPg==", - "BDNM1u/9mefjuW1YM2DuBg==", - "SDi5+FoP9bMyKYp+vVv1XA==", - "23d9B9Gz5kUOi1I//EYsSQ==", - "/a9O7kWeXa0le45ab3+nVw==", - "PcoVtZrS1x1Q+6nfm4f80w==", - "A6TLWhipfymkjPYq8kaoDQ==", - "lzUQ1o7JAbdJYpmEqi6KnQ==", - "/2jGyMekNu7U136K+2N3Jg==", - "ZItMIn1vhGqAlpDHclg0Ig==", - "Ee4A3lTMLQ7iDQ7b8QP8Qg==", - "bO55S58bqDiRWXSAIUGJKw==", - "zeHF6fdeqcOId3fRUGscRw==", - "BxsDnI8jXr4lBwDbyHaYXw==", - "ylA6sU7Kaf9fMNIx1+sIlw==", - "ZWXfE3uGU91WpPMGyknmqw==", - "f1+fHgR5rDPsCZOzqrHM7Q==", - "8VqeoQELbCs232+Mu+HblA==", - "beSrliUu0BOadCWmx+yZyA==", - "NQVQfN3nIg9ipHiFh4BvfQ==", - "4wnUAbPT3AHRJrPwTTEjyw==", - "/cdR1i5TuQvO+u3Ov3b0KQ==", - "wtyAZIfhomcHe9dLbYoSvA==", - "ulpDxLeQnIRPnq6oaah2AA==", - "pdPwUHauXOowaq9hpL2yFw==", - "1+A9FCGP3bZhk6gU3LQtNg==", - "raYifKqev8pASjjuV+UTKQ==", - "+OERSmo7OQUUjudkccSMOA==", - "FeRovookFQIsXmHXUJhGOw==", - "USCvrMEm/Wqeu9oX6FrgcQ==", - "kly/2kE4/7ffbO34WTgoGg==", - "IindlAnepkazs5DssBCPhA==", - "Bq82MoMcDjIo/exqd/6UoA==", - "ocvA1/NbyxM0hanwwY6EiA==", - "rtd6mqFgGe98mqO0pFGbSw==", - "nvLEpj6ZZF3LWH3wUB6lKg==", - "AGd0rcLnQ0n+meYyJur1Pw==", - "wI7JrSPQwYHpv2lRsQu9nQ==", - "OnmvXbyT2BYsSDJYZhLScA==", - "CmBf5qchS1V3C2mS6Rl4bw==", - "TafM7nTE5d+tBpRCsb8TjQ==", - "wxkb8evGEaGf/rg/1XUWiA==", - "y1J+o6DC2sETFsySgpDZyA==", - "SVLHWPCCH7GPVCF7QApPbw==", - "HMWOlMmzocOIiJ7yG1YaDQ==", - "DJmrmNRKARzsTCKSMLmcNA==", - "/XC/FmMIOdhMTPqmy4DfUA==", - "63OTPaKM0xCfJOy9EDto+Q==", - "PxReytUUn/BbxYTFMu1r2Q==", - "WjDqf1LyFyhdd8qkwWk+MA==", - "/DiUApY7cVp5W9o24rkgRA==", - "alJtvTAD7dH/zss/Ek1DMQ==", - "xLm/bJBonpTs0PwsF0DvRg==", - "eAOEgF5N80A/oDVnlZYRAw==", - "LqgzKxbI6WTMz0AMIDJR5w==", - "MJ1FuK8PXcmnBAG9meU84A==", - "JLq/DrW2f26NaRwfpDXIEA==", - "fsrX00onlGvfsuiCc35pGg==", - "tXVb5f90k9l3e1oK2NGXog==", - "1JRgSHnfAQFQtSkFTttkqQ==", - "B0TaUQ6dKhPfSc5V/MjLEQ==", - "nkbLVLvh3ClKED97+nH+7Q==", - "avFTp3rS6z5zxQUZQuaBHQ==", - "lNF8PvUIN02NattcGi5u4g==", - "bBEndaOStXBpAK79FrgHaw==", - "dM9up4vKQV5LeX82j//1jQ==", - "4WO6eT0Rh6sokb29zSJQnQ==", - "RHKCMAqrPjvUYt13BVcmvw==", - "Ju4YwtPw+MKzpbC0wJsZow==", - "tzV7ixFH37ze4zuLILTlfA==", - "oPlhC4ebXdkIDazeMSn1fQ==", - "5pje7qyz8BRsa8U4a4rmoA==", - "7E6V6/zSjbtqraG7Umj+Jw==", - "8QK7emHS6rAcAF5QQemW/A==", - "LhqRc9oewY4XaaXTcnXIHQ==", - "p/7qM5+Lwzw1/lIPY91YxQ==", - "fy54Milpa7KZH/zgrDmMXQ==", - "LyPXOoOPMieqINtX8C9Zag==", - "aD4QvtMlr8Lk/zZgZ6zIMg==", - "dsueq9eygFXILDC7ZpamuA==", - "+mJLK+6qq8xFv7O/mbILTw==", - "nHUpYmfV59fe3RWaXhPs3Q==", - "VbCoGr8apEcN7xfdaVwVXw==", - "/2Chaw2M9DzsadFFkCu6WQ==", - "rKAQxu80Q8g1EEhW5Wh8tg==", - "RJJqFMeiCZHdsqs72J17MQ==", - "GF2yvI9UWf1WY7V7HXmKPA==", - "JyIDGL1m/w+pQDOyyeYupA==", - "wR2Gxb07nkaPcZHlEjr8iA==", - "PbDVq2Iw1eeM8c2o/XYdTA==", - "BL3buzSCV78rCXNEhUhuKQ==", - "i42XumprV/aDT5R0HcmfIQ==", - "DuEKxykezAvyaFO2/5ZmKQ==", - "6ACvJNfryPSjGOK39ov8Qg==", - "YaUKOTyByjUvp1XaoLiW5Q==", - "jNcMS2zX1iSZN9uYnb2EIg==", - "VRnx+kd6VdxChwsfbo1oeQ==", - "4Qinl7cWmVeLJgah8bcNkw==", - "Fiy3hkcGZQjNKSQP9vRqyA==", - "HaSc7MZphCMysTy2JbTJkw==", - "VhYGC8KYe5Up+UJ2OTLKUw==", - "K2gk9zWGd0lJFRMQ1AjQ/Q==", - "NfxVYc3RNWZwzh2RmfXpiA==", - "JGeqHRQpf4No74aCs+YTfA==", - "7VHlLw20dWck+I8tCEZilA==", - "V5HKdaTHjA8IzvHNd9C51g==", - "9TalxEyFgy6hFCM73hgb7Q==", - "R/y6+JJP8rzz1KITJ4qWBw==", - "7bM/pn4G7g7Zl6Xf1r62Lg==", - "CHsFJfsvZkPWDXkA6ZMsDQ==", - "uXuPA/2KJbb7ZX+NymN3dw==", - "o+nYS4TqJc6XOiuUzEpC3A==", - "8N3mhHt29FZDHn1P2WH1wQ==", - "uZ2gUA74/7Q33tI2TcGQlg==", - "8B12CamjOGzJDnQ+RkUf4w==", - "9FdpxlIFu11qIPdO7WC5nw==", - "G+sGF13VXPH4Ih6XgFEXxg==", - "y+1I05LDAYJ09tKMs3zW6g==", - "gnkadeCgjdmLdlu/AjBZJg==", - "1I+UVx3krrD4NhzO7dgfHQ==", - "8LNNoHe6rEQyJ0ebl151Mw==", - "yOE90OHQdyOfrAgwDvn2gA==", - "ayBGGPEy++biljvGcwIjXA==", - "o/Y4U6rWfsUCXJ72p5CUGw==", - "5kvyy902llnYGQdn2Py04w==", - "6k2cuk0McTThSMW/QRHfjA==", - "2XrR2hjDEvx8MQpHk9dnjw==", - "fv/PW8oexJYWf5De30fdLQ==", - "861mBNvjIkVgkBiocCUj/Q==", - "NKGY0ANVZ0gnUtzVx1pKSw==", - "4DIPP/yWRgRuFqVeqIyxMQ==", - "cgSEbLqqvDsNUyeA3ryJ6Q==", - "xbBxUP9JyY0wDgHDipBHeg==", - "c3WVxyC5ZFtzGeQlH5Gw+w==", - "ZKeTDCboOgCptrjSfgu0xw==", - "DjHszpS8Dgocv3oQkW/VZQ==", - "Iqszlv4R49UevjGxIPMhIA==", - "uChFnF0oCwARhAOz/d47eA==", - "0egBaMnAf0CQEXf1pCIKnA==", - "FnVNxl5AFH1AieYru2ZG+A==", - "2Ct+pLXrK6Ku1f4qehjurQ==", - "x2nSgcTjA3oGgI8mMgiqjw==", - "AUGmvZkpkKBry5bHZn4DJA==", - "x8kRVzohTdhkryvYeMvkMw==", - "rXfWkabSPN+23Ei1bdxfmQ==", - "ElTNyMR4Rg8ApKrPw88WPg==", - "9jxA/t3TQx8dQ+FBsn/YCg==", - "I07W2eDQwe6DVsm1zHKM8A==", - "0p1jMr06OyBoXQuSLYN4aQ==", - "odGhKtO4bDW5R8SYiI5yCg==", - "5Q/Y2V0iSVTK8HE8JerEig==", - "Ily2MKoFI1zr5LxBy93EmQ==", - "8dUcSkd2qnX5lD9B+fUe+Q==", - "80UE+Ivby3nwplO/HA7cPw==", - "sS6QcitMPdvUBLiMXkWQkw==", - "5VY++KiWgo7jXSdFJsPN3A==", - "aY6B28XdPnuYnbOy9uSP8A==", - "ZfRlID+pC1Rr4IY14jolMw==", - "/YuQw7oAF08KDptxJEBS9g==", - "16d+fhFlgayu3ttKVV/pbg==", - "8dBIsHMEAk7aoArLZKDZtg==", - "wRqaDZVHHurp5whOQ1kDbQ==", - "lFUq6PGk9dBRtUuiEW7Cug==", - "FoJZ61VrU8i084pAuoWhDQ==", - "4mig4AMLUw+T/ect9p4CfA==", - "Po0lhBfiMaXhl+vYh1D8gA==", - "z9cd+Qj+ueX34Zf3997MNQ==", - "1dsKN1nG6upj7kKTKuJWsQ==", - "UtLYUlQJ02oKcjNR3l+ktg==", - "O538ibsrI4gkE5tfwjxjmg==", - "G736AX070whraDxChqUrqw==", - "THs1r8ZEPChSGrrhrNTlsA==", - "pVG1hL96/+hQ+58rJJy6/A==", - "1BjsijOzgHt/0i36ZGffoQ==", - "6rIWazDEWU5WPZHLkqznuQ==", - "cdWUm6uLNzR/knuj2x75eA==", - "nsnX3tKkN1elr18E31tXDw==", - "0fnruVOCxEczscBuv4yL9A==", - "SVuEYfQ9FGyVMo1672n0Yg==", - "ZRWyfXyXqAaOEjkzWl949Q==", - "S2MAIYeDQeJ1pl9vhtYtUg==", - "vsRNZx4thFFFPneubKq1Fw==", - "kuWGANwzNRpG4XmY7KjjNg==", - "i6r+mZfyhZyqlYv56o0H+w==", - "wqWqe0KRjZlUIrGgEOG9Mg==", - "t5wh9JGSkQO78QoQoEqvXA==", - "AGoVLd0QPcXnTedT5T95JQ==", - "aRrcmH+Ud3mF1vEXcpEm4w==", - "C65PZm8rZxJ6tTEb6d08Eg==", - "oAHVGBSJ2cf4dVnb/KEYmw==", - "BuDVDLl0OGdomEcr+73XhQ==", - "bLsStF0DDebpO+xulqGNtg==", - "xukOAM0QVsA72qEy0yku9A==", - "LpoayYsTO8WLFLCSh2kf2w==", - "LEVYAE54618FrlXkDN01Kw==", - "Jm862vBTCYbv/V4T1t46+Q==", - "X4kdXUuhcUqMSduqhfLpxA==", - "cLR0Ry4/N5swqga1R6QDMw==", - "0klouNfZRHFFpdHi4ZR2hA==", - "JGx8sTyvr4bLREIhSqpFkw==", - "ZiJ/kJ9GneF3TIEm08lfvQ==", - "hP7dSa8lLn9KTE/Z0s4GVQ==", - "600bwlyhcy754W1E6tuyYg==", - "U49SfOBeqQV9wzsNkboi8Q==", - "5DDb7fFJQEb3XTc3YyOTjg==", - "6uT7LZiWjLnnqnnSEW4e/Q==", - "tq5xUJt8GtjDIh1b48SthQ==", - "eJFIQh/TR7JriMzYiTw4Sg==", - "jdRzkUJrWxrqoyNH9paHfQ==", - "RKVDdE1AkILTFndYWi9wFg==", - "AEpTVUQhIEJGlXJB6rS26A==", - "PD+yHtJxZJ2XEvjIPIJHsQ==", - "dOS+mVCy3rFX9FvpkTxGXA==", - "lz+SeifYXxamOLs1FsFmSQ==", - "QTz21WkhpPjfK8YoBrpo+w==", - "9wUIeSgNN36SFxy8v2unVg==", - "ash1r2J6B0PUxJe8P0otVQ==", - "y7yS9x3yshVhMpDbQtfYOQ==", - "f07bdNVAe9x+cAMdF1bByQ==", - "N2KovXW14hN/6+iWa1Yv3g==", - "2DNbXVgesUa7PgYQ4zX5Lw==", - "WQznrwqvMhUlM3CzmbhAOQ==", - "FpWDTLTDmkUhH/Sgo+g1Gg==", - "OVHqwV8oQMC5KSMzd5VemA==", - "Bv4mNIC72KppYw/nHQxfpQ==", - "MI+HSMRh8KTW+Afiaxd/Fw==", - "10OltdxPXOvfatJuwPVKbQ==", - "y4/HohCJxtt+cT7nLJB08w==", - "RhcqXY4OsZlVVF7ZlkTeRw==", - "/mrqas0eDX+sFUNJvCQY8g==", - "ZIZx4MehWTVXPN9cVQBmyA==", - "z20AAnvj7WsfJeOu3vemlA==", - "dL6n/JsK+Iq6UTbQuo/GOw==", - "rMm9bHK69h0fcMkMdGgeeA==", - "ftsf2qztw3NC78ep/CZXWQ==", - "/n1RLTTVpygre1dl36PDwQ==", - "/FsJYFNe+7UvsSkiotNJEQ==", - "Yy2pPhITTmkEwoudXizHqQ==", - "lizovLQxu6L9sbafNQuShQ==", - "XV5MYe0Q7YMtoBD6/iMdSw==", - "5jHgQF4SfO/zy9xy9t+9dw==", - "16iT/jCcPDrJEfi2bE5F+Q==", - "syeBfQBUmkXNWCZ1GV8xSA==", - "sr3UXbMg5zzkRduFx/as7g==", - "xUXEE7OBBCudsQnuj5ycOA==", - "ojZY7Gi2QJXE/fp6Wy31iA==", - "RlNPyhgYOIn28R4vKCVtYA==", - "KOm8PTa+ICgDrgK9QxCJZw==", - "DJoy1NSZZw87oxWGlNHhfg==", - "jEdanvXKyZdZJG6mj/3FWw==", - "Omr+zPWVucPCSfkgOzLmSQ==", - "71w3aSvuh2mBLtdqJCN3wA==", - "xjTMO2mvtpvwQrounD4e8g==", - "Zz/5VMbw1TqwazReplvsEg==", - "hIjgi20+km+Ks23NJ4VQ6Q==", - "00TVKawojyqrJkC7YqT41Q==", - "YgVpC5d5V6K/BpOD663yQA==", - "wX70jKLKJApHnhyK0r6t3A==", - "lacCCRiWdquNm4YRO7FoKA==", - "cWdlhVZD7NWHUGte24tMjg==", - "t5U+VMsTtlWAAWSW+00SfQ==", - "AMfL0rH+g8c0VqOUSgNzQw==", - "0G93AxGPVwmr66ZOleM90A==", - "9tiibT8V9VwnPOErWGNT3w==", - "+dBv88reDrjEz6a2xX3Hzw==", - "xX6atcCApI08oVLjjLteLg==", - "+YrqTEJlJCv0A2RHQ8tr1A==", - "aqcOby9QyEbizPsgO3g0yw==", - "s/BZAhh1cTV3JCDUQsV8mA==", - "x9VwDdFPp/rJ+SF16ooWYg==", - "k/OVIllJvW6BefaLEPq7DA==", - "rIMXaCaozDvrdpvpWvyZOQ==", - "qQQwJ/aF87BbnLu3okXxaw==", - "TIWSM78m0RprwgPGK/e0JA==", - "r/b5px/UImGNjT/X5sYjuA==", - "7K8l6KoP0BH82/WMLntfrg==", - "gEHGeR2F82OgBeAlnYhRSw==", - "1/SGIab+NnizimUmNDC4wA==", - "WADmxH7R6B4LR+W6HqQQ6A==", - "pcoBh5ic7baSD4TZWb3BSw==", - "es/L9iW8wsyLeC5S4Q8t+g==", - "D175i+2bZ7aWa4quSSkQpA==", - "WQMffxULFKJ+bun6NrCURA==", - "82hTTe1Nr4N2g7zwgGjxkw==", - "oyYtf08AkWLR52bXm5+sKw==", - "8uP4HUnSodw88yoiWXOIcw==", - "x2NpqNnqRihktNzpxmepkQ==", - "x5zMDuW66467ofgL3spLUQ==", - "OMO4pqzfcbQ11YO4nkTXfg==", - "N4/mQFyhDpPzmihjFJJn6w==", - "NN/ymVQNa17JOTGr6ki3eQ==", - "htDbVu1xGhCRd8qoMlBoMg==", - "S47hklz3Ow+n5aY6+qsCoA==", - "ji+1YHlRvzevs3q5Uw1gfA==", - "3Y4w0nETru3SiSVUMcWXqw==", - "XfBOCJwi2dezYzLe316ivw==", - "kMUdiwM7WR8KGOucLK4Brw==", - "V/xG5QFyx1pihimKmAo8ZA==", - "sQskMBELEq86o1SJGQqfzg==", - "6+jhreeBLfw64tJ+Nhyipw==", - "8iYdEleTXGM+Wc85/7vU9w==", - "D7piVoB2NJlBxK5owyo4+g==", - "hDGa2yLwNvgBd/v6mxmQaQ==", - "WLsh3UF4WXdHwgnbKEwRlQ==", - "D5jaV+HtXkSpSxJPmaBDXg==", - "jCgdKXsBCgf7giUKnr6paQ==", - "XqW7UBTobbV4lt1yfh0LZw==", - "EbGG4X18upaiVQmPfwKytg==", - "dXDPnL1ggEoBqR13aaW9HA==", - "Vik8tGNxO0xfdV0pFmmFDw==", - "Swjn3YkWgj0uxbZ1Idtk+A==", - "JPxEncA4IkfBDvpjHsQzig==", - "F5FcNti7lUa9DyF2iEpBug==", - "HJYgUxFZ66fRT8Ka73RaUg==", - "Jbxl8Nw1vlHO9rtu0q/Fpg==", - "fmC+85h5WBuk8fDEUWPjtQ==", - "dZgMquvZmfLqP4EcFaWCiA==", - "XF/yncdoT4ruPeXCxEhl9Q==", - "QJEbr3+42P9yiAfrekKdRQ==", - "Sr9c0ReRpkDYGAiqSy683g==", - "Nr4zGo5VUrjXbI8Lr4YVWQ==", - "NDZWIhhixq7NT8baJUR4VQ==", - "GFRJoPcXlkKSvJRuBOAYHQ==", - "WHutPin+uUEqtrA7L8878A==", - "2rhjiY0O0Lo36wTHjmlNyw==", - "XsF7R12agx/KkRWl0TyXRA==", - "R6cO8GzYfOGTIi773jtkXw==", - "zrZWcqQsUE3ocWE0fG+SOA==", - "uNzpptKjihEfKRo5A1nWmw==", - "gICaI06E9scnisonpvqCsA==", - "TA9WjiLAFgJubLN4StPwLw==", - "sBpytpE38xz0zYeT+0qc2A==", - "Ej7W3+67kCIng3yulXGpRQ==", - "nR3ACzeVF5YcLX6Gj6AGyQ==", - "b0vZfEyuTja2JYMa20Rtbg==", - "f1h+Vp+xmdZsZIziHrB2+g==", - "WzjvUJ4jZAEK7sBqw+m07A==", - "OzMR5D2LriC5yrVd5hchnA==", - "cw1gBLtxH/m4H7dSM7yvFg==", - "CZbd+UoTz0Qu1kkCS3k8Xg==", - "WtT0QAERZSiIt2SFDiAizg==", - "QsquNcCZL9wv7oZFqm64vQ==", - "FXzaxi3nAXBc8WZfFElQeA==", - "Ml3mi1lGS1IspHp3dYYClg==", - "XGAXhUFjORwKmAq9gGEcRg==", - "wOhbpTzmFla8R0kI9OiHaA==", - "qoK2keBg3hdbn7Q24kkVXg==", - "ZAQHWU6RMg4IadOxuaukyw==", - "RiahBXX2JbPzt8baPiP/8g==", - "Qx6rVv9Xj8CBjqikWI9KFA==", - "ZRnR6i+5WKMRfs3BDRBCJg==", - "91LQuW6bMSxl10J/UDX23A==", - "0dIeIM5Zvm5nSVWLy94LWg==", - "Ja3ECL7ClwDrWMTdcSQ6Ug==", - "f6iLrMpxKhFxIlfRsFAuew==", - "iSeH0JFSGK73F470Rhtesw==", - "DwOTyyCoUfaSShHZx9u6xg==", - "rdeftHE7gwAT67wwhCmkYQ==", - "kUhyc3G8Zvx8+q5q5nVEhw==", - "W8bATujVUT80v2XGJTKXDg==", - "dMRx4Mf6LrN64tiJuyWmDw==", - "9cvHJmim9e0pOaoUEtiM6A==", - "RHToSGASrwEmvzjX6VPvNQ==", - "V7eji28JSg3vTi30BCS7gw==", - "4+htiqjEz9oq0YcI/ErBVg==", - "jKJn4czwUl/6wtZklcMsSg==", - "bvyB6OEwhwCIfJ6KRhjnRw==", - "59ipbMH7cKBsF9bNf4PLeQ==", - "M/cQja3uIk1im9++brbBOA==", - "AChOz8avRYsvxlbWcorQ3w==", - "FcKjlHKfQAGoovtpf+DxWQ==", - "y+cl1/Knb9MZPz8nBB0M+w==", - "b8BZV1NfBdLi70ir4vYvZg==", - "aFJuE/s+Kbge4ppn+wulkA==", - "CWBGcRFYwZ0va6115vV/oQ==", - "glnqaRfwm6NxivtB2nySzw==", - "mPk1IsU5DmDFA/Ym5+1ojw==", - "LGwcvetzQ3QqKjNh5vA8vw==", - "yctId8ltkl3+xqi9bj+RqA==", - "spJI3xFUlpCDqzg0XCxopA==", - "V8m51xgUgywRoV6BGKUrgg==", - "rgcXxjx3pDLotH7TTfAoZw==", - "/TSsi/AwKHtP6kQaeReI3w==", - "8dbyfox/isKLsnVjQNsEXg==", - "MOrAbuJTyGKPC6MgYJlx5Q==", - "uNWFZlP7DA96sf+LWiAhtQ==", - "hNHqznsrIVRSQdII6crkww==", - "GT6WUDXiheKAM7tPg3he9A==", - "JC8Q+8yOJ52NvtVeyHo68w==", - "HMQarkPWOUDIg5+5ja2dBQ==", - "nknBKPgb7US42v8A0fTl/w==", - "fDOUzPTU2ndpbH0vgkgrJQ==", - "GTNttXfMniNhrbhn92Aykg==", - "D2JcY4zWwqaCKebLM8lPiQ==", - "/c34NtdUZAHWIwGl3JM8Tw==", - "/G26n5Xoviqldr5sg/Jl3w==", - "GF0lY77rx1NQzAsZpFtXIQ==", - "BMOi5JmFUg5sCkbTTffXHw==", - "R+beucURp/H5jLs4kW6wmg==", - "xfYZ6qhWNBqqJ0PdWRjOwA==", - "Ahpi9+nl13kPTdzL+jgqMw==", - "oIU19xAvLJwQSZzIH577aA==", - "50xwiYvGQytEDyVgeeOnMg==", - "M0ESOGwJ4WZ4Ons1ljP0bQ==", - "fS471/rN4K2m10mUwGFuLg==", - "RrE3B3X/SJi3CqCUlTYwaw==", - "oDca3JEdRb4vONT9GUUsaQ==", - "pHo1O5zrCHCiLvopP2xaWw==", - "7sCJ4RxbxRqVnF4MBoKfuQ==", - "7R5rFaXCxM3moIUtoCfM2g==", - "4rrSL6N0wyucuxeRELfAmw==", - "9Gkw+hvsR/tFY1cO89topg==", - "aw4CzX8pYbPVMuNrGCEcWg==", - "KyLQxi5UP+qOiyZl0PoHNQ==", - "T1pMWdoNDpIsHF8nKuOn2A==", - "Qv6wWP4PpycDGxe7EZNSCw==", - "ZJc7GV0Yb6MrXkpDVIuc8g==", - "aXrbsro7KLV8s4I4NMi4Eg==", - "7k5rBuh8FbTTI4TP87wBPQ==", - "NRyFx6jqO/oo9ojvbYzsAg==", - "P7eMlOz9YUcJO+pJy0Kpkw==", - "jpjpNjL1IKzJdGqWujhxCw==", - "9k1u/5TgPmXrsx3/NsYUhg==", - "c1wbFbN7AdUERO/xVPJlgw==", - "Yw4ztKv6yqxK9U1L0noFXg==", - "GnJKlRzmgKN9vWyGfMq3aA==", - "91VcAVv7YDzkC1XtluPigw==", - "h1NNwMy0RjQmLloSw1hvdg==", - "pzC8Y0Vj9MPBy3YXR32z6w==", - "UTmTgvl+vGiCDQpLXyVgOg==", - "CzWhuxwYbNB/Ffj/uSCtbw==", - "VOB+9Bcfu8aHKGdNO0iMRw==", - "X2Tawm2Cra6H7WtXi1Z4Qw==", - "6cTETZ9iebhWl+4W5CB+YQ==", - "X4hrgqMIcApsjA9qOWBoCw==", - "1buQEv2YlH/ljTgH0uJEtw==", - "FH5Z60RXXUiDk+dSZBxD3g==", - "FI2WhaSMb3guFLe3e9il8Q==", - "O/EizzJSuFY8MpusBRn7Tg==", - "b6rrRA0W247O+FfvDHbVCQ==", - "ng1Q0A7ljho3TUWWYl46sw==", - "1Ym0lyBJ9aFjhJb/GdUPvQ==", - "+OXdvbTxHtSoLg7bZMho4w==", - "cuQslgfqD2VOMhAdnApHrA==", - "pCQmlnn3BxhsV2GwqjRhXg==", - "6PzjncEw2wHZg7SP7SQk9w==", - "nqtQI1bSM7DCO9P1jGV97Q==", - "O1ckWUwuhD44MswpaD6/rw==", - "RUmhye56tQu9xXs4SRJpOQ==", - "llujnWE17U8MIHmx4SbrSA==", - "UwqBVd4Wfias4ElOjk2BzQ==", - "kBAB2PSjXwqoQOXNrv80AA==", - "w1zN28mSrI/gqHsgs4ME3A==", - "301utVPZ93AnPLYbsiJggw==", - "qIFpKKwUmztsBpJgMaVvSg==", - "QmcURiMzmVeUNaYPSOtTTg==", - "x/MpsQvziUpW40nNUHDS5Q==", - "t1O9jSNjg4DTIv/Za4NbtA==", - "1B5gxGQSGzVKoNd5Ol4N7g==", - "81iQLU+YwxNwq4of6e9z7A==", - "x0eIHCvQLd2jdDaXwSWTYQ==", - "96ORaz1JRHY1Gk8H74+C2g==", - "bNDKcFu8T5Y6OoLSV+o/Sw==", - "WrJMOuXSLKKzgmIDALkyNw==", - "+gpHnUj2GWocP74t5XWz4w==", - "z5DveTu377UW8IHnsiUGZg==", - "irnD9K8bsT+up/JUrxPw6A==", - "ginkFyNVMwkZLE49AbfqfA==", - "2hEzujfG3mR5uQJXbvOPTQ==", - "E9yeifEZtpqlD0N3pomnGw==", - "OpC/sL320wl5anx6AVEL+A==", - "D7wN7b5u5PKkMaLJBP9Ksw==", - "83WGpQGWyt6mCV+emaomog==", - "X6ulLp4noBgefQTsbuIbYQ==", - "BH+rkZWQjTp7au6vtll/CQ==", - "Ex3x5HeDPhgO2S9jjCFy4g==", - "YNqIHCmBp/EbCgaPKJ7phw==", - "312g8iTB9oJgk/OqcgR7Cw==", - "LcF0OqPWrcpHby8RwXz1Yg==", - "gaEtlJtD6ZjF5Ftx0IFt0A==", - "bvbMJZMHScwjJALxEyGIyg==", - "StoXC7TBzyRViPzytAlzyQ==", - "XqFSbgvgZn0CpaZoZiRauQ==", - "AqHVaj3JcR44hnMzUPvVYg==", - "jTg9Y6EfpON4CRFOq0QovA==", - "q/siBRjx6wNu+OTvpFKDwA==", - "goSgZ8N5UbT5NMnW3PjIlQ==", - "9onh6QKp70glZk9cX3s34A==", - "o5XVEpdP4OXH0NEO4Yfc/A==", - "a5gZ5uuRrXEAjgaoh7PXAg==", - "PaROi5U16Tk35p0EKX5JpA==", - "dtnE401dC0zRWU0S/QOTAg==", - "7J3FoFGuTIW36q0PZkgBiw==", - "hiYg+aVzdBUDCG0CXz9kCw==", - "vhdFtKVH4bVatb4n8KzeXw==", - "DWKsPfKDAtfuwgmc2dKUNg==", - "M2JMnViESVHTZaru6LDM6w==", - "G/PA+kt0N+jXDVKjR/054A==", - "6rqK8sjLPJUIp7ohkEwfZg==", - "wajwXfWz2J+O+NVaj6j2UQ==", - "C4QEzQKGxyRi2rjwioHttA==", - "N/HgDydvaXuJvTCBhG/KtA==", - "6erpZS36qZRXeZ9RN9L+kw==", - "bbBsi6tXMVWyq3SDVTIXUg==", - "aySnrShOW4/xRSzl/dtSKQ==", - "rxfACPLtKXbYua18l3WlUw==", - "L4+C6I7ausPl6JbIbmozAg==", - "R3ijnutzvK6IKV3AKHQZSA==", - "leDlMcM+B1mDE8k5SWtUeg==", - "KGI/cXVz6v6CfL8H6akcUQ==", - "NtwqUO3SKZE/9MXLbTJo/g==", - "dJHKDkfMFJeoULg7U4wwDQ==", - "IEz72W2/W8xBx5aCobUFOQ==", - "wUYhs4j3W9nIywu1HIv2JA==", - "GzbeM7snhe+M+J7X+gAsQw==", - "3/1puZTGSrD9qNKPGaUZww==", - "eKQCVzLuzoCLcB4im8147A==", - "CCK+6Dr72G3WlNCzV7nmqw==", - "CJoZn5wdTXbhrWO5LkiW0g==", - "bJ1cZW7KsXmoLw0BcoppJg==", - "OlpA9HsF8MBh7b45WZSSlg==", - "JZRjdJLgZ+S0ieWVDj8IJg==", - "uhT12XY79CtbwhcSfAmAXQ==", - "isep9d+Q7DEUf0W7CJJYzw==", - "K9A87aMlJC8XB9LuFM913g==", - "uqe3rFveJ2JIkcZQ3ZMXHQ==", - "0e8hM3E5tnABRyy29A8yFw==", - "4iiCq+HhC+hPMldNQMt0NA==", - "X4o0OkTz0ec70mzgwRfltA==", - "1E3pMgAHOnHx3ALdNoHr8Q==", - "xNilc7UOu1kyP0+nK5MrLw==", - "DQlZWBgdTCoYB1tJrNS5YQ==", - "iruDC5MeywV4yA8o1tw/KQ==", - "z+1oDVy8GJ5u/UDF+bIQdA==", - "uExgqZkkJnZj252l5dKAGg==", - "ZgdpqFrVGiaHkh9o3rDszg==", - "5N2oi2pB69NxeNt08yPLhw==", - "G37U8XTFyshfCs7qzFxATg==", - "0ZEC3hy411LkOhKblvTcqg==", - "ITZ3P47ALS0JguFms6/cDA==", - "WWN44lbUnEdHmxSfMCZc6w==", - "r2f2MyT+ww1g9uEBzdYI1w==", - "ZvvxwDd0I6MsYd7aobjLUA==", - "uQs79rbD/wEakMUxqMI48A==", - "022B0oiRMx8Xb4Af98mTvQ==", - "afMd/Hr3rYz/l7a3CfdDjg==", - "xmsYnsJq78/f9xuKuQ2pBQ==", - "dFetwmFw+D6bPMAZodUMZQ==", - "TBQpcKq2huNC5OmI2wzRQw==", - "skrQRB9xbOsiSA19YgAdIQ==", - "anyANMnNkUqr3JuPJz5Qzw==", - "6QUGE2S8oFYx4T4nW56cCw==", - "rwtF86ZAbWyKI6kLn4+KBw==", - "6txm8z4/LGCH0cpaet/Hsg==", - "wdRyYjaM11VmqkkxV/5bsA==", - "+k5lDb+QdNc9iZ01hL5yBg==", - "k/pBSWE2BvUsvJhA9Zl5uw==", - "jQjyjWCEo9nWFjP4O8lehw==", - "R6Me6sSGP5xpNI8R0xGOWw==", - "9+hjTVMQUsvVKs7Tmp52tg==", - "VQIpquUqmeyt/q6OgxzduQ==", - "KXvdjZ3rRKn60djPTCENGA==", - "5HovoyHtul8lXh+z8ywq9A==", - "1+XWdu4qCqLLVjqkKz3nmA==", - "LCj4hI520tA685Sscq6uLw==", - "b53qqLnrTBthRXmmnuXWvw==", - "WTr3q/gDkmB4Zyj7Ly20+w==", - "FbxScyuRacAQkdQ034ShTA==", - "qaTdVEeZ6S8NMOxfm+wOMA==", - "ZNrjP1fLdQpGykFXoLBNPw==", - "/Bwpt5fllzDHq2Ul6v86fA==", - "/mFp3GFkGNLhx2CiDvJv4A==", - "RppDe/WGt1Ed6Vqg1+cCkQ==", - "6M6QapJ5xtMXfiD3bMaiLA==", - "Ghuj9hAyfehmYgebBktfgA==", - "GncGQgmWpI/fZyb/6zaFCg==", - "R1TCCfgltnXBvt5AiUnCtQ==", - "5NEP7Xt7ynj6xCzWzt21hQ==", - "4yEkKp2FYZ09mAhw2IcrrA==", - "y2Tn2gmhKs5WKc01ce74rg==", - "wnfYUctNK+UPwefX5y4/Rw==", - "BV1moliPL15M14xkL+H1zw==", - "80C9TB9/XT1gGFfQDJxRoA==", - "yL1DwlIIREPuyuCFULi0uw==", - "D09afzGpwCEH0EgZUSmIZA==", - "eCy/T+a8kXggn1L8SQwgvA==", - "+dIEf5FBrHpkjmwUmGS6eg==", - "kzXsrxWRnWhkA82LsLRYog==", - "Nf9fbRHm844KZ2sqUjNgkA==", - "XAq/C+XyR6m3uzzLlMWO5Q==", - "jiV+b/1EFMnHG6J0hHpzBg==", - "HK0yf7F97bkf1VYCrEFoWA==", - "Cz1G77hsDtAjpe0WzEgQog==", - "xdCCdP8SNBOK3IsX6PiPQA==", - "8snljTGo/uICl9q0Hxy7/A==", - "sLdxIKap0ZfC3GpUk3gjog==", - "IA1jmtfpYkz/E2wD0+27WA==", - "PPa7BDMpRdxJdBxkuWCxKA==", - "CuGIxWhRLN7AalafBZLCKQ==", - "MWcV03ULc0vSt/pFPYPvFA==", - "QVwuN66yPajcjiRnVk/V8g==", - "aLY2pCT0WfFO5EJyinLpPg==", - "dGrf9SWJ13+eWS6BtmKCNw==", - "YtZ8CYfnIpMd2FFA5fJ+1Q==", - "Umd+5fTcxa3mzRFDL9Z8Ww==", - "Al8+d/dlOA5BXsUc5GL8Tg==", - "/KYZdUWrkfxSsIrp46xxow==", - "kr8tw1+3NxoPExnAtTmfxg==", - "PwvPBc+4L73xK22S9kTrdA==", - "VWNDBOtjiiI4uVNntOlu/A==", - "lJFPmPWcDzDp5B2S8Ad8AA==", - "Mofqu40zMRrlcGRLS42eBw==", - "BuENxPg7JNrWXcCxBltOPg==", - "nmD7fEU4u7/4+W/pkC4/0Q==", - "axEl7xXt/bwlvxKhI7hx4g==", - "W04GeDh+Tk/I1S85KlozRA==", - "tVw8U1AsslIFmQs4H1xshg==", - "TSPFvkgw6uLsJh66Ou0H9w==", - "IYIbEaErHoFBn8sTT9ICIQ==", - "WBu0gJmmjVdVbjDmQOkU6w==", - "ZgjifTVKmxOieco81gnccQ==", - "ZrCnZB/U/vcqEtI1cSvnww==", - "2D6yhuABiaFFoXz0Lh0C+w==", - "SfwnYZCKP1iUJyU1yq4eKg==", - "tsiqwelcBAMU/HpLGBtMGw==", - "S9L29U2P5K8wNW+sWbiH7w==", - "sGLPmr568+SalaQr8SE/PA==", - "Hm6MG6BXbAGURVJKWRM6ZA==", - "euxzbIq4vfGYoY3s1QmLcw==", - "/FchS2nPezycB8Bcqc2dbg==", - "ZKvox7BaQg4/p5jIX69Umw==", - "HkbdaMuDTPBDnt3wAn5RpQ==", - "eddhS+FkXxiUnbPoCd5JJw==", - "Muf2Eafcf9G3U2ZvQ9OgtQ==", - "a7Pv1SOWYnkhIUC22dhdDA==", - "O839JUrR+JS30/nOp428QA==", - "2qK2ZEY9LgdKSTaLf6VnLA==", - "BTiGLT6XdZIpFBc91IJY6g==", - "EqYq2aVOrdX5r7hBqUJP7g==", - "SIuKH/Qediq0TyvqUF93HQ==", - "c5ymZKqx/td1MiS2ERiz9A==", - "rqucO37p86LpzehR/asCSQ==", - "1tpM0qgdo7JDFwvT0TD78g==", - "Ar1Eb/f/LtuIjXnnVPYQlA==", - "V8q+xz4ljszLZMrOMOngug==", - "P5WPQc5NOaK7WQiRtFabkw==", - "Xo8ZjXOIoXlBjFCGdlPuZw==", - "jTmPbq+wh30+yJ/dRXk1cA==", - "KSumhnbKxMXQDkZIpDSWmQ==", - "Kh/J1NpDBGoyDU+Mrnnxkg==", - "3BjLFon1Il0SsjxHE2A1LQ==", - "dml2gqLPsKpbIZ93zTXwCQ==", - "ZyoaR1cMiKAsElmYZqKjLA==", - "vnOJ3e9Zd4wPx8PX7QgZzQ==", - "2melaInV0wnhBpiI3da6/A==", - "mUek9NkXm8HiVhQ6YXiyzA==", - "RZTpYKxOAH9JgF1QFGN+hw==", - "a/Y6IAVFv0ykRs9WD+ming==", - "yhRi5M9Etuu9HSu4d24i3w==", - "+1gcqAqaRZwCj5BGiZp3CA==", - "o1zeXHJEKevURAAbUE/Vog==", - "cvOg7N4DmTM+ok1NBLyBiQ==", - "uPdjKJIGzN7pbGZDZdCGaA==", - "REnDNe9mGfqVGZt+GdsmjQ==", - "XqTK/2QuGWj50tGmiDxysA==", - "bL2FuwsPT7a7oserJQnPcw==", - "uO+uK1DntCxVRr1KttfUIw==", - "Xconi1dtldH90Wou9swggw==", - "HRF3WL/ue3/QlYyu7NUTrA==", - "5LuFDNKzMd2BzpWEIYO2Ww==", - "dNTU+/2DdZyGGTdc+3KMhQ==", - "H+NHjk/GJDh/GaNzMQSzjg==", - "/Ph/6l/lFNVqxAje1+PgFA==", - "4WRdAjiUmOQg2MahsunjAg==", - "j+lDhAnWAyso+1N8cm85hQ==", - "nFBXCPeiwxK9mLXPScXzTA==", - "vGKknndb4j6VTV8DxeT4fQ==", - "fdqt93OrpG13KAJ5cASvkg==", - "1MIn73MLroxXirrb+vyg2Q==", - "Q7teXmTHAC5qBy+t7ugf0w==", - "bWwtTFlhO3xEh/pdw0uWaQ==", - "Omi2ZB9kdR1HrVP2nueQkA==", - "+ZozWaPWw8ws1cE5DJACeg==", - "3FH4D31nKV13sC9RpRZFIg==", - "4kXlJNuT79XXf1HuuFOlHw==", - "36XDmX6j542q+Oei1/x0gw==", - "MqqDg9Iyt4k3vYVW5F+LDw==", - "cvrGmub2LoJ+FaM5HTPt9A==", - "uC2lzm7HaMAoczJO6Z/IhQ==", - "MnStiFQAr3QlaRZ02SYGaQ==", - "ZuayB6IpbeITokKGVi9R5w==", - "FtxpWdhEmC6MT61qQv4DGA==", - "KujFdhhgB9q4oJfjYMSsLg==", - "ZV8mEgJweIYk0/l0BFKetA==", - "gDLjxT7vm07arF4SRX5/Vg==", - "/MEOgAhwb7F0nBnV4tIRZA==", - "k2KP9oPMnHmFlZO6u6tgyw==", - "fbTm027Ms0/tEzbGnKZMDA==", - "HOi+vsGAae4vhr+lJ5ATnQ==", - "9Bet5waJF5/ZvsYaHUVEjQ==", - "Wd0dOs7eIMqW5wnILTQBtg==", - "z/e5M2lE9qh3bzB97jZCKA==", - "b16O4LF7sVqB7aLU2f3F1A==", - "lsBTMnse2BgPS6wvPbe7JA==", - "0nOg18ZJ/NicqVUz5Jr0Hg==", - "MFeXfNZy6Q9wBfZmPQy3xg==", - "ksOFI9C7IrDNk4OP6SpPgw==", - "NquRbPn8fFQhBrUCQeRRoQ==", - "ccmy4GVuX967KaQyycmO0w==", - "DY0IolKTYlW+jbKLPAlYjQ==", - "aJFbBhYtMbTyMFBFIz/dTA==", - "9pdeedz1UZUlv8jPfPeZ1g==", - "qZ2q5j2gH3O56xqxkNhlIA==", - "N7fHwb397tuQHtBz1P80ZQ==", - "uOkMpYy/7DYYoethJdixfQ==", - "E9ajQQMe02gyUiW3YLjO/A==", - "dFSavcNwGd8OaLUdWq3sng==", - "TAD0Lk95CD86vbwrcRogaQ==", - "jLI3XpVfjJ6IzrwOc4g9Pw==", - "CzP13PM/mNpJcJg8JD3s6w==", - "GSWncBq4nwomZCBoxCULww==", - "9k17UqdR1HzlF7OBAjpREA==", - "TrWS+reCJ0vbrDNT5HDR9w==", - "CXMKIdGvm60bgfsNc+Imvg==", - "6NP81geiL14BeQW6TpLnUA==", - "hW9DJA1YCxHmVUAF7rhSmQ==", - "8M0kSvjn5KN8bjsMdUqKZQ==", - "eS/vTdSlMUnpmnl1PbHjyw==", - "h2B0ty0GobQhDnFqmKOpKQ==", - "n7KL1Kv027TSxBVwzt9qeA==", - "yYmnM/WOgi+48Rw7foGyXA==", - "FhthAO5IkMyW4dFwpFS7RA==", - "81ZH3SO0NrOO+xoR/Ngw1g==", - "t7HaNlXL16fVwjgSXmeOAQ==", - "N+K1ibXAOyMWdfYctNDSZQ==", - "yQCLV9IoPyXEOaj3IdFMWw==", - "3+zsjCi7TnJhti//YXK35w==", - "600mjiWke4u0CDaSQKLOOg==", - "K4VS+DDkTdBblG93l2eNkA==", - "5KOgetfZR+O2wHQSKt41BQ==", - "kj5WqpRCjWAfjM7ULMcuPQ==", - "AxEjImKz4tMFieSo7m60Sg==", - "jp5Em/0Ml4Txr1ptTUQjpg==", - "jQVlDU+HjZ2OHSDBidxX5A==", - "4NHQwbb3zWq2klqbT/pG6g==", - "PeJS+mXnAA6jQ0WxybRQ8w==", - "l6Ssc04/CnsqUua9ELu2iQ==", - "nFPDZGZowr3XXLmDVpo7hg==", - "yYBIS9PZbKo7Gram7IXWPA==", - "/HU2+fBqfWTEuqINc0UZSA==", - "adT+OjEB2kqpeYi4kQ6FPg==", - "GW1Uaq622QamiiF24QUA0g==", - "rTwJggSxTbwIYdp07ly0LA==", - "4yrFNgqWq17zVCyffULocA==", - "vvh9vAIrXjIwLVkuJb5oDQ==", - "C7UaoIEXsVRxjeA0u99Qmw==", - "x1A74vg/hwwjAx6GrkU8zw==", - "7XRiYvytcwscemlxd9iXIQ==", - "64AA4jLHXc1Dp15aMaGVcA==", - "u/QxrP1NOM/bOJlJlsi/jQ==", - "5M3dFrAOemzQ0MAbA8bI5w==", - "wyqmQGB6vgRVrYtmB2vB7w==", - "8vLA9MOdmLTo3Qg+/2GzLA==", - "/u5W2Gab4GgCMIc4KTp2mg==", - "lhAOM81Ej6YZYBu45pQYgg==", - "MArbGuIAGnw4+fw6mZIxaw==", - "ZZImGypBWwYOAW43xDRWCQ==", - "L2IeUnATZHqOPcrnW2APbA==", - "bQKkL+/KUCsAXlwwIH0N3w==", - "f09F7+1LRolRL5nZTcfKGA==", - "hPnPQOhz4QKhZi02KD6C+A==", - "78b8sDBp28zUlYPV5UTnYw==", - "iVDd2Zk7vwmEh97LkOONpQ==", - "LHQETSI5zsejvDaPpsO29g==", - "Yjm5tSq1ejZn3aWqqysNvA==", - "gkrg0NR0iCaL7edq0vtewA==", - "Lo1xTCEWSxVuIGEbBEkVxA==", - "8GyPup4QAiolFJ9v80/Nkw==", - "3L3KEBHhgDwH615w4OvgZA==", - "hJSP7CostefBkJrwVEjKHA==", - "9oQ/SVNJ4Ye9lq8AaguGAQ==", - "n7Bns42aTungqxKkRfQ5OQ==", - "K5lhaAIZkGeP5rH2ebSJFw==", - "ZaPsR9X77SNt7dLjMJUh8A==", - "18ndtDM9UaNfBR1cr3SHdA==", - "0QbH4oI8IjZ9BRcqRyvvDQ==", - "J/eAtAPswMELIj8K2ai+Xg==", - "qenHZKKlTUiEFv6goKM/Mw==", - "vjrSYGUpeKOtJ2cNgLFg2g==", - "DA+3fjr7mgpwf6BZcExj0w==", - "rh7bzsTQ1UZjG7amysr0Gg==", - "tFMJRXfWE9g78O1uBUxeqQ==", - "e/nWuo5YalCAFKsoJmFyFA==", - "gqehq46BhFX2YLknuMv02w==", - "Uudn69Kcv2CGz2FbfJSSEA==", - "Otz/PgYOEZ1CQDW54FWJIQ==", - "IwfeA6d0cT4nDTCCRhK+pA==", - "jgNijyoj2JrQNSlUv4gk4A==", - "KzWdWPP2gH0DoMYV4ndJRg==", - "pv/m2mA/RJiEQu2Qyfv9RA==", - "ATmMzriwGLl+M3ppkfcZNA==", - "tVvWdA+JqH0HR2OlNVRoag==", - "n6QVaozMGniCO0PCwGQZ6w==", - "gU3gu8Y5CYVPqHrZmLYHbQ==", - "cBBOQn7ZjxDku0CUrxq2ng==", - "w+jzM0I5DRzoUiLS/9QIMQ==", - "MLlVniZ08FHAS5xe+ZKRaA==", - "wMyJLQJdmrC2TSeFkIuSvQ==", - "dG98w8MynOoX7aWmkvt+jg==", - "zm+z+OOyHhljV2TjA3U9zw==", - "Tk5MAqd1gyHpkYi8ErlbWg==", - "g6zSo8BvLuKqdmBFM1ejLA==", - "d0VAZLbLcDUgLgIfT1GmVQ==", - "SNPYH4r/J9vpciGN2ybP5Q==", - "XA2hUgq3GVPpxtRYiqnclg==", - "fVCRaPsTCKEVLkoF4y3zEw==", - "FpgdsQ2OG+bVEy3AeuLXFQ==", - "JquDByOmaQEpFb47ZJ4+JA==", - "e369ZIQjxMZJtopA//G55Q==", - "Nsd+DfRX6L54xs+iWeMjCQ==", - "+/UCpAhZhz368iGioEO8aQ==", - "e5l9ZiNWXglpw6nVCtO8JQ==", - "Cl1u5nGyXaoGyDmNdt38Bw==", - "6sNP0rzCCm3w976I2q2s/w==", - "qcpeZWUlPllQYZU6mHVwUw==", - "kzYddqiMsY3EYrpxve2/CQ==", - "3iC21ByW/YVL+pSyppanWw==", - "3HPOzIZxoaQAmWRy9OkoSg==", - "xsCZVhCk2qJmOqvUjK3Y8Q==", - "i2sSvrTh/RdLJX0uKhbrew==", - "7Y87wVJok20UfuwkGbXxLg==", - "ibsb1ncaLZXAYgGkMO7tjQ==", - "+VfRcTBQ80KSeJRdg0cDfw==", - "kgKWQJJQKLUuD2VYKIKvxA==", - "ARKIvf4+zRF8eCvUITWPng==", - "1fztTtQWNMIMSAc5Hr6jMQ==", - "md6zNd7ZBn3qArYqQz7/fw==", - "kvAaIJb+aRAfKK104dxFAA==", - "UIXytIHyVODxlrg+eQoARA==", - "Dk0L/lQizPEb3Qud6VHb1Q==", - "64YsV2qeDxk2Q6WK/h7OqA==", - "90dtIMq0ozJXezT2r79vMQ==", - "wy/Z8505o4sVovk4UuBp1A==", - "ytDXLDBqWiU1w3sTurYmaw==", - "9pk75mBzhmcdT+koHvgDlw==", - "DQeib845UqBMEl96sqsaSg==", - "UPYR575ASaBSZIR3aX1IgQ==", - "swsVVsPi/5aPFBGP+jmPIw==", - "1cj1Fpd3+UiBAOahEhsluA==", - "ifuJCv9ZA84Vz1FYAPsyEA==", - "uu+ncs63SdQIvG6z4r7Q3Q==", - "UvC1WADanMrhT+gPp/yVqA==", - "llOvGOUDVfX68jKnAlvVRA==", - "SusSOsWNoAerAIMBVWHtfA==", - "VznvTPAAwAev+yhl9oZT0w==", - "luR/kvHLwA6tSdLeTM4TzA==", - "PcdBtV8pfKU0YbDpsjPgwg==", - "5l6kDfjtZjkTZPJvNNOVFw==", - "4FBBtWPvqJ3dv4w25tRHiQ==", - "JJbzQ/trOeqQomsKXKwUpQ==", - "0bj069wXgEJbw7dpiPr8Tg==", - "tejpAZp7y32SO2+o4OGvwQ==", - "kq26VyDyJTH/eM6QvS2cMw==", - "+zBkeHF4P8vLzk1iO1Zn3Q==", - "BzkNYH03gF/mQY71RwO3VA==", - "RnxOYPSQdHS6fw4KkDJtrA==", - "65KhGKUBFQubRRIEdh9SwQ==", - "k1DPiH6NkOFXP/r3N12GyA==", - "DqzWt1gfyu/e7RQl5zWnuQ==", - "gnez1VrH+UHT8C/SB9qGdA==", - "vZtL0yWpSIA+9v8i23bZSg==", - "FNvQqYoe0s/SogpAB7Hr1Q==", - "6nwR+e9Qw0qp8qIwH9S/Mg==", - "BPT4PQxeQcsZsUQl33VGmg==", - "rOYeIcB+Rg5V6JG2k4zS2w==", - "Je1UESovkBa9T6wS0hevLw==", - "HFHMGgfOeO0UPrray1G+Zw==", - "NBmB/cQfS+ipERd7j9+oVg==", - "iIm8c9uDotr87Aij+4vnMw==", - "S3VQa6DH+BdlSrxT/g6B5g==", - "BwRA+tMtwEvth28IwpZx+w==", - "vg3jozLXEmAnmJwdfcEN0g==", - "gW0oKhtQQ7BxozxUWw5XvQ==", - "Q6vGRQiNwoyz7bDETGvi5g==", - "Ak3rlzEOds6ykivfg39xmw==", - "G4qzBI1sFP2faN+tlRL/Bw==", - "ND9l4JWcncRaSLATsq0LVw==", - "yQmNZnp/JZywbBiZs3gecA==", - "ZoNSxARrRiKZF5Wvpg7bew==", - "GhpJfRSWZigLg/azTssyVA==", - "QyyiJ5I/OZC50o89fa5EmQ==", - "4kj0S8XlmhHXoUP7dQItUw==", - "Dt8Q5ORzTmpPR2Wdk0k+Aw==", - "/hFhjFGJx2wRfz6hyrIpvA==", - "eFimq+LuHi42byKnBeqnZQ==", - "JrKGKAKdjfAaYeQH8Y2ZRQ==", - "JFFeXsFsMA59iNtZey7LAA==", - "91SdBFJEZ65M+ixGaprY/A==", - "+S+WXgVDSU1oGmCzGwuT3g==", - "1X14kHeKwGmLeYqpe60XEA==", - "4xojeUxTFmMLGm6jiMYh/Q==", - "+1e7jvUo8f2/2l0TFrQqfA==", - "8WU1vLKV1GhrL7oS9PpABg==", - "DYWCPUq/hpjr6puBE7KBHg==", - "birqO8GOwGEI97zYaHyAuw==", - "6e8boFcyc8iF0/tHVje4eQ==", - "FLvED9nB9FEl9LqPn7OOrA==", - "ji306HRiq965zb8EZD2uig==", - "AklOdt9/2//3ylUhWebHRw==", - "VGRCSrgGTkBNb8sve0fYnQ==", - "oqlkgrYe9aCOwHXddxuyag==", - "KXuFON8tMBizNkCC48ICLA==", - "9aKH1u5+4lgYhhLztQ4KWA==", - "3hVslsq98QCDIiO40JNOuA==", - "OOS6wQCJsXH8CsWEidB35A==", - "YXHQ3JI9+oca8pc/jMH6mA==", - "V9vkAanK+Pkc4FGAokJsTA==", - "OFLn4wun6lq484I7f6yEwg==", - "3WVBP9fyAiBPZAq3DpMwOQ==", - "5gGoDPTc/sOIDLngmlEq4A==", - "E2lvMXqHdTw0x+KCKVnblg==", - "f1Gs++Iilgq9GHukcnBG3w==", - "uIkVijg7RPi/1j7c18G1qA==", - "9T7gB0ZkdWB0VpbKIXiujQ==", - "KCJJfgLe00+tjSfP6EBcUg==", - "WbAdlac/PhYUq7J2+n5f+w==", - "GLnS9wDCje7TOMvBX9jJVA==", - "VAg/aU5nl72O+cdNuPRO4g==", - "kzTl7WH/JXsX1fqgnuTOgw==", - "1HDgfU7xU7LWO/BXsODZAQ==", - "D0W5F7gKMljoG5rlue1jrg==", - "9reBKZ1Rp6xcdH1pFQacjw==", - "SSKhl2L3Mvy93DcZulADtA==", - "hlu7os0KtAkpBTBV6D2jyQ==", - "sfte/o9vVNyida/yLvqADA==", - "gYGQBLo5TdMyXks0LsZhsQ==", - "dNq2InSVDGnYXjkxPNPRxA==", - "fiv0DJivQeqUkrzDNlluRw==", - "msstzxq++XO0AqNTmA7Bmg==", - "DCjgaGV5hgSVtFY5tcwkuA==", - "aMmrAzoRWLOMPHhBuxczKg==", - "qNOSm15bdkIDSc/iUr+UTQ==", - "2nSTEYzLK77h5Rgyti+ULQ==", - "BhKO1s1O693Fjy1LItR/Jw==", - "kRnBEH6ILR5GNSmjHYOclw==", - "R97chlspND/sE9/HMScXjQ==", - "1Oykse0jQVbuR3MvW5ot4A==", - "Dmyb+a7/QFsU4d2cVQsxDw==", - "W5now3RWSzzMDAxsHSl++Q==", - "IrDuBrVu1HWm0BthAHyOLQ==", - "V6zyoX6MERIybGhhULnZiw==", - "ZQSDYgpsimK+lYGdXBWE/w==", - "lV70RNlE++04G1KFB3BMXA==", - "QmSBVvdk0tqH9RAicXq2zA==", - "qNyy6Fc0b8oOMWqqaliZ/w==", - "xvipmmwKdYt4eoKvvRnjEg==", - "Q7Df6zGwvb4rC+EtIKfaSw==", - "n1M2dgFPpmaICP+JwxHUug==", - "1k8tL2xmGFVYMgKUcmDcEw==", - "fFvXa1dbMoOOoWZdHxPGjw==", - "UP9mmAKzeQqGhod7NCqzhg==", - "PMCWKgog/G+GFZcIruSONw==", - "dnvatwSEcl73ROwcZ4bbIQ==", - "hY82j+sUQQRpCi6CCGea5A==", - "QoUC9nyK1BAzoUVnBLV2zw==", - "+aF4ilbjQbLpAuFXQEYMWQ==", - "XTCcsVfEvqxnjc0K5PLcyw==", - "ML7ipnY/g8mA1PUIju1j8Q==", - "tOkYq1BZY152/7IJ6ZYKUg==", - "2bsIpvnGcFhTCSrK9EW1FQ==", - "Af9j1naGtnZf0u1LyYmK1w==", - "ZmblZauRqO5tGysY3/0kDw==", - "PF0lpolQQXlpc3qTLMBk8w==", - "emVLJVzha7ui5OFHPJzeRQ==", - "gR0sgItXIH8hE4FVs9Q07w==", - "PTW+fhZq/ErxHqpM0DZwHQ==", - "g0kHTNRI7x/lAsr92EEppw==", - "24H9q+E8pgCEdFS7JO5kzQ==", - "HtDXgMuF8PJ1haWk88S0Ew==", - "pulldyBt2sw6QDvTrCh6zw==", - "ehwc2vvwNUAI7MxU4MWQZw==", - "enj9VEzLbmeOyYugTmdGfQ==", - "auvG6kWMnhCMi7c7e9eHrw==", - "R36O31Pj8jn0AWSuqI7X2Q==", - "3AVYtcIv7A5mVbVnQMaCeA==", - "T9WoUJNwp8h4Yydixbx6nA==", - "t0WN8TwMLgi8UVEImoFXKg==", - "mS99D+CXhwyfVt8xJ+dJZA==", - "AFdelaqvxRj6T3YdLgCFyg==", - "Lu02ic/E94s42A14m7NGCA==", - "7w3b73nN/fIBvuLuGZDCYQ==", - "O209ftgvu0vSr0UZywRFXA==", - "MQvAr+OOfnYnr/Il/2Ubkg==", - "e5txnNRcGs2a9+mBFcF1Qg==", - "YA0kMTJ82PYuLA4pkn4rfw==", - "QIKjir/ppRyS63BwUcHWmw==", - "P3y5MoXrkRTSLhCdLlnc4A==", - "WY7mCUGvpXrC8gkBB46euw==", - "g0GbRp2hFVIdc7ct7Ky7ag==", - "Cv079ZF55RnbsDT27MOQIA==", - "cvMJ714elj/HUh89a9lzOQ==", - "9inw7xzbqAnZDKOl/MfCqA==", - "F58ktE4O0f7C9HdsXYm+lw==", - "CsPkyTZADMnKcgSuNu1qxg==", - "mAzsVkijuqihhmhNTTz65g==", - "FxnbKnuDct4OWcnFMT/a5w==", - "P5wS+xB8srW4a5KDp/JVkA==", - "ctJYJegZhG42i+vnPFWAWw==", - "OrqJKjRndcZ8OjE3cSQv7g==", - "aXqiibI6BpW3qilV6izHaQ==", - "BA18GEAOOyVXO2yZt2U35w==", - "saEpnDGBSZWqeXSJm34eOA==", - "CUEueo8QXRxkfVdfNIk/gg==", - "H0UMAUfHFQH92A2AXRCBKA==", - "CT9g8mKsIN/VeHLSTFJcNQ==", - "E4NtzxQruLcetC23zKVIng==", - "203EqmJI9Q4tWxTJaBdSzA==", - "Do3aqbRKtmlQI2fXtSZfxQ==", - "JaYQXntiyznQzrTlEeZMIw==", - "VK95g27ws2C6J2h/7rC2qA==", - "CQ0PPwgdG3N6Ohfwx1C8xA==", - "/MeHciFhvFzQsCIw39xIZA==", - "u5cUPxM6/spLIV8VidPrAA==", - "OwArFF1hpdBupCkanpwT+Q==", - "PdBgXFq5mBqNxgCiqaRnkw==", - "lC5EumoIcctvxYqwELqIqw==", - "xoPSM86Se+1hHX0y3hhdkw==", - "F5bs0GGWBx9eBwcJJpXbqg==", - "1mw6LfTiirFyfjejf8QNGA==", - "daBhAvmE9shDgmciDAC5eg==", - "AvdeYb9XNOUFWiiz+XGfng==", - "JJJkp1TpuDx5wrua2Wml7g==", - "3y5Xk65ShGvWFbQxcZaQAQ==", - "l6QHU5JsJExNoOnqxBPVbw==", - "X2YfnPXgF2VHVX95ZcBaxQ==", - "g6udffWh7qUnSIo1Ldn3eA==", - "V2P75JFB4Se9h7TCUMfeNA==", - "IUZ5aGpkJ9rLgSg6oAmMlw==", - "pyrUqiZ98gVXxlXQNXv5fA==", - "83ERX2XJV3ST4XwvN7YWCg==", - "eJDUejE/Ez/7kV+S74PDYg==", - "M9oqlPb63e0kZE0zWOm+JQ==", - "0rTYcuVYdilO7zEfKrxY3A==", - "rfPTskbnoh3hRJH6ZAzQRg==", - "QtD35QhE8sAccPrDnhtQmQ==", - "jpNUgFnanr9Sxvj2xbBXZw==", - "nykEOLL/o7h0cs0yvdeT2g==", - "wX2URK6eDDHeEOF3cgPgHA==", - "jqPQ0aOuvOJte/ghI1RVng==", - "nHTsDl0xeQPC5zNRnoa0Rw==", - "mNv2Q67zePjk/jbQuvkAFA==", - "HjlPM2FQWdILUXHalIhQ5w==", - "cHkOsVd80Rgwepeweq4S1g==", - "kTCHqcb3Cos51o8cL+MXcg==", - "nvmBgp0YlUrdZ05INsEE8Q==", - "kFrRjz7Cf2KvLtz9X6oD+w==", - "Tmx0suRHzlUK4FdBivwOwA==", - "bG+P+p34t/IJ1ubRiWg6IA==", - "uESeJe/nYrHCq4RQbrNpGA==", - "ehfPlu6YctzzpQmFiQDxGA==", - "ZH5Es/4lJ+D5KEkF1BVSGg==", - "HHxn4iIQ7m0tF1rSd+BZBg==", - "DQJRsUwO1fOuGlkgJavcwQ==", - "HITIVoFoWNg04NExe13dNA==", - "MeKXnEfxeuQu9t3r/qWvcw==", - "Y7OofF9eUvp7qlpgdrzvkg==", - "XSb71ae0v+yDxNF5HJXGbQ==", - "p8W1LgFuW6JSOKjHkx3+aA==", - "y2JOIoIiT9cV1VxplZPraQ==", - "MN94B0r5CNAF9sl3Kccdbw==", - "Q1pdQadt12anX1QRmU2Y/A==", - "JIC8R48jGVqro6wmG2KXIw==", - "eWgLAqJOU+fdn8raHb9HCw==", - "5CMadLqS2KWwwMCpzlDmLw==", - "H1y2iXVaQYwP0SakN6sa+Q==", - "CUCjG2UaEBmiYWQc6+AS1Q==", - "yV3IbbTWAbHMhMGVvgb/ZQ==", - "80PCwYh4llIKAplcDvMj4g==", - "fgdUFvQPb5h+Rqz8pzLsmw==", - "2SI4F7Vvde2yjzMLAwxOog==", - "kJdY3XEdJS/hyHdR+IN0GA==", - "IKgNa2oPaFVGYnOsL+GC5Q==", - "eXFOya6x5inTdGwJx/xtUQ==", - "uTA0XbiH3fTeVV7u5z0b3w==", - "onFcHOO1c3pDdfCb5N4WkQ==", - "Slu3z535ijcs5kzDnR7kfA==", - "SElc2+YVi3afE1eG1MI7dQ==", - "ND2hYtAIQGMxBF7o7+u7nQ==", - "Pv9FWQEDLKnG/9K9EIz4Gw==", - "6CjtF1S2Y6RCbhl7hMsD+g==", - "rs2QrN4qzAHCHhkcrAvIfA==", - "eTMPXa60OTGjSPmvR4IgGw==", - "pvXHwJ3dwf9GDzfDD9JI3g==", - "CRmAj3JcasAb4iZ9ZbNIbw==", - "rcY4Ot40678ByCfqvGOGdg==", - "l4ddTxbTCW5UmZW+KRmx6A==", - "NKRzJndo2uXNiNppVnqy1g==", - "0NrvBuyjcJ2q6yaHpz/FOA==", - "3YXp1PmMldUjBz3hC6ItbA==", - "CmVD6nh8b/04/6JV9SovlA==", - "HjyxyL0db2hGDq2ZjwOOhg==", - "4PBaoeEwUj79njftnYYqLg==", - "vFFzkWgGyw6OPADONtEojQ==", - "czBWiYsQtNFrksWwoQxlOw==", - "9iB7+VwXRbi6HLkWyh9/kg==", - "zwY6tCjjya/bgrYaCncaag==", - "mW6TCje9Zg2Ep7nzmDjSYQ==", - "5LJqHFRyIwQKA4HbtqAYQQ==", - "INNBBin5ePwTyhPIyndHHg==", - "dChBe9QR29ObPFu/9PusLg==", - "1dhq3ozNCx0o4dV1syLVDA==", - "nyaekSYTKzfSeSfPrB114Q==", - "TfNHjSTV8w6Pg6+FaGlxvA==", - "m/Lp4U75AQyk9c8cX14HJg==", - "uU1TX5DoDg6EcFKgFcn0GA==", - "B+TsxQZf0IiQrU8X9S4dsQ==", - "6b7ue29cBDsvmj1VSa5njw==", - "RvXWAFwM+mUAPW1MjPBaHA==", - "pdaY6kZ8+QqkMOInvvACNA==", - "7nr3zyWL+HHtJhRrCPhYZA==", - "BXGlq54wIH6R3OdYfSSDRw==", - "b06KGv5zDYsTxyTbQ9/eyA==", - "8ylI1AS3QJpAi3I/NLMYdg==", - "0fpe9E6m3eLp/5j5rLrz2Q==", - "Qrh7OEHjp80IW+YzQwzlJg==", - "lqhgbgEqROAdfzEnJ17eXA==", - "Dulw855DfgIwiK7hr3X8vg==", - "wsp+vmW8sEqXYVURd/gjHA==", - "VoPth5hDHhkQcrQTxHXbuw==", - "TgWe70YalDPyyUz6n88ujg==", - "9lLhHcrPWI4EsA4fHIIXuw==", - "UymZUnEEQWVnLDdRemv+Tw==", - "qnkFUlJ8QT322JuCI3LQgg==", - "/p/aCTIhi1bU0/liuO/a2Q==", - "hWoxz5HhE50oYBNRoPp1JQ==", - "88tB/HgUIUnqWXEX++b5Aw==", - "Z8T1b9RsUWf59D06MUrXCQ==", - "BZTzHJGhzhs3mCXHDqMjnQ==", - "XfY+QUriCAA1+3QAsswdgg==", - "TZ3ATPOFjNqFGSKY3vP2Hw==", - "cl4t9FXabQg7tbh1g7a0OA==", - "9SgfpAY0UhNC6sYGus9GgQ==", - "d/Wd3Ma1xYyoMByPQnA9Cw==", - "DDitrRSvovaiXe2nfAtp4g==", - "s+eHg5K9zZ2Jozu5Oya9ZQ==", - "z3L2BNjQOMOfTVBUxcpnRA==", - "v4xIYrfPGILEbD/LwVDDzA==", - "HoaBBw2aPCyhh0f5GxF+/Q==", - "i9IRqAqKjBTppsxtPB7rdw==", - "cWUg7AfqhiiEmBIu+ryImA==", - "E+02smwQGBIxv42LIF2Y4Q==", - "W4CfeVp9mXgk04flryL7iA==", - "9SUOfKtfKmkGICJnvbIDMg==", - "xweGAZf+Yb3TtwR/sGmGIA==", - "EJgedRYsZPc4cT9rlwaZhg==", - "wv4NC9CIpwuGf/nOQYe/oA==", - "ZXeMG5eqQpZO/SGKC4WQkA==", - "bzXXzQGZs8ustv0K4leklA==", - "RkQK9S1ezo+dFYHQP57qrw==", - "mrinv7KooPQPrLCNTRWCFg==", - "qIUJPanWmGzTD1XxvHp+6w==", - "Js7g8Dr6XsnGURA4UNF0Ug==", - "dpSTNOCPFHN5yGoMpl1EUA==", - "ugY8rTtJkN4CXWMVcRZiZw==", - "rqHKB91H3qVuQAm+Ym5cUA==", - "UjmDFO7uzjl4RZDPeMeNyg==", - "cu4ZluwohhfIYLkWp72pqA==", - "ZydKlOpn2ySBW0G3uAqwuw==", - "LWd0+N3M94n81qd346LfJQ==", - "VbHoWmtiiPdABvkbt+3XKQ==", - "J4MC9He6oqjOWsYQh9nl3Q==", - "ahAbmGJZvUOXrcK6OydNGQ==", - "Byhi4ymFqqH8uIeoMRvPug==", - "LSN9GmT6LUHlCAMFqpuPIA==", - "IAMInfSYb76GxDlAr1dsTg==", - "qYHdgFAXhF/XcW4lxqfvWQ==", - "26+yXbqI+fmIZsYl4UhUzw==", - "AwPTZpC28NJQhf5fNiJuLA==", - "SESKbGF35rjO64gktmLTWA==", - "YVlRQHQglkbj3J2nHiP/Hw==", - "DdaT4JLC7U0EkF50LzIj9w==", - "G0LChrb0OE5YFqsfTpIL1Q==", - "5Yrj6uevT8wHRyqqgnSfeg==", - "NmWmDxwK5FpKlZbo0Rt8RA==", - "iUsUCB0mfRsE9KPEQctIzw==", - "Tm4zk2Lmg8w4ITMI31NfTA==", - "Vu0E+IJXBnc25x4n41kQig==", - "6wkfN8hyKmKU6tG3YetCmw==", - "trjM81KANPZrg9iSThWx6Q==", - "iGuY4VxcotHvMFXuXum7KA==", - "ICPdBCdONUqPwD5BXU5lrw==", - "alqHQBz8V446EdzuVfeY5Q==", - "74FW/QYTzr/P1k6QwVHMcw==", - "avZp5K7zJvRvJvpLSldNAw==", - "TIKadc6FAaRWSQUg5OATgg==", - "PfkWkSbAxIt1Iso0znW0+Q==", - "Z+bsbVP91KrJvxrujBLrrQ==", - "mrxlFD3FBqpSZr1kuuwxGg==", - "nUgYO7/oVNSX8fJqP2dbdg==", - "tVhXk9Ff3wAg56FbdNtcFg==", - "DdiNGiOSoIZxrMrGNvqkXw==", - "CDsanJz7e3r/eQe+ZYFeVQ==", - "wVfSZYjMjbTsD2gaSbwuqQ==", - "6c0iuya20Ys8BsvoI4iQaQ==", - "qCPfJTR8ecTw6u6b1yHibA==", - "fZrj3wGQSt8RXv0ykJROcQ==", - "gR3B8usSEb0NLos51BmJQg==", - "vTAmgfq3GxL4+ubXpzwk5w==", - "jLkmUZ6fV56GfhC0nkh4GA==", - "3v09RHCPTLUztqapThYaHg==", - "nULSbtw2dXbfVjZh33pDiA==", - "IHhyR6+5sZXTH+/NrghIPg==", - "tnUtJ/DQX9WaVJyTgemsUA==", - "7xTKFcog69nTmMfr5qFUTA==", - "IshzWega6zr3979khNVFQQ==", - "Ng5v/B9Z10TTfsDFQ/XrXQ==", - "hnCUnoxofUiqQvrxl73M8w==", - "VPa7DG6v7KnzMvtJPb88LQ==", - "4LtQrahKXVtsbXrEzYU1zQ==", - "Ev/xjTi7akYBI7IeZJ4Igw==", - "41WEjhYUlG6jp2UPGj11eQ==", - "JvXTdChcE3AqMbFYTT3/wg==", - "2rOkEVl90EPqfHOF5q2FYw==", - "mjFBVRJ7TgnJx+Q74xllPg==", - "Uy4QI8D2y1bq/HDNItCtAw==", - "wMOE/pEKVIklE75xjt6b6w==", - "ZcuIvc8fDI+2uF0I0uLiVA==", - "CX/N/lHckmAtHKysYtGdZA==", - "j8to4gtSIRYpCogv2TESuQ==", - "iS9wumBV5ktCTefFzKYfkA==", - "ewPT4dM12nDWEDoRfiZZnA==", - "vWn9OPnrJgfPavg4D6T/HQ==", - "J/PNYu4y6ZMWFFXsAhaoow==", - "catI+QUNk3uJ+mUBY3bY8Q==", - "F8tEIT5EhcvLNRU5f0zlXQ==", - "zyA9f5J7mw5InjhcfeumAQ==", - "MlOOZOwcRGIkifaktEq0aQ==", - "Pt3i49uweYVgWze3OjkjJA==", - "sfIClgTMtZo9CM9MHaoqhQ==", - "HeQbUuBM9sqfXFXRBDISSw==", - "SFn78uklZfMtKoz2N0xDaQ==", - "H6j2nPbBaxHecXruxiWYkA==", - "fU32wmMeD44UsFSqFY0wBA==", - "hDILjSpTLqJpiSSSGu445A==", - "ieEAgvK9LsWh2t6DsQOpWA==", - "xfjBQk3CrNjhufdPIhr91A==", - "j+8/VARfbQSYhHzj0KPurQ==", - "/zFLRvi75UL8qvg+a6zqGg==", - "U0KmEI6e5zJkaI4YJyA5Ew==", - "uXvr6vi5kazZ9BCg2PWPJA==", - "jEqP0dyHKHiUjZ9dNNGTlQ==", - "1xWx5V3G9murZP7srljFmA==", - "OIwtfdq37eQ0qoXuB2j7Hw==", - "fUAy3f9bAglLvZWvkO2Lug==", - "duRFqmvqF93uf/vWn8aOmg==", - "ysRQ+7Aq7eVLOp88KnFVMA==", - "CkZUmKBAGu0FLpgPDrybpw==", - "TrLmfgwaNATh24eSrOT+pw==", - "83wtvSoSP9FVBsdWaiWfpA==", - "pUfWmRXo70yGkUD/x5oIvA==", - "PybPZhJErbRTuAafrrkb3g==", - "8hsfXqi4uiuL+bV1VrHqCw==", - "TVlHoi8J7sOZ2Ti7Dm92cQ==", - "za4rzveYVMFe3Gw531DQJQ==", - "JKphO0UYjFqcbPr6EeBuqg==", - "hqeSvwu8eqA072iidlJBAw==", - "bUF0JIfS4uKd3JZj2xotLQ==", - "hKOsXOBoFTl/K4xE+RNHDA==", - "JHBjKpCgSgrNNACZW1W+1w==", - "Rrq0ak9YexLqqbSD4SSXlw==", - "+NmjwjsPhGJh9bM10SFkLw==", - "xMIHeno2qj3V8q9H1xezeg==", - "TcFinyBrUoAEcLzWdFymow==", - "Rvchz/xjcY9uKiDAkRBMmA==", - "TYlnrwgyeZoRgOpBYneRAg==", - "PbnxuVerGwHyshkumqAARg==", - "iFtadcw8v6betKka9yaJfg==", - "7wgT9WIiMVcrj48PVAMIgw==", - "2HHqeGRMfzf3RXwVybx+ZQ==", - "tdgI9v7cqJsgCAeW1Fii1A==", - "4ZFYKa7ZgvHyZLS6WpM8gA==", - "gB8wkuIzvuDAIhDtNT1gyA==", - "g1ELwsk6hQ+RAY1BH640Pg==", - "UZoibx+y1YJy/uRSa9Oa2w==", - "yS/yMnJDHW0iaOsbj4oPTg==", - "JzW+yhrjXW1ivKu3mUXPXg==", - "/wIZAye9h1TUiZmDW0ZmYA==", - "YK+q7uJObkQZvOwQ9hplMg==", - "Rs8deApkoosIJSfX7NXtAA==", - "MsCloSmTFoBpm7XWYb+ueQ==", - "3ltw31yJuAl4VT6MieEXXw==", - "1+qmrbC8c7MJ6pxmDMcKuA==", - "AYxGETZs477n2sa1Ulu/RQ==", - "Q0TJZxpn3jk67L7N+YDaNA==", - "OGpsXRHlaN8BvZftxh1e7A==", - "UbABE6ECnjB+9YvblE9CYw==", - "kZ0D191c/uv4YMG15yVLDw==", - "QWURrsEgxbJ8MWcaRmOWqw==", - "xiFlcSfa/gnPiO+LwbixcQ==", - "Szko0IPE7RX2+mfsWczrMg==", - "Ugt8HVC/aUzyWpiHd0gCOQ==", - "8j9GVPiFdfIRm/+ho7hpoA==", - "KR401XBdgCrtVDSaXqPEiA==", - "d0NBFiwGlQNclKObRtGVMQ==", - "XEwOJG24eaEtAuBWtMxhwg==", - "0Y6iiZjCwPDwD/CwJzfioQ==", - "MvMbvZNKbXFe2XdN+HtnpQ==", - "fsoXIbq0T0nmSpW8b+bj+g==", - "Uje3Ild84sN41JEg3PEHDg==", - "i6ZYpFwsyWyMJNgqUMSV1A==", - "+P5q4YD1Rr5SX26Xr+tzlw==", - "z4oKy2wKH+sbNSgGjbdHGw==", - "XwKWd03sAz8MmvJEuN08xA==", - "Xv0mNYedaBc57RrcbHr9OA==", - "9oUawSwUGOmb0sDn3XS6og==", - "9RGIQ2qyevNbSSEF36xk/A==", - "q8YF9G2jqydAxSqwyyys5Q==", - "m5JIUETVXcRza4VL4xlJbg==", - "aRpdnrOyu5mWB1P5YMbvOA==", - "rM/BOovNgnvebKMxZQdk7g==", - "fQS0jnQMnHBn7+JZWkiE/g==", - "gAoV4BZYdW1Wm712YXOhWQ==", - "hCzsi1yDv9ja5/o7t94j9Q==", - "CoLvjQDQGldGDqRxfQo+WQ==", - "pfGcaa49SM3S6yJIPk/EJQ==", - "yYp4iuI5f/y/l1AEJxYolQ==", - "Jj4IrSVpqQnhFrzNvylSzA==", - "4jeOFKuKpCmMXUVJSh9y0g==", - "+NMUaQ7XPsAi0rk7tTT9wQ==", - "Jt4Eg6MJn8O4Ph/K2LeSUA==", - "CiiUeJ0LeWfm7+gmEmYXtg==", - "c5Tc7rTFXNJqYyc0ppW+Iw==", - "4KJZPCE9NKTfzFxl76GWjg==", - "aXs9qTEXLTkN956ch3pnOA==", - "f5Xo7F1uaiM760Qbt978iw==", - "wpZqFkKafFpLcykN2IISqg==", - "vIORTYSHFIXk5E2NyIvWcQ==", - "prOsOG0adI4o+oz50moipw==", - "blygTgAHZJ3NzyAT33Bfww==", - "rBt6L/KLT7eybxKt5wtFdg==", - "vMuaLvAntJB5o7lmt/kVXA==", - "iujlt9fXcUXEYc+T2s5UjA==", - "LyYPOZKm8bBegMr5NTSBfg==", - "ZtWvgitOSRDWq7LAKYYd4Q==", - "kh51WUI5TRnKhur6ZEpRTQ==", - "VzQ1NwNv9btxUzxwVqvHQg==", - "8fJLQeIHaTnJ8wGqUiKU6g==", - "vvEH5A39TTe1AOC11rRCLA==", - "dihDsG7+6aocG6M9BWrCzQ==", - "3jqsY8/xTWELmu/az3Daug==", - "mpOtwBvle+nyY6lUBwTemw==", - "E1CvxFbuu9AYW604mnpGTw==", - "1LPC0BzhJbepHTSAiZ3QTw==", - "XpGXh76RDgXC4qnTCsnNHA==", - "3Gg9N7vjAfQEYOtQKuF/Eg==", - "+WpF8+poKmHPUBB4UYh/ig==", - "UNt7CNMtltJWq8giDciGyA==", - "RIZYDgXqsIdTf9o2Tp/S7g==", - "0QCQORCYfLuSbq94Sbt0bQ==", - "hvsZ5JmVevK1zclFYmxHaw==", - "3+9nURtBK3FKn0J9DQDa3g==", - "jdVMQqApseHH3fd91NFhxg==", - "VX+cVXV8p9i5EBTMoiQOQQ==", - "I5qDndyelK4Njv4YrX7S6w==", - "rWliqgfZ3/uCRBOZ9sMmdA==", - "vwno3vugCvt6ooT3CD4qIQ==", - "cffrYrBX3UQhfX1TbAF+GQ==", - "nOiwBFnXxCBfPCHYITgqNg==", - "LQttmX92SI94+hDNVd8Gtw==", - "iCF+GWw9/YGQXsOOPAnPHQ==", - "nwtCsN1xEYaHvEOPzBv+qQ==", - "CQpJFrpOvcQhsTXIlJli+Q==", - "tYeIZjIm0tVEsYxH1iIiUQ==", - "iCnm5fPmSmxsIzuRK6osrA==", - "tX8X8KoxUQ8atFSCxgwE1Q==", - "hZlX6qOfwxW5SPfqtRqaMw==", - "2aIx9UdMxxZWvrfeJ+DcTw==", - "TlJizlASbPtShZhkPww4UA==", - "p+bx+/WQWALXEBCTnIMr4w==", - "4VR5LiXLew6Nyn91zH9L4w==", - "bfUD03N2PRDT+MZ+WFVtow==", - "cTvDd8okNUx0RCMer6O8sw==", - "49jZr/mEW6fvnyzskyN40w==", - "vHmQUl4WHXs1E/Shh+TeyA==", - "fgXfRuqFfAu8qxbTi4bmhA==", - "Wn+Vj4eiWx0WPUHr3nFbyA==", - "2SwIiUwT4vRZPrg7+vZqDA==", - "nkedTagkmf6YE4tEY+0fKw==", - "8nOTDhFyZ8YUA4b6M5p84w==", - "qnzWszsyJhYtx8wkMN6b1g==", - "ka7pMp8eSiv92WgAsz2vdA==", - "pGQEWJ38hb/ZYy2P1+FIuw==", - "cVhdRFuZaW/09CYPmtNv5g==", - "prCOYlboBnzmLEBG/OeVrQ==", - "oIWwTbkVS5DDL47mY9/1KQ==", - "PKtXc4x4DEjM45dnmPWzyg==", - "f9ywiGXsz+PuEsLTV3zIbQ==", - "6G2bD3Y7qbGmfPqH9TqLFA==", - "DMHmyn2U2n+UXxkqdvKpnA==", - "XOG1PYgqoG8gVLIbVLTQgg==", - "1FSrgkUXgZot2CsmbAtkPw==", - "BxFP+4o6PSlGN78eSVT1pA==", - "EZVQGsXTZvht1qedRLF8bQ==", - "eYAQWuWZX2346VMCD6s7/A==", - "jkUpkLoIXuu7aSH8ZghIAQ==", - "mXPtbPaoNAAlGmUMmJEWBQ==", - "HLesnV3DL+FhWF3h6RXe8g==", - "nDAsSla+9XfAlQSPsXtzPA==", - "RAECgYZmcF4WxcFcZ4A0Ww==", - "W+M4BcYNmjj7xAximDGWsA==", - "ueODvMv/f9ZD8O0aIHn4sg==", - "cszpMdGbsbe6BygqMlnC9Q==", - "siHwJx6EgeB1gBT9z/vTyw==", - "FN7oLGBQGHXXn5dLnr/ElA==", - "Tud+AMyuFkWYYZ73yoJGpQ==", - "TuaG3wRdM9BWKAxh2UmAsg==", - "8CjmgWQSAAGcXX9kz3kssw==", - "ays5/F7JANIgPHN0vp2dqQ==", - "PCOGl7GIqbizAKj/sZmlwQ==", - "rZKD8oJnIj5fSNGiccfcvA==", - "gFEnTI8os2BfRGqx9p5x8w==", - "5r1ZsGkrzNQEpgt/gENibw==", - "1YO9G8qAhLIu2rShvekedw==", - "6ZKmm7IW7IdWuVytLr68CQ==", - "mMfn8OaKBxtetweulho+xQ==", - "GQJxu1SoMBH14KPV/G/KrQ==", - "IYIP2UBRyWetVfYLRsi1SQ==", - "Jit0X0srSNFnn8Ymi1EY+g==", - "ARCWkHAnVgBOIkCDQ19ZuA==", - "qA0sTaeNPNIiQbjIe1bOgQ==", - "iGI9uqMoBBAjPszpxjZBWQ==", - "+L1FDsr5VQtuYc2Is5QGjw==", - "4XNUmgwxsqDYsNmPkgNQYQ==", - "Yig+Wh18VIqdsmwtwfoUQw==", - "uqp92lAqjec8UQYfyjaEZw==", - "QiozlNcQCbqXtwItWExqJQ==", - "JFHutgSe1/SlcYKIbNNYwQ==", - "Y26jxXvl79RcffH8O8b9Ew==", - "bQ7J5mebp38rfP/fuqQOsg==", - "HI4ZIE5s8ez8Rb+Mv39FxA==", - "OzH7jTcyeM7RPVFtBdakpQ==", - "HLxROy6fx/mLXFTDSX4eLA==", - "s5RUHVRNAoKMuPR/Jkfc2Q==", - "X9QAaNjgiOeAWSphrGtyVw==", - "ALJWKUImVE40MbEooqsrng==", - "9MDG0WeBPpjGJLEmUJgBWg==", - "9RXymE9kCkDvBzWGyMgIWA==", - "vFox1d3llOeBeCUZGvTy0A==", - "r3lQAYOYhwlLnDWQIunKqg==", - "2os5s7j7Tl46ZmoZJH8FjA==", - "O5N2yd+QQggPBinQ+zIhtQ==", - "ZygAjaN62XhW5smlLkks+Q==", - "AgDJsaW0LkpGE65Kxk5+IA==", - "omAjyj1l6gyQAlBGfdxJTw==", - "fY9VATklOvceDfHZDDk57A==", - "StpQm/cQF8cT0LFzKUhC5w==", - "CYJB3qy5GalPLAv1KGFEZA==", - "coGEgMVs2b314qrXMjNumQ==", - "DQQB/l55iPN9XcySieNX3A==", - "6dshA8knH5qqD+KmR/kdSQ==", - "qyRmvxh8p4j4f+61c10ZFQ==", - "apWEPWUvMC24Y+2vTSLXoA==", - "RzX2OfSFEd//LhZwRwzBVw==", - "NdULoUDGhIolzw1PyYKV0A==", - "5w/c9WkI/FA+4lOtdPxoww==", - "bV9r7j2kNJpDCEM5E2339Q==", - "vbyiKeDCQ4q9dDRI1Q0Ong==", - "9xIgKpZGqq0/OU6wM5ZSHw==", - "RYkDwwng6eeffPHxt8iD9A==", - "w5N/aHbtOIKzcvG3GlMjGA==", - "3P2aJxV8Trll2GH9ptElYA==", - "yteeQr3ub2lDXgLziZV+DQ==", - "yqtj8GfLaUHYv/BsdjxIVw==", - "NyF+4VRog7etp90B9FuEjA==", - "uwA6N5LptSXqIBkTO0Jd7Q==", - "6lVSzYUQ/r0ep4W2eCzFpg==", - "1d7RPHdZ9qzAbG3Vi9BdFA==", - "7br49X11xc2GxQLSpZWjKQ==", - "peMW+rpwmXrSwplVuB/gTA==", - "RqYpA5AY7mKPaSxoQfI1CA==", - "dqVw2q2nhCvTcW82MT7z0g==", - "5S5/asYfWjOwnzYpbK6JDw==", - "NvkR0inSzAdetpI4SOXGhw==", - "tIqwBotg052wGBL65DZ+yA==", - "S4RvORcJ3m6WhnAgV4YfYA==", - "UAqf4owQ+EmrE45hBcUMEw==", - "4aPU6053cfMLHgLwAZJRNg==", - "3Y6/HqS1trYc9Dh778sefg==", - "ck86G8HsbXflyrK7MBntLg==", - "GLmWLXURlUOJ+PMjpWEXVA==", - "jNJQ6otieHBYIXA9LjXprg==", - "AsAHrIkMgc3RRWnklY9lJw==", - "FCLQocqxxhJeleARZ6kSPg==", - "3Leu2Sc+YOntJFlrvhaXeg==", - "hSkY45CeB6Ilvh0Io4W6cg==", - "DwrNdmU5VFFf3TwCCcptPA==", - "u2WQlcMxOACy6VbJXK4FwA==", - "E9IlDyULLdeaVUzN6eky8g==", - "EXveRXjzsjh8zbbQY2pM9g==", - "5VO1inwXMvLDBQSOahT6rg==", - "HaHTsLzx7V3G1SFknXpGxA==", - "MMaegl2Md9s/wOx5o9564w==", - "mpWNaUH9kn4WY26DWNAh3Q==", - "w3G+qXXqqKi8F5s+qvkBUg==", - "wM8tnXO4PDlLVHspZFcjYw==", - "LFcpCtnSnsCPD2gT/RA+Zg==", - "bhVbgJ4Do4v56D9mBuR/EA==", - "yU3N0HMSP5etuHPNrVkZtg==", - "FzqIpOcTsckSNHExrl+9jg==", - "BYz52gYI/Z6AbYbjWefcEA==", - "h3vYYI9yhpSZV2MQMJtwFQ==", - "adJAjAFyR2ne1puEgRiH+g==", - "eDcyiPaB954q5cPXcuxAQw==", - "40gCrW4YWi+2lkqMSPKBPg==", - "ulLuTZqhEDkX0EJ3xwRP9A==", - "y4iBxAMn/KzMmaWShdYiIw==", - "ilBBNK/IV69xKTShvI94fQ==", - "0HN6MIGtkdzNPsrGs611xA==", - "twPn6wTGqI0aR//0wP3xtA==", - "3UNJ37f+gnNyYk9yLFeoYA==", - "4SdHWowXgCpCDL28jEFpAw==", - "Mr5mCtC53+wwmwujOU/fWw==", - "81pAhreEPxcKse+++h1qBg==", - "KmcGEE0pacQ/HDUgjlt7Pg==", - "Gt4/MMrLBErhbFjGbiNqQQ==", - "lf1fwA0YoWUZaEybE+LyMQ==", - "RIVYGO2smx9rmRoDVYMPXw==", - "rJ9qVn8/2nOxexWzqIHlcQ==", - "lfOLLyZNbsWQgHRhicr4ag==", - "wgH1GlUxWi6/yLLFzE76uQ==", - "Qg1ubGl+orphvT990e5ZPA==", - "Z5B+uOmPZbpbFWHpI9WhPw==", - "snGTzo540cCqgBjxrfNpKw==", - "ZqkmoGB0p5uT5J6XBGh7Tw==", - "uPi8TsGY3vQsMVo/nsbgVQ==", - "Y5XR8Igvau/h+c1pRgKayg==", - "ZmVpw1TUVuT13Zw/MNI5hQ==", - "60suecbWRfexSh7C67RENA==", - "kZ/mZZg9YSDmk2rCGChYAg==", - "OpL+vHwPasW30s2E1TYgpA==", - "ZVnErH1Si4u51QoT0OT7pA==", - "3pi3aNVq1QNJmu1j0iyL0g==", - "tb5+2dmYALJibez1W4zXgA==", - "jOPdd330tB6+7C29a9wn0Q==", - "5oD/aGqoakxaezq43x0Tvw==", - "HdB7Se47cWjPgpJN0pZuiA==", - "6WhHPWlqEUqXC52rHGRHjA==", - "WLwpjgr9KzevuogoHZaVUw==", - "E8yMPK7W0SIGTK6gIqhxiQ==", - "1/Hxu8M9N/oNwk8bCj4FNQ==", - "Uo1ebgsOxc3eDRds1ah3ag==", - "5pqqzC/YmRIMA9tMFPi7rg==", - "ri4AOITPdB1YHyXV+5S51g==", - "HfvsiCQN/3mT0FabCU5ygQ==", - "UQTQk5rrs6lEb1a+nkLwfg==", - "VH70dN82yPCRctmAHMfCig==", - "yD3Dd4ToRrl53k/2NSCJiw==", - "fO0+6TsjL+45p9mSsMRiIg==", - "fM5uYpkvJFArnYiQ3MrQnA==", - "V+QzdKh5gxTPp2yPC9ZNEg==", - "XHHEg/8KZioW/4/wgSEkbQ==", - "2abfl3N46tznOpr+94VONQ==", - "gxwbqZDHLbQVqXjaq42BCg==", - "WnHK5ZQDR6Da5cGODXeo0A==", - "SChDh/Np1HyTPWfICfE1uA==", - "yhexr/OFKfZl0o3lS70e4w==", - "N65PqIWiQeS082D6qpfrAg==", - "RM5CpIiB94Sqxi462G7caA==", - "CBAGa5l95f3hVzNi6MPWeQ==", - "OHJBT2SEv5b5NxBpiAf7oQ==", - "p48i7AfSSAyTdJSyHvOONw==", - "/SP6pOdYFzcAl2OL05z4uQ==", - "N8dXCawxSBX40fgRRSDqlQ==", - "bMWFvjM8eVezU1ZXKmdgqw==", - "Um1ftRBycvb+363a90Osog==", - "QAz7FA+jpz9GgLvwdoNTEQ==", - "qO4HlyHMK5ygX+6HbwQe8w==", - "UgvtdE2eBZBUCAJG/6c0og==", - "q5g3c8tnQTW2EjNfb2sukw==", - "gsC/mWD8KFblxB0JxNuqJw==", - "SVFbcjXbV7HRg+7jUrzpwg==", - "bz294kSG4egZnH2dJ8HwEg==", - "ybpTgPr3SjJ12Rj5lC/IMA==", - "yDrAd1ot38soBk7zKdnT8A==", - "BB/R8oQOcoE4j63Hrh8ifg==", - "GNrMvNXQkW7PydlyJa+f1w==", - "w0PKdssv+Zc5J/BbphoxpA==", - "D5ibbo8UJMfFZ48RffuhgQ==", - "MdvhC1cuXqni/0mtQlSOCw==", - "wQKL8Ga6JQkpZ7yymDkC3w==", - "o1uhaQg5/zfne84BFAINUQ==", - "Ft2wXUokFdUf6d2Y/lwriw==", - "sLJrshdEANp0qk2xOUtTnQ==", - "jx7rpxbm1NaUMcE2ktg5sA==", - "ZQ0ZnTsZKWxbRj7Tilh24Q==", - "KhrIIHfqXl9zGE9aGrkRVg==", - "jS0JuioLGAVaHdo/96JFoQ==", - "tr+U/vt+MIGXPRQYYWJfRg==", - "TXab/hqNGWaSK+fXAoB2bg==", - "0K4NBxqEa3RYpnrkrD/XjQ==", - "3oMTbWf7Bv83KRlfjNWQZA==", - "yLAhLNezvqVHmN1SfMRrPw==", - "ZYW30FfgwHmW6nAbUGmwzA==", - "CZNoTy26VUQirvYxSPc/5A==", - "CF1sAlhjDQY/KWOBnSSveA==", - "+CLf5witKkuOvPCulTlkqw==", - "1m1yD4L9A7Q1Ot+wCsrxJQ==", - "2E41e0MgM3WhFx2oasIQeA==", - "mDXHuOmI4ayjy2kLSHku1Q==", - "sCLMrLjEUQ6P1L8tz90Kxg==", - "zDUZCzQesFjO1JI3PwDjfg==", - "x/BIDm6TKMhqu/gtb3kGyw==", - "DEaZD/8aWV6+zkiLSVN/gA==", - "7dz+W494zwU5sg63v5flCg==", - "Y5iDQySR2c3MK7RPMCgSrw==", - "GglPoW5fvr4JSM3Zv99oiA==", - "myzvc+2MfxGD9uuvZYdnqQ==", - "V9G1we3DOIQGKXjjPqIppQ==", - "gYvdNJCDDQmNhtJ6NKSuTA==", - "rXtGpN17Onx8LnccJnXwJQ==", - "/a+bLXOq02sa/s8h7PhUTg==", - "htNVAogFakQkTX6GHoCVXg==", - "eshD40tvOA6bXb0Fs/cH3A==", - "K1CGbMfhlhIuS0YHLG30PQ==", - "aOeJZUIZM9YWjIEokFPnzQ==", - "r0hAwlS0mPZVfCSB+2G6uQ==", - "0q+erphtrB+6HBnnYg7O6w==", - "bkRdUHAksJZGzE1gugizYQ==", - "J8v2f6hWFu8oLuwhOeoQjA==", - "qkvEep4vvXhc2ZJ6R449Mg==", - "6HGeEPyTAu9oiKhNVLjQnA==", - "JoATsk/aJH0UcDchFMksWA==", - "QozQL0DTtr+PXNKifv6l6g==", - "HiAgt86AyznvbI2pnLalVQ==", - "lY+tivtsfvU0LJzBQ6itYQ==", - "EfXDc6h69aBPE6qsB+6+Ig==", - "gnAIpoCyl3mQytLFgBEgGA==", - "p2JPOX8yDQ0agG+tUyyT/g==", - "zeELfk015D5krExLKRUYtg==", - "wDiGoFEfIVEDyyc4VpwhWQ==", - "7Ephy+mklG2Y3MFdqmXqlA==", - "8ZFPMJJYVJHsfRpU4DigSg==", - "ocRh5LR1ZIN9Johnht8fhQ==", - "l5f3I6osM9oxLRAwnUnc5A==", - "yxCyBXqGWA735JEyljDP7Q==", - "qE/h/Z+6buZWf+cmPdhxog==", - "HCu4ZMrcLMZbPXbTlWuvvQ==", - "TDrq23VUdzEU/8L5i8jRJQ==", - "L+N/6geuokiLPPSDXM9Qkg==", - "v6jZicMNM3ysm3U5xu0HoQ==", - "b85nxzs8xiHxaqezuDVWvg==", - "ca+kx+kf7JuZ3pfYKDwFlg==", - "KlY5TGg0pR/57TVX+ik1KQ==", - "3jmCreW5ytSuGfmeLv7NfQ==", - "ucLMWnNDSqE4NOCGWvcGWw==", - "NSrzwNlB0bde3ph8k6ZQcQ==", - "nL4iEd3b5v4Y9fHWDs+Lrw==", - "W2x0SBzSIsTRgyWUCOZ/lg==", - "ifZM0gBm9g9L09YlL+vXBg==", - "4WcFEswYU/HHQPw77DYnyA==", - "TLJbasOoVO435E5NE5JDcA==", - "WyCFB4+6lVtlzu3ExHAGbQ==", - "BW0A06zoQw7S+YMGaegT7g==", - "qP1cCE4zsKGTPhjbcpczMw==", - "UVEZPoH9cysC+17MKHFraw==", - "eQ45Mvf5in9xKrP6/qjYbg==", - "fOARCnIg/foF/6tm7m9+3w==", - "lK2xe+OuPutp4os0ZAZx5w==", - "Tug3eh+28ttyf+U7jfpg5w==", - "ENFfP93LA257G6pXQkmIdg==", - "FuWspiqu5g8Eeli5Az+BkA==", - "kIGxCUxSlNgsKZ45Al1lWw==", - "RzeH+G3gvuK1z+nJGYqARQ==", - "0ofMbUCA3/v5L8lHnX4S5w==", - "VI8pgqBZeGWNaxkuqQVe7g==", - "x6lNRGgJcRxgKTlzhc1WPg==", - "La0gzdbDyXUq6YAXeKPuJA==", - "dAq8/1JSQf1f4QPLUitp0g==", - "WN7lFJfw4lSnTCcbmt5nsg==", - "2aDK0tGNgMLyxT+BQPDE8Q==", - "9W57pTzc572EvSURqwrRhw==", - "37Nkh06O979nt7xzspOFyQ==", - "4TQkMnRsXBobbtnBmfPKnA==", - "f/BjtP5fmFw2dRHgocbFlg==", - "9vEgJVJLEfed6wJ7hBUGgQ==", - "HRWYX2XOdsOqYzCcqkwIyw==", - "StDtLMlCI75g4XC59mESEQ==", - "99+SBN45LwKCPfrjUKRPmw==", - "HbT6W1Ssd3W7ApKzrmsbcg==", - "l8/KMItWaW3n4g1Yot/rcQ==", - "s7iW1M6gkAMp+D/3jHY58w==", - "GWwJ32SZqD5wldrXUdNTLA==", - "YhLEPsi/TNyeUJw69SPYzQ==", - "g0aTR8aJ0uVy3YvGYu5xrw==", - "m6get5wjq5j1i5abnpXuZQ==", - "ymtA8EMPMgmMcimWZZ0A1Q==", - "HEcOaEd9zCoOVbEmroSvJg==", - "F8l+Qd9TZgzV+r8G584lKA==", - "3yDD+xT8iRfUVdxcc7RxKw==", - "1eRUCdIJe3YGD5jOMbkkOg==", - "DO1/jfP/xBI9N0RJNqB2Rw==", - "SiSlasZ+6U2IZYogqr2UPg==", - "tBQDfy48FnIOZI04rxfdcA==", - "HEghmKg3GN60K7otpeNhaA==", - "mTLBkP+yGHsdk5g7zLjVUw==", - "RgtwfY5pTolKrUGT+6Pp6g==", - "EyIsYQxgFa4huyo/Lomv7g==", - "HwLSUie8bzH+pOJT3XQFyg==", - "7Tauesu7bgs5lJmQROVFiQ==", - "ojugpLIfzflgU2lonfdGxA==", - "ZqjnqxZE/BjOUY0CMdVl0g==", - "oQjugfjraFziga1BcwRLRA==", - "JXCYeWjFqcdSf6QwB54G+A==", - "TeBGJCqSqbzvljIh9viAqA==", - "1Gpj4TPXhdPEI4zfQFsOCg==", - "asouSfUjJa8yfMG7BBe+fA==", - "ccy3Ke2k4+evIw0agHlh3w==", - "CzSumIcYrZlxOUwUnLR2Zw==", - "9QFYrCXsGsInUb4SClS3cQ==", - "3RTtSaMp1TZegJo5gFtwwA==", - "aTWiWjyeSDVY/q8y9xc2zg==", - "UK+R+hAoVeZ4xvsoZjdWpw==", - "rHagXw+CkF3uEWPWDKXvog==", - "MfkyURTBfkNZwB+wZKjP4g==", - "Qf7JFJJuuacSzl6djUT2EQ==", - "K1RL+tLjICBvMupe7QppIQ==", - "R2OOV18CV/YpWL1xzr/VQg==", - "o+areESiXgSO0Lby56cBeg==", - "VPqyIomYm7HbK5biVDvlpw==", - "pw1jplCdTC+b0ThX0FXOjw==", - "gTnsH3IzALFscTZ1JkA9pw==", - "JYJvOZ4CHktLrYJyAbdOnA==", - "P8lUiLFoL100c9YSQWYqDA==", - "LATQEY7f47i77M6p11wjWA==", - "U9kE50Wq5/EHO03c5hE4Ug==", - "pFKzcRHSUBqSMtkEJvrR1Q==", - "vHVXsAMQqc0qp7HA5Q+YkA==", - "3XyoREdvhmSbyvAbgw2y/A==", - "qOEIUWtGm5vx/+fg4tuazg==", - "a6IszND1m+6w+W+CvseC7g==", - "KuNY8qAJBce+yUIluW8AYw==", - "5Wcq+6hgnWsQZ/bojERpUw==", - "l2ZB9TvT68rn8AAN4MdxWw==", - "h5HsEsObPuPFqREfynVblw==", - "fvm0IQfnbfZFETg9v3z/Fg==", - "QV0OG5bpjrjku4AzDvp9yw==", - "nMuMtK/Zkb3Xr34oFuX/Lg==", - "jMZKSMP2THqwpWqJNJRWdw==", - "fX4G68hFL7DmEmjbWlCBJQ==", - "ZlBNHAiYsfaEEiPQ1z+rCA==", - "ckugAisBNX18eQz+EnEjjw==", - "Dt6hvhPJu94CJpiyJ5uUkg==", - "eYE9No9sN5kUZ5ePEyS3+Q==", - "Tp52d1NndiC9w3crFqFm9g==", - "MBjMU/17AXBK0tqyARZP5w==", - "1EI9aa955ejNo1dJepcZJw==", - "FqWLkhWl0iiD/u2cp+XK9A==", - "j8nMH8mK/0Aae7ZkqyPgdg==", - "ZtmnX24AwYAXHb2ZDC6MeQ==", - "who8uUamlHWHXnBf7dwy4A==", - "CmkmWcMK4eqPBcRbdnQvhw==", - "61V74uIjaSfZM8au1dxr1A==", - "778O1hdVKHLG2q9dycUS0Q==", - "IdadoCPmSgHDHzn1zyf8Jw==", - "Z2rwGmVEMCY6nCfHO3qOzw==", - "Q3TpCE+wnmH/1h/EPWsBtQ==", - "HnVfyqgJ+1xSsN4deTXcIA==", - "XgPHx2+ULpm14IOZU2lrDg==", - "IbN736G1Px5bsYqE5gW1JQ==", - "nY/H7vThZ+dDxoPRyql+Cg==", - "wlWxtQDJ+siGhN2fJn3qtw==", - "MrbEUlTagbesBNg0OemHpw==", - "LJtRcR70ug6UHiuqbT6NGw==", - "hSNZWNKUtDtMo6otkXA/DA==", - "LawT9ZygiVtBk0XJ+KkQgQ==", - "DLzHkTjjuH6LpWHo2ITD0Q==", - "i8XXN7jcrmhnrOVDV8a2Hw==", - "ogcuGHUZJkmv+vCz567a2g==", - "rUp5Mfc57+A8Q29SPcvH/Q==", - "6706ncrH1OANFnaK6DUMqQ==", - "gK7dhke5ChQzlYc/bcIkcg==", - "t3Txxjq43e/CtQmfQTKwWg==", - "6ZMs9vCzK9lsbS6eyzZlIA==", - "uTHBqApdKOAgdwX3cjrCYQ==", - "zirOtGUXeRL22ezfotZfQg==", - "iK0dWKHjVVexuXvMWJV9pg==", - "uzEgwx1iAXAvWPKSVwYSeQ==", - "FHvI0IVNvih8tC7JgzvCOw==", - "jjNMPXbmpFNsCpWY0cv3eg==", - "/cJ0Nn5YbXeUpOHMfWXNHQ==", - "WkSJpxBa45XJRWWZFee7hw==", - "edlXkskLx287vOBZ9+gVYg==", - "+Pl0bSMBAdXpRIA+zE02JA==", - "3xw8+0/WU51Yz4TWIMK8mw==", - "GdTanUprpE3X/YjJDPpkhQ==", - "qnsBdl050y9cUaWxbCczRw==", - "pnJnBzAJlO4j3IRqcfmhkQ==", - "USq1iF90eUv41QBebs3bhw==", - "QH3lAwOYBAJ0Fd5pULAZqw==", - "gvvyX5ATi4q9NhnwxRxC8w==", - "7xDIG/80SnhgxAYPL9YJtg==", - "WVhfn2yJZ43qCTu0TVWJwA==", - "twjiDKJM7528oIu/el4Zbg==", - "6sBemZt4qY/TBwqk3YcLOQ==", - "m3XYojKO+I6PXlVRUQBC3w==", - "gUNP5w7ANJm257qjFxSJrA==", - "mMLhjdWNnZ8zts9q+a2v3g==", - "kjWYVC7Eok2w2YT4rrI+IA==", - "ZzT5b0dYQXkQHTXySpWEaA==", - "YzTV0esAxBFVls3e0qRsnA==", - "9xmtuClkFlpz/X5E9JBWBA==", - "nhAnHuCGXcYlqzOxrrEe1g==", - "cbBXgB1WQ/i8Xul0bYY2fg==", - "AkAes5oErTaJiGD2I4A1Pw==", - "Wx9jh/teM0LJHrvTScssyQ==", - "fU5ZZ1bIVsV+eXxOpGWo/Q==", - "k8eZxqwxiN/ievXdLSEL/w==", - "E2LR1aZ3DcdCBuVT7BhReA==", - "1eCHcz4swFH+uRhiilOinQ==", - "JipruVZx4ban3Zo5nNM37g==", - "IPLD9nT5EEYG9ioaSIYuuA==", - "pHozgRyMiEmyzThtJnY4MQ==", - "p0eNK7zJd7D/HEGaVOrtrQ==", - "dGjcKAOGBd4gIjJq7fL+qQ==", - "uMq8cDVWFD+tpn8aeP8Pqg==", - "gC7gUwGumN7GNlWwfIOjJQ==", - "It+K/RCYMOfNrDZxo7lbcA==", - "4CfEP8TeMKX33ktwgifGgA==", - "nxDGRpePV3H4NChn4eLwag==", - "300hoYyMR/mk1mfWJxS8/w==", - "DmxgZsQg+Qy1GP0fPkW3VA==", - "1vqRt79ukuvdJNyIlIag8Q==", - "RWI0HfpP7643OSEZR8kxzw==", - "zZtYkKU50PPEj6qSbO5/Sw==", - "UNRlg6+CYVOt68NwgufGNA==", - "kkbX+a00dfiTgbMI+aJpMg==", - "VIC7inSiqzM6v9VqtXDyCw==", - "l+x2QhxG8wb5AQbcRxXlmA==", - "GUiinC3vgBjbQC2ybMrMNQ==", - "6uMF5i0b/xsk55DlPumT7A==", - "aK9nybtiIBUvxgs1iQFgsw==", - "BLbTFLSb4mkxMaq4/B2khg==", - "mTAqtg6oi0iytHQCaSVUsA==", - "eBapvE+hdyFTsZ0y5yrahg==", - "lHN2dn2cUKJ8ocVL3vEhUQ==", - "Mj87ajJ/yR41XwAbFzJbcA==", - "FA+nK6mpFWdD0kLFcEdhxA==", - "FrTgaF5YZCNkyfR1kVzTLQ==", - "5eHStFN7wEmIE+uuRwIlPQ==", - "AyWlT+EGzIXc395zTlEU5Q==", - "I+wVQA+jpPTJ6xEsAlYucg==", - "Y1flEyZZAYxauMo4cmtJ1w==", - "1AeReq55UQotRQVKJ66pmg==", - "xzGzN5Hhbh0m/KezjNvXbQ==", - "meHzY9dIF7llDpFQo1gyMg==", - "RnOXOygwJFqrD+DlM3R5Ew==", - "JKg64m6mU7C/CkTwVn4ASg==", - "gGLz3Ss+amU7y6JF09jq7A==", - "Pu9pEf+Tek3J+3jmQNqrKw==", - "EATnlYm0p3h04cLAL95JgA==", - "o64LDtKq/Fulf1PkVfFcyg==", - "hUWqqG1QwYgGC5uXJpCvJw==", - "RfSwpO/ywQx4lfgeYlBr2w==", - "VaJc9vtYlqJbRPGb5Tf0ow==", - "9JKIJrlQjhNSC46H3Cstcw==", - "6Z9myGCF5ylWljgIYAmhqw==", - "9bAWYElyRN1oJ6eJwPtCtQ==", - "ohK6EftXOqBzIMI+5XnESw==", - "AVjwqrTBQH1VREuBlOyUOg==", - "G2UponGde3/Z+9b2m9abpQ==", - "DoiItHSms0B9gYmunVbRkQ==", - "vUC0HlTTHj6qNHwfviDtAw==", - "hq35Fjgvrcx6I9e6egWS4w==", - "sw+bmpzqsM4gEQtnqocQLQ==", - "ApiuEPWr8UjuRyJjsYZQBw==", - "VXu4ARjq7DS2IR/gT24Pfw==", - "3TbRZtFtsh9ez8hqZuTDeA==", - "CazLJMJjQMeHhYLwXW7YNg==", - "ROSt+NlEoiPFtpRqKtDUrQ==", - "IUwVHH6+8/0c+nOrjclOWA==", - "lkzFdvtBx5bV6xZO0cxK7g==", - "4ekt4m38G9m599xJCmhlug==", - "fzkmVWKhJsxyCwiqB/ULnQ==", - "LZAKplVoNjeQgfaHqkyEJA==", - "91vfsZ7Lx9x5gqWTOdM4sg==", - "MVoxyIA+emaulH8Oks8Weg==", - "oGH7SMLI2/qjd9Vnhi3s0A==", - "vmqfGJE6r4yDahtU/HLrxw==", - "Y5KKN7t/v9JSxG/m1GMPSA==", - "gXlb7bbRqHXusTE5deolGA==", - "/2c4oNniwhL3z5IOngfggg==", - "HgIFX42oUdRPu7sKAXhNWg==", - "A3dX2ShyL9+WOi6MNJBoYQ==", - "hN9bmMHfmnVBVr+7Ibd2Ng==", - "DB706G73NpBSRS8TKQOVZw==", - "JSyq2MIuObPnEgEUDyALjQ==", - "kSUectNPXpXNg+tIveTFRw==", - "XVVy3e6dTnO3HpgD6BtwQw==", - "td7nDgTDmKPSODRusMcupw==", - "Lt/pVD4TFRoiikmgAxEWEw==", - "mmRob7iyTkTLDu8ObmTPow==", - "Fd0c8f2eykUp9GYhqOcKoA==", - "18RKixTv12q3xoBLz6eKiA==", - "RClzwwKh51rbB4ekl99EZA==", - "oONlXCW4aAqGczQ/bUllBw==", - "foPAmiABJ3IXBoed2EgQXA==", - "wEJDulZafLuXCvcqBYioFQ==", - "K1RgR6HR5uDEQgZ32TAFgA==", - "SEIZhyguLoyH7So0p1KY0A==", - "ggIfX1J4dX3xQoHnHUI7VA==", - "HBRzLacCVYfwUVGzrefZYg==", - "aWZRql2IUPVe9hS3dxgVfQ==", - "Err1mbWJud80JNsDEmXcYg==", - "Z2MkqmpQXdlctCTCUDPyzw==", - "JnE6BK0vpWIhNkaeaYNUzw==", - "5dUry23poD+0wxZ3hH6WmA==", - "DwP0MQf71VsqvAbAMtC3QQ==", - "kHcBZXoxnFJ+GMwBZ/xhfQ==", - "SUAwMWLMml8uGqagz5oqhQ==", - "79uTykH43voFC3XhHHUzKg==", - "P5fucOJhtcRIoElFJS4ffg==", - "s8NpalwgPdHPla7Zi9FJ3w==", - "8cXqZub6rjgJXmh1CYJBOg==", - "tY916jrSySzrL+YTcVmYKQ==", - "DRiFNojs7wM8sfkWcmLnhQ==", - "wqUJ1Gq1Yz2cXFkbcCmzHQ==", - "0u+0WHr7WI6IlVBBgiRi6w==", - "GCYI9Dn1h3gOuueKc7pdKA==", - "nVDxVhaa2o38gd1XJgE3aw==", - "5I/heFSQG/UpWGx0uhAqGQ==", - "1PvTn90xwZJPoVfyT5/uIQ==", - "jHOoSl3ldFYr9YErEBnD3w==", - "swJhrPwllq5JORWiP5EkDA==", - "tj2rWvF2Fl+XIccctj8Mhw==", - "QvYZxsLdu+3nV/WhY1DsYg==", - "fKalNdhsyxTt1w08bv9fJA==", - "CHLHizLruvCrVi9chj9sXA==", - "sa2DECaqYH1z1/AFhpHi+g==", - "LbPp1oL0t3K2BAlIN+l8DA==", - "5SbwLDNT6sBOy6nONtUcTg==", - "AfVPdxD3FyfwwNrQnVNQ7A==", - "jt9Ocr9D8EwGRgrXVz//aQ==", - "KkwQL0DeUM3nPFfHb2ej+A==", - "WwraoO97OTalvavjUsqhxQ==", - "fAKFfwlCOyhtdBK6yNnsNg==", - "EqMlrz1to7HG4GIFTPaehQ==", - "YmjZJyNfHN5FaTL/HAm8ww==", - "L2D7G0btrwxl9V4dP3XM5Q==", - "oUqO4HrBvkpSL781qAC9+w==", - "c6Yhwy/q3j7skXq52l36Ww==", - "FWphIPZMumqnXr1glnbK4w==", - "AcKwfS8FRVqb72uSkDNY/Q==", - "uSIiF1r9F18avZczmlEuMQ==", - "XrFDomoH2qFjQ2jJ2yp9lA==", - "N2X7KWekNN+fMmwyXgKD5w==", - "IdmcpJXyVDajzeiGZixhSA==", - "Wf2olJCYZRGTTZxZoBePuQ==", - "oVlG+0rjrg2tdFImxIeVBA==", - "7w4PDRJxptG8HMe/ijL6cQ==", - "rueNryrchijjmWaA3kljYg==", - "ZybIEGf1Rn/26vlHmuMxhw==", - "yYVW07lOZHdgtX42xJONIA==", - "4ifNsmjYf1iOn2YpMfzihg==", - "KTjwL+qswa+Bid8xLdjMTg==", - "THfzE2G2NVKKfO+A2TjeFw==", - "QoqHzpHDHTwQD5UF30NruQ==", - "dTMoNd6DDr1Tu8tuZWLudw==", - "wOc4TbwQGUwOC1B3BEZ4OQ==", - "gfhkPuMvjoC3CGcnOvki3Q==", - "vljJciS+uuIvL7XXm5688g==", - "EGLOaMe6Nvzs/cmb7pNpbg==", - "oLWWIn/2AbKRHnddr2og9g==", - "7l0RMKbONGS/goW/M+gnMQ==", - "eFkXKRd2dwu/KWI5ZFpEzw==", - "jWsC7kdp2YmIZpfXGUimiA==", - "Jcxjli2tcIAjCe+5LyvqdQ==", - "MUkRa/PjeWMhbCTq43g6Aw==", - "g2nh2xENCFOpHZfdEXnoQA==", - "x6M66krXSi0EhppwmDmsxA==", - "26Wmdp6SkKN74W0/XPcnmA==", - "ycjv4XkS5O7zcF3sqq9MwQ==", - "gfnbviaVhKvv1UvlRGznww==", - "aIPde9CtyZrhbHLK740bfw==", - "0p8YbEMxeb73HbAfvPLQRw==", - "Is3uxoSNqoIo5I15z6Z2UQ==", - "NZtcY8fIpSKPso/KA6ZfzA==", - "iQ304I1hmLZktA1d1cuOJA==", - "0QB0OUW5x2JLHfrtmpZQ+w==", - "kgyUtd8MFe0tuuxDEUZA9w==", - "AcbG0e6xN8pZfYAv7QJe1Q==", - "bb/U8UynPHwczew/hxLQxw==", - "NuBYjwlxadAH+vLWYRZ3bg==", - "Ao1Zc0h5AdSHtYt1caWZnQ==", - "FL/j3GJBuXdAo54JYiWklQ==", - "E2v8Kk60qVpQ232YzjS2ow==", - "zVupSPz7cD0v/mD/eUIIjg==", - "sEeblUmISi1HK4omrWuPTA==", - "xQpYjaAmrQudWgsdu24J0A==", - "vCekQ2nOQKiN/q8Be/qwZg==", - "8g08gjG/QtvAYer32xgNAg==", - "miiOqnhtef1ODjFzMHnxjA==", - "sXlFMSTBFnq0STHj6cS/8w==", - "+SclwwY8R2RPrnX54Z+A6w==", - "g8TcogVxHpw7uhgNFt5VCQ==", - "9viAzLFGYYudBYFu7kFamg==", - "BAJ+/jbk2HyobezZyB9LiQ==", - "/DJgKE9ouibewuZ2QEnk6w==", - "fxg/vQq9WPpmQsqQ4RFYaA==", - "lM/EhwTsbivA7MDecaVTPw==", - "pVgjGg4TeTNhKimyOu3AAw==", - "gYnznEt9r97haD/j2Cko7g==", - "/ngbFuKIAVpdSwsA3VxvNw==", - "VCL3xfPVCL5RjihQM59fgg==", - "eDWsx4isnr2xPveBOGc7Hw==", - "FIOCTEbzb2+KMCnEdJ7jZw==", - "40HzgVKYnqIb6NJhpSIF0A==", - "ccK42Lm8Tsv73YMVZRwL6A==", - "MpAwWMt7bcs4eL7hCSLudQ==", - "zxsSqovedB3HT99jVblCnQ==", - "4erEA42TqGA9K4iFKkxMMA==", - "BaRwTrc5ulyKbW4+QqD0dw==", - "CT3ldhWpS1SEEmPtjejR/Q==", - "lkl6XkrTMUpXi46dPxTPxg==", - "3EhLkC9NqD3A6ApV6idmgg==", - "fsW2DaKYTCC7gswCT+ByQQ==", - "pW4gDKtVLj48gNz6V17QdA==", - "KjfL7YyVqmCJGBGDFdJ0gw==", - "bGGUhiG9SqJMHQWitXTcYQ==", - "8RtLlzkGEiisy1v9Xo0sbw==", - "R81DX/5a7DYKkS4CU+TL+w==", - "Tu6w6DtX2RJJ3Ym3o3QAWw==", - "nx/U4Tode5ILux4DSR+QMg==", - "mjQS8CpyGnsZIDOIEdYUxg==", - "wJpepvmtQQ3sz3tVFDnFqw==", - "a4rPqbDWiMivVzaRxvAj7g==", - "6o5g9JfKLKQ2vBPqKs6kjg==", - "UzPPFSXgeV7KW4CN5GIQXA==", - "NdVyHoTbBhX6Umz/9vbi0g==", - "Fzuq+Wg7clo6DTujNrxsSA==", - "XXFr0WUuGsH5nXPas7hR3Q==", - "JVSLiwurnCelNBiG2nflpQ==", - "NiawWuMBDo0Q3P2xK/vnLQ==", - "nNaGqigseHw30DaAhjBU3g==", - "+edqJYGvcy1AH2mEjJtSIg==", - "1WIi4I62GqkjDXOYqHWJfQ==", - "rwplpbNJz0ADUHTmzAj15Q==", - "iWNlSnwrtCmVF89B+DZqOQ==", - "tHDbi43e6k6uBgO0hA+Uiw==", - "fHNpW230mNib08aB7IM3XQ==", - "OChiB4BzcRE8Qxilu6TgJg==", - "d+ctfXU0j07rpRRzb5/HDA==", - "GDMqfhPQN0PxfJPnK1Bb9A==", - "bLd38ZNkVeuhf0joEAxnBQ==", - "nvUKoKfC6j8fz3gEDQrc/w==", - "fhcbn9xE/6zobqQ2niSBgA==", - "HGxe+5/kkh6R9GXzEOOFHA==", - "mPwCyD0yrIDonVi+fhXyEQ==", - "5PfGtbH9fmVuNnq83xIIgQ==", - "XePy/hhnQwHXFeXUQQ55Vg==", - "yfAaL0MMtSXPQ37pBdmHxQ==", - "NiQ/m4DZXUbpca9aZdzWAw==", - "uT6WRh5UpVdeABssoP2VTg==", - "oxoZP897lgMg/KLcZAtkAg==", - "oKt57TPe4PogmsGssc3Cbg==", - "RxmdoO8ak8y/HzMSIm+yBQ==", - "6leyDVmC5jglAa98NQ3+Hg==", - "+QosBAnSM2h4lsKuBlqEZw==", - "hy303iin+Wm7JA6MeelwiQ==", - "m9iuy4UtsjmyPzy6FTTZvw==", - "f6Ye5F0Lkn34uLVDCzogFQ==", - "iGykaF+h4p46HhrWqL8Ffg==", - "LPYFDbTEp5nGtG6uO8epSw==", - "t2vWMIh2BvfDSQaz5T1TZw==", - "OONAvFS/kmH7+vPhAGTNSg==", - "g/z9yk94XaeBRFj4hqPzdw==", - "2wesXiib76wM9sqRZ7JYwQ==", - "n7h9v2N1gOcvMuBEf8uThw==", - "ITYL3tDwddEdWSD6J6ULaA==", - "inrUwXyKikpOW0y2Kl1wGw==", - "iwKBOGDTFzV4aXgDGfyUkw==", - "+fcjH2kZKNj8quOytUk4nQ==", - "Srl4HivgHMxMOUHyM3jvNw==", - "qngzBJbiTB4fivrdnE5gOg==", - "G0MlFNCbRjXk4ekcPO/chQ==", - "t+bYn9UqrzKiuxAYGF7RLA==", - "RVD3Ij6sRwwxTUDAxwELtA==", - "RNdyt6ZRGvwYG5Ws3QTuEA==", - "9DRHdyX8ECKHUoEsGuqR4Q==", - "oMJLQTH1wW7LvOV0KRx/dw==", - "bjLZ7ot/X/vWSVx4EYwMCg==", - "+p8pofUlwn8vV6Rp6+sz9g==", - "cchuqe+CWCJpoakjHLvUfA==", - "NvurnIHin4O+wNP7MnrZ1w==", - "RBMv0IxXEO3o7MnV47Bzow==", - "xTizUioizbMQxD0T6fy/EQ==", - "ZCdad3AwhVArttapWFwT/Q==", - "Hy1nqC40l5ItxumkIC2LAA==", - "W/5ThNLu43uT1O+fg0Fzwg==", - "b3BQG9/9qDNC/bNSTBY/sQ==", - "neQoa8pvETr07blVMN3pgA==", - "oR8rvIZoeoaZ/ufpo0htfQ==", - "zEzWZ6l7EKoVUxvk/l78Mw==", - "IHyIeMad23fSDisblwyfpA==", - "m6srF+pMehggHB1tdoxlPg==", - "kggaIvN2tlbZdZRI8S5Apw==", - "2RFaMPlSbVuoEqKXgkIa5A==", - "//eHwmDOQRSrv+k9C/k3ZQ==", - "X/Gha4Ajjm/GStp/tv+Jvw==", - "+H0Rglt/HnhZwdty2hsDHg==", - "a1aL8zQ+ie3YPogE3hyFFg==", - "HxEU37uBMeiR5y8q/pM42g==", - "68nqDtXOuxF7DSw6muEZvg==", - "s5+78jS4hQYrFtxqTW3g1Q==", - "drfODfDI6GyMW7hzkmzQvA==", - "pT1raq2fChffFSIBX3fRiA==", - "sfowXUMdN2mCoBVrUzulZg==", - "AV/YJfdoDUdRcrXVwinhQg==", - "3AKEYQqpkfW7CZMFQZoxOw==", - "PHwJ5ZAqqftZ4ypr8H1qiQ==", - "AoN/pnK4KEUaGw4V9SFjpg==", - "soBA65OmZdfBGJkBmY/4Iw==", - "mSstwJq7IkJ0JBJ5T8xDKg==", - "h13Xuonj+0dD1xH86IhSyQ==", - "HK9xG03FjgCy8vSR+hx8+Q==", - "oFanDWdePmmZN0xqwpUukA==", - "zCRZgVsHbQZcVMHd9pGD3A==", - "EvSB+rCggob2RBeXyDQRvQ==", - "tXuu7YpZOuMLTv87NjKerA==", - "DJ+a37tCaGF5OgUhG+T0NA==", - "KkXlgPJPen6HLxbNn5llBw==", - "2W6lz1Z7PhkvObEAg2XKJw==", - "n+xYzfKmMoB3lWkdZ+D3rg==", - "CPDs+We/1wvsGdaiqxzeCQ==", - "2Wvk/kouEEOY0evUkQLhOQ==", - "ezsm4aFd6+DO9FUxz0A8Pg==", - "9sYLg75/hudZaBA3FrzKHw==", - "Pp1ZMxJ8yajdbfKM4HAQxA==", - "xiyRfVG0EfBA+rCk+tgWRQ==", - "/IarsLzJB8bf0AupJJ+/Eg==", - "LJeLdqmriyAQp+QjZGFkdQ==", - "IhHyHbHGyQS+VawxteLP0w==", - "nGzPc0kI/EduVjiK7bzM6Q==", - "m06wctjNc3o7iyBHDMZs2w==", - "mSJF9dJnxZ15lTC6ilbJ2A==", - "xdmY+qyoxxuRZa9kuNpDEg==", - "oNOI17POQCAkDwj6lJsYOA==", - "p73gSu4d+4T/ZNNkIv9Nlw==", - "vOJ55zFdgPPauPyFYBf01w==", - "4A+RHIw+aDzw0rSRYfbc7g==", - "/gi3UZmunVOIXhZSktZ8zQ==", - "a6vem8n6WmRZAalDrHNP0g==", - "kGeXrHEN6o7h5qJYcThCPw==", - "wrewZ0hoHODf7qmoGcOd7g==", - "Z0sjccxzKylgEiPCFBqPSA==", - "LKyOFgUKKGUU/PxpFYMILw==", - "L2RofFWDO0fVgSz4D2mtdw==", - "KI7tQFYW38zYHOzkKp9/lQ==", - "ewe/P3pJLYu/kMb5tpvVog==", - "IADk81pIu8NIL/+9Fi94pA==", - "0L0FVcH5Dlj3oL8+e9Na7g==", - "tdiTXKrkqxstDasT0D5BPA==", - "R906Kxp2VFVR3VD+o6Vxcw==", - "wc+8ohFWgOF4VlSYiZIGwQ==", - "wJKFMqh6MGctWfasjHrPEg==", - "UHpge5Bldt9oPGo2oxnYvQ==", - "vX7RIhatQeXAMr1+OjzhZw==", - "s2AKVTwrY65/SWqQxDGJQg==", - "Q4bfQslDSqU64MOQbBQEUw==", - "mVT74Eht+gAowINoMKV7IQ==", - "EuGWtIbyKToOe6DN3NkVpQ==", - "ALlGgVDO8So71ccX0D6u2g==", - "Rww3qkF3kWSd+AaMT0kfdw==", - "hlvtFGW8r0PkbUAYXEM+Hw==", - "Oc3BqTF3ZBW3xE0QsnFn/A==", - "3j0kFUZ6g+yeeEljx+WXGg==", - "8BLkvEkfnOizJq0OTCYGzw==", - "Lqel4GdU0ZkfoJVXI5WC/Q==", - "rvE64KQGkVkbl07y7JwBqw==", - "HbXv8InyZqFT7i3VrllBgg==", - "zwQ/3MzTJ9rfBmrANIh14w==", - "gglLMohmJDPRGMY1XKndjQ==", - "lyfqic/AbEJbCiw+wA01FA==", - "XqUO7ULEYhDOuT/I2J8BOA==", - "wPhJcp7U7IVX83szbIOOxQ==", - "1gA65t5FiBTEgMELTQFUPQ==", - "ll2M0QQzBsj5OFi02fv3Yg==", - "wt+qDLU38kzNU75ZYi3Hbw==", - "a4EYNljinYTx9vb1VvUA6A==", - "T6LA+daQqRI38iDKZTdg1A==", - "gwyVIrTk5o0YMKQq4lpJ+Q==", - "bPRX2zl+K1S0iWAWUn1DZw==", - "KQw25X4LnQ9is+qdqfxo0w==", - "6tfM6dx3R5TiVKaqYQjnCg==", - "OlwHO6Sg2zIwsCOCRu0HiQ==", - "mr1qjhliRfl87wPOrJbFQg==", - "8c+lvG5sZNimvx9NKNH3ug==", - "5Nk2Z94DhlIdfG5HNgvBbQ==", - "F50iXjRo1aSTr37GQQXuJA==", - "tfgO55QqUyayjDfQh+Zo1Q==", - "h7Fc+eT/GuC8iWI+YTD0UQ==", - "3TjntNWtpG7VqBt3729L6Q==", - "+DWs0vvFGt6d3mzdcsdsyA==", - "VJt2kPVBLEBpGpgvuv1oUw==", - "XLq/nWX8lQqjxsK9jlCqUg==", - "9s3ar9q32Y5A3tla5GW/2Q==", - "51yLpfEdvqXmtB6+q27/AQ==", - "AiMtfedwGcddA+XYNc+21g==", - "p/48hurJ1kh2FFPpyChzJg==", - "CRiL6zpjfznhGXhCIbz8pQ==", - "/jDVt9dRIn+o4IQ1DPwbsg==", - "UNdKik7Vy23LjjPzEdzNsg==", - "Koiog/hpN7ew5kgJbty34A==", - "4itEKfbRCJvqlgKnyEdIOQ==", - "zi04Yc01ZheuFAQc59E45A==", - "etRjRvfL/IwceY/IJ1tgzQ==", - "3sNJJIx1NnjYcgJhjOLJOg==", - "4yVqq66iHYQjiTSxGgX2oA==", - "Q8RVI/kRbKuXa8HAQD7zUA==", - "OERGn45uzfDfglzFFn6JAg==", - "JGEy6VP3sz3LHiyT2UwNHQ==", - "1zDfWw5LdG20ClNP1HYxgw==", - "TGB+FIzzKnouLh5bAiVOQg==", - "n5GA+pA9mO/f4RN9NL9lNg==", - "bUxQBaqKyvlSHcuRL9whjg==", - "tOdlnsE3L3XCBDJRmb/OqA==", - "XdkxmYYooeDKzy7PXVigBQ==", - "PMvG4NqJP76kMRAup6TSZA==", - "qpFJZqzkklby+u1UT3c1iA==", - "fW3QZyq5UixIA1mP6eWgqQ==", - "9nMltdrrBmM5ESBY2FRjGA==", - "1Vtrv6QUAfiYQjlLTpNovg==", - "ur9JDCVNwzSH4q4ngDlHNQ==", - "4u3eyKc+y3uRnkASrgBVUw==", - "XddlSluOH6VkR7spFIFmdQ==", - "NOmu8oZc6CcKLu+Wfz2YOQ==", - "3Ejtsqw3Iep/UQd0tXnSlg==", - "y/e3HSdg7T19FanRpJ7+7Q==", - "YodhkayN5wsgPZEYN7/KNA==", - "pZfn6IiG+V28fN8E2hawDQ==", - "jGHMJqbj6X1NdTDyWmXYAQ==", - "olTSlmirL9MFhKORiOKYkQ==", - "CrJDgdfzOea2M2hVedTrIg==", - "fpXijBOM3Ai1RkmHven5Ww==", - "eLYKLr4labZeLiRrDJ9mnA==", - "9vmJUS7WIVOlhMqwipAknQ==", - "G7J/za99BFbAZH+Q+/B8WA==", - "Hb+pdSavvJ9lUXkSVZW8Og==", - "gTB2zM3RPm27mUQRXc/YRg==", - "e5KCqQ/1GAyVMRNgQpYf6g==", - "1ApqwW7pE+XUB2Cs2M6y7g==", - "/wiA2ltAuWyBhIvQAYBTQw==", - "HFCQEiZf7/SNc+oNSkkwlA==", - "JFi6N1PlrpKaYECOnI7GFg==", - "E4ojRDwGsIiyuxBuXHsKBA==", - "+25t/2lo0FUEtWYK8LdQZQ==", - "up2MVDi9ve+s83/nwNtZ7Q==", - "cXpfd6Io6Glj2/QzrDMCvA==", - "DCvI9byhw0wOFwF1uP6xIQ==", - "PibGJQNw7VHPTgqeCzGUGA==", - "0ZRGz+oj2infCAkuKKuHiQ==", - "2QS/6OBA1T01NlIbfkTYJg==", - "P14k+fyz0TG9yIPdojp52w==", - "g5EzTJ0KA4sO3+Opss3LMg==", - "R5oOM58zdbVxFSDQnNWqeA==", - "Vg2E5qEDfC+QxZTZDCu9yQ==", - "YPgMthbpcBN2CMkugV60hQ==", - "gZWTFt5CuLqMz6OhWL+hqQ==", - "YrEP9z2WPQ8l7TY1qWncDA==", - "7p4NpnoNSQR7ISg+w+4yFg==", - "9L6yLO93sRN70+3qq3ObfA==", - "QH36wzyIhh6I56Vnx79hRA==", - "9DtM1vls4rFTdrSnQ7uWXw==", - "ZlOAnCLV1PkR0kb3E+Nfuw==", - "9UhKmKtr4vMzXTEn74BEhg==", - "Ndx5LDiVyyTz/Fh3oBTgvA==", - "mXZ4JeBwT2WJQL4a/Tm4jQ==", - "N9nD7BGEM7LDwWIMDB+rEQ==", - "dmAfbd9F0OJHRAhNMEkRsA==", - "jV/D2B11NLXZRH77sG9lBw==", - "1C50kisi9nvyVJNfq2hOEQ==", - "NMbAjbnuK7EkVeY3CQI5VA==", - "J1nYqJ7tIQK1+a/3sMXI/Q==", - "m416yrrAlv+YPClGvGh+qQ==", - "rLZII1R6EGus+tYCiUtm6g==", - "xktOghh1S9nIX6fXWnT+Ug==", - "FcFcn4qmPse5mJCX5yNlsA==", - "xAAipGfHTGTjp9Qk1MR8RQ==", - "RQOlmzHwQKFpafKPJj0D8w==", - "WRjYdKdtnd1G9e/vFXCt0g==", - "z0BU//aSjYHAkGGk3ZSGNg==", - "M55eersiJuN9v61r8DoAjQ==", - "l2mAbuFF3QBIUILDODiUHQ==", - "IhpXs1TK7itQ3uTzZPRP5Q==", - "t2EkpUsLOEOsrnep0nZSmA==", - "lMaO8Yf+6YNowGyhDkPhQA==", - "UbSFw5jtyLk5MealqJw++A==", - "5u2PdDcIY3RQgtchSGDCGg==", - "MQYM3BT77i35LG9HcqxY2Q==", - "8AfCSZC0uasVON9Y/0P2Pw==", - "evaWFoxZNQcRszIRnxqB+A==", - "+8PiQt6O7pJI/nIvQpDaAg==", - "eRwaYiog2DdlGQyaltCMJg==", - "JyUJEnU6hJu8x2NCnGrYFw==", - "l0E0U/CJsyCVSTsXW4Fp+w==", - "XV13yK0QypJXmgI+dj4KYw==", - "jrRH0aTUYCOpPLZwzwPRfQ==", - "N3YDSkBUqSmrmNvZZx4a1Q==", - "0yJ7TQYzcp3DXVSvwavr+w==", - "rhgtLQh0F9bRA6IllM7AGw==", - "IWZnTJ3Hb9qw9HAK/M9gTw==", - "izeyFvXOumNgVyLrbKW45g==", - "xYD8jrCDmuQna+p1ebnKDQ==", - "SOdpdrk2ayeyv0xWdNuy9g==", - "HYylUirJRqLm+dkp39fSOQ==", - "q4z6A4l3nhX3smTmXr+Sig==", - "Zyo0fzewcqXiKe2mAwKx5g==", - "LMEtzh0+J27+4zORfcjITw==", - "LoUv/f2lcWpjftzpdivMww==", - "mXBfDUt/sBW5OUZs2sihvw==", - "PggVPQL5YKqSU/1asihcrg==", - "mI0eT4Rlr7QerMIngcu/ng==", - "NmQrsmb8PVP05qnSulPe5Q==", - "TcyyXrSsQsnz0gJ36w4Dxw==", - "y4mfEDerrhaqApDdhP5vjA==", - "ynaj4XjU27b7XbqPyxI8Ig==", - "Ua6aO6HwM+rY4sPR19CNFA==", - "3go7bJ9WqH/PPUTjNP3q/Q==", - "n1ixvP7SfwYT3L2iWpJg6A==", - "W8y32OLHihfeV0XFw7LmOg==", - "uzkNhmo2d08tv5AmnyqkoQ==", - "hJ8leLNuJ6DK5V8scnDaZQ==", - "KodYHHN62zESrXUye7M01g==", - "H+yPRiooEh5J7lAJB4RZ7Q==", - "dZg5w8rFETMp9SgW7m0gfg==", - "LsmsPokAwWNCuC74MaqFCQ==", - "1QGhj9NONF2rC44UdO+Izw==", - "uwGivY3/C9WK+dirRPJZ4A==", - "rXGWY/Gq+ZEsmvBHUfFMmQ==", - "j4FBMnNfdBwx0VsDeTvhFg==", - "81nkjWtpBhqhvOp6K8dcWg==", - "dCDaYYrgASXPMGFRV0RCGg==", - "Kj1QI+s9261S3lTtPKd9eg==", - "LblwOqNiciHmt2NXjd89tg==", - "46piyANQVvvLqcoMq5G8tQ==", - "XJihma9zSRrXLC+T+VcFDA==", - "K3NBEG8jJTJbSrYSOC3FKw==", - "cT3PwwS6ALZA/na9NjtdzA==", - "wJ4uCrl4DPg70ltw1dZO3w==", - "JATLdpQm//SQnkyCfI5x7Q==", - "X1PaCfEDScclLtOTiF5JUw==", - "444F9T6Y7J67Y9sULG81qg==", - "8JVHFRwAd/SCLU0CRJYofg==", - "aLh1XEUrfR9W82gzusKcOg==", - "U+bB5NjFIuQr/Y5UpXHwxA==", - "Egs14xVbRWjfBBX7X5Z60g==", - "KSorNz/PLR/YYkxaj1fuqw==", - "RDgGGxTtcPvRg/5KRRlz4w==", - "5T39s5CtSrK5awMPUcEWJg==", - "+PUVXkoTqHxJHO18z4KMfw==", - "Bvk8NX4l6WktLcRDRKsK/A==", - "kNGIV3+jQmJlZDTXy1pnyA==", - "E3jMjAgXwvwR8PA53g4+PQ==", - "MbI04HlTGCoc/6WDejwtaQ==", - "aEnHUfn7UE/Euh6jsMuZ7g==", - "z4Bft++f72QeDh4PWGr/sw==", - "1lCcQWGDePPYco4vYrA5vw==", - "iu5csar0IQQBOTgw5OvJwQ==", - "raKMXnnX6PFFsbloDqyVzQ==", - "uPnL9tboMZo0Kl2fe24CmA==", - "8OFxXwnPmrogpNoueZlC4Q==", - "V6CRKrKezPwsRdbm0DJ2Yg==", - "xmGgK3W5y+oCd0K2u8XjZQ==", - "Ry3zgZ6KHrpNyb7+Tt2Pkw==", - "IwLbkL33z+LdTjaFYh93kg==", - "caepyBOAFu0MxbcXrGf6TA==", - "iIWxFdolLcnXqIjPMg+5kQ==", - "P430CeF2MDkuq11YdjvV8A==", - "yCu+DVU/ceMTOZ5h/7wQTg==", - "4mQVNv7FHj+/O6XFqWFt/Q==", - "OEJ40VmMDYzc2ESEMontRA==", - "D66Suu3tWBD+eurBpPXfjA==", - "RNK9G1hfuz3ETY/RmA9+aA==", - "BYpHADmEnzBsegdYTv8B5Q==", - "DBKrdpCE0awppxST4o/zzg==", - "KOmdvm+wJuZ/nT/o1+xOuw==", - "gDxqUdxxeXDYhJk9zcrNyA==", - "UPzS4LR3p/h0u69+7YemrQ==", - "hf9HFxWRNX2ucH8FLS7ytA==", - "ozVqYsmUueKifb4lDyVyrg==", - "TfHvdbl2M4deg65QKBTPng==", - "SzCGM8ypE58FLaR1+1ccxQ==", - "3nthUmLZ30HxQrzr2d7xFA==", - "1jBaRO8Bg5l6TH7qJ8EPiw==", - "eJlcN+gJnqAnctbWSIO9uA==", - "G8LFBop8u6IIng+gQuVg3w==", - "3JhnM6G4L06NHt31lR0zXA==", - "342VOUOxoLHUqtHANt83Hw==", - "hRxbdeniAVFgKUgB9Q3Y+g==", - "cFFE2R4GztNoftYkqalqUQ==", - "YmaksRzoU+OwlpiEaBDYaQ==", - "jon1y9yMEGfiIBjsDeeJdA==", - "oSnrpW4UmmVXtUGWqLq+tQ==", - "zaqyy3GaJ7cp8qDoLJWcTw==", - "luO1R8dUM9gy1E2lojRQoA==", - "YHM6NNHjmodv+G0mRLK7kw==", - "ZSmN8mmI9lDEHkJqBBg0Nw==", - "520wTzrysiRi2Td92Zq0HQ==", - "RAAw14BA1ws5Wu/rU7oegw==", - "vb6Agwzk4JG0Nn7qRPPFMQ==", - "joDXdLpXvRjOqkRiYaD/Sw==", - "dK2DU3t1ns+DWDwfBvH3SQ==", - "gZNJ1Qq6OcnwXqc+jXzMLQ==", - "R8ULpSNu9FcCwXZM0QedSg==", - "mc45FSMtzdw2PTcEBwHWPw==", - "d0qvm3bl38rRCpYdWqolCQ==", - "o9tdzmIu+3J/EYU4YWyTkA==", - "5eXpiczlRdmqMYSaodOUiQ==", - "KYuUNrkTvjUWQovw9dNakA==", - "02im2RooJQ/9UfUrh5LO+A==", - "kWPUUi7x9kKKa6nJ+FDR5Q==", - "6z8CRivao3IMyV4p4gMh7g==", - "SmRWEzqddY9ucGAP5jXjAg==", - "DJscTYNFPyPmTb57g/1w+Q==", - "uOHrw37yF9oLLVd16nUpeg==", - "HaIRV9SNPRTPDOSX9sK/bg==", - "K4yZNVoqHjXNhrZzz2gTew==", - "bTNRjJm+FfSQVfd56nNNqQ==", - "x5lyMArsv1MuJmEFlWCnNw==", - "cxpZ4bloGv734LBf4NpVhA==", - "kUudvRfA33uJDzHIShQd3Q==", - "3Wfj05vCLFAB9vII5AU9tw==", - "FUQySDFodnRhr+NUsWt0KA==", - "eC/RcoCVQBlXdE9WtcgXIw==", - "NoX8lkY+kd2GPuGjp+s0tQ==", - "EzjbinBHx3Wr08eXpH3HXA==", - "0VsaJHR0Ms8zegsCpAKoyg==", - "e2xLFVavnZIUUtxJx+qa1g==", - "Kt6BTG1zdeBZ3nlVk+BZKQ==", - "EUXQZwLgnDG+C8qxVoBNdw==", - "0SkC/4PtnX1bMYgD6r6CLA==", - "rzj6mjHCcMEouL66083BAg==", - "V5HEaY3v9agOhsbYOAZgJA==", - "tJt6VDdAPEemBUvnoc4viA==", - "g0lWrzEYMntVIahC7i0O2g==", - "zCpibjrZOA3FQ4lYt0WoVA==", - "4Xh/B3C16rrjbES+FM1W8g==", - "GHEdXgGWOeOa6RuPMF0xXg==", - "3kREs/qaMX0AwFXN0LO5ow==", - "GLDNTSwygNBmuFwCIm7HtA==", - "JBkbaBiorCtFq9M9lSUdMg==", - "rJCuanCy51ydVD4nInf9IQ==", - "OzFRv+PzPqTNmOnvZGoo5g==", - "7mxU5fJl/c6dXss9H3vGcQ==", - "9J53kk+InE3CKa7cPyCXMw==", - "x9TIZ9Ua++3BX+MpjgTuWA==", - "h0MH5NGFfChgmRJ3E/R3HQ==", - "25w3ZRUzCvJwAVHYCIO5uw==", - "1Wc8jQlDSB4Dp32wkL2odw==", - "ipPPjxpXHS1tcykXmrHPMQ==", - "r95wJtP5rsTExKMS7QhHcw==", - "TZT86wXfzFffjt0f95UF5w==", - "VpmBstwR7qPVqPgKYQTA3g==", - "3++dZXzZ6AFEz7hK+i5hww==", - "mAiD16zf+rCc7Qzxjd5buA==", - "1JI9bT92UzxI8txjhst9LQ==", - "TNyvLixb03aP2f8cDozzfA==", - "spHVvA/pc7nF9Q4ON020+w==", - "GA8k6GQ20DGduVoC+gieRA==", - "T7waQc3PvTFr0yWGKmFQdQ==", - "P0Pc8owrqt6spdf7FgBFSw==", - "DKApp/alXiaPSRNm3MfSuA==", - "UreSZCIdDgloih8KLeX7gg==", - "xJi0T+psHOXMivSOVpMWeQ==", - "cNsC9bH30eM1EZS6IdEdtQ==", - "XjjrIpsmATV/lyln4tPb+g==", - "qt5CsMts2aD4lw/4Q6bHYQ==", - "h+KRDKIvyVUBmRjv1LcCyg==", - "2j83jrPwPfYlpJJ2clEBYQ==", - "ZrCezGLz38xKmzAom6yCTQ==", - "SEGu+cSbeeeZg4xWwsSErQ==", - "Duz/8Ebbd0w6oHwOs0Wnwg==", - "Ci7sS7Yi1+IwAM3VMAB4ew==", - "DG2Qe2DqPs5MkZPOqX363Q==", - "v0Bvws1WYVoEgDt8xmVKew==", - "CtDj/h2Q/lRey20G8dzSgA==", - "WRoJMO0BCJyn5V6qnpUi4Q==", - "RQywrOLZEKw9+kG6qTzr3g==", - "mU4CqbAwpwqegxJaOz9ofQ==", - "aN5x46Gw1VihRalwCt1CGg==", - "U6VQghxOXsydh3Naa5Nz4A==", - "YA+zdEC+yEgFWRIgS1Eiqw==", - "oPcxgoismve6+jXyIKK6AQ==", - "PqLCd/pwc+q5GkL6MB0jTg==", - "fHL+fHtDxhALZFb9W/uHuw==", - "dhTevyxTYAuKbdLWhG47Kw==", - "VllbOAjeW3Dpbj5lp2OSmA==", - "3itfXtlLPRmPCSYaSvc39Q==", - "GNak/LFeoHWlTdLW1iU4eg==", - "HuDuxs2KiGqmeyY1s1PjpQ==", - "xs8J3cesq7lDhP/dNltqOw==", - "foXSDEUwMhfHWJSmSejsQg==", - "6fWom3YoKvW6NIg6y9o9CQ==", - "NhZbSq0CjDNOAIvBHBM9zA==", - "5w4FbRhWACP7k2WnNitiHg==", - "0UeRwDID2RBIikInqFI7uw==", - "/y/jHHEpUu5TR+R2o96kXA==", - "voO3krg4sdy4Iu+MZEr8+g==", - "hdzol5dk//Q6tCm4+OndIA==", - "Nc5kiwXCAyjpzt43G5RF1A==", - "3UBYBMejKInSbCHRoJJ7dg==", - "dRFCIbVu0Y8XbjG5i+UFCQ==", - "t8pjhdyNJirkvYgWIO/eKg==", - "FAXzjjIr8l1nsQFPpgxM/g==", - "SPGpjEJrpflv1hF0qsFlPw==", - "9Y1ZmfiHJd9vCiZ6KfO1xQ==", - "7Eqzyb+Kep+dIahYJWNNxQ==", - "9rL8nC/VbSqrvnUtH9WsxQ==", - "H4FZ5Wcnb40hQM1DMGGe8A==", - "AjoXWGb/l9xH/hscgEc6kQ==", - "6nzFl41uutgDdC30oOeCqg==", - "3jo1jRy3MybXtoLR+JIbJw==", - "mXdE08dv+OlIhlcqMBH2Gg==", - "Ifd7DI6o8N5gnyAKqZTlRw==", - "JNUvg/kxL3rdcZnD4IqUxw==", - "ry8B+sAHNeFIZHCCDynFyw==", - "TXaEd5lIKhzjcncfNcBgSg==", - "Mr3ehuDMUimOSn+FlkchdA==", - "cwiGhjmX9v8I7E/ekQ0h+g==", - "I/r5+1jnqumCPprKC/2BqA==", - "S4V3MfGYk8I4fd3WH09yYw==", - "A+crVyUeynAkEMYKbnFjZw==", - "vtyHcNQPcUTRuZcQvRUX4Q==", - "UNKx1ZVv3HNp21zrUSm6ew==", - "rsAlvGLv2D0swd6ol3WlvA==", - "2qwqb8ENAR2fpQnw55sPDw==", - "xBJJuYYnsTJOeFggZSKC4Q==", - "omvtZZKruPiEt6fV0YXTdg==", - "JZEgKUhUN+USJsvtF4HZOg==", - "euG/kpJ5elSDOGNbWWDfNQ==", - "DiiVmM6/WNcp0MUjSaFq6w==", - "QCNS8gAml1M2pJ+MxZsueg==", - "M6+pggFsHfM3alFxcMOFNQ==", - "YLoWpDTwXnszEQm8FA164Q==", - "N08oUZtlXbQvO9t3vXnGog==", - "jkjuJowWuOa4CLY+RZiErQ==", - "mPf+S+6oAoVIYEVveaiNFA==", - "R0iVyo5qreP/68uZlZphDA==", - "GYlqhQgp03B0mXpUhQ+ZCA==", - "lQNbmWD7PhwNGye+zbc3GQ==", - "cNeaOJEOzUSDdRmenPQyuw==", - "Gp66/Txv6ebv5bn85TuQtA==", - "xAda6DVkcvvqhI8vWZeGyA==", - "Ggk1Qa0lEdAgCXG6SmCkBA==", - "MYuO7ZURXtyaf56q7hH4Zw==", - "RUIdZRTgJBudWUZQFgiFaQ==", - "bgFJxLirUom2zT0h7LdOpw==", - "A2gaOpIlrS7TKVQgy9XMSw==", - "zevXp0lqqnXv9X6Bgmjtqg==", - "a5iuFqWAdFFsRgp7SFYwNg==", - "TxTy0TaDsWTcRH3wdBEQLQ==", - "jephVdKDeJIhXPrdMOJ4qA==", - "C4KdamfqUPuJ3RGFdpIEdw==", - "zl6l2Ioz1qovRUIWrSyxVA==", - "+gGaDxUe0UnNrf3PPg1qQQ==", - "1HgbrlaLMHS6Qj/0kkaJxg==", - "eGxTly6Pnu7eV/MKYMmuYw==", - "RAMKfnlrzNjpyh2BWt6JHg==", - "4pZQm9ogCZ/EAR9pjJm1eA==", - "l1zv3erwXIegQFd02NlCag==", - "uHGyRZchuA4ulmuD5LqquQ==", - "/vFu89tsV+lbcoiqM/XWog==", - "63SUgqfQimrmjvy/bEDQ0w==", - "JLHuf+FlChFDa9LYfTQ4Eg==", - "I+ZnPePTFX8ZODe14bxgyA==", - "CtoK1k3U82BkvzuPfQ4pjQ==", - "6nqQm4C7y+wZ+qX0kVjwmA==", - "+C3kBxRXIjqBk0EJxe3Xfg==", - "qVu748pIxEZtiywg4/4qhw==", - "07o+sKjjRCYkwy/ACyoYhg==", - "CiLF4dkbLURekBcQbwPUVA==", - "W/N5/nkp4iQIPYfAagVV7A==", - "3PJOphhEjw0E4arTfVVwdg==", - "YdMbARHwB+bSOd0PlTlXiA==", - "41hbx5Yr7UWxsV6+bWUYUA==", - "SqJHXD0MorNwHtHL9TbWLg==", - "pWKGUzm/muwOiBtzkRMnRg==", - "az9zZ7HTa4FJGRQMcamvEw==", - "zavAAN8C9Wo8oBLyztp63Q==", - "yBAnPmwrMJ8kpPP292S/Lw==", - "E6szQhjuUAz2e0h9ffQfEQ==", - "Fs3cQxQyS9kM4T8j5R7rWw==", - "GB5fRLZxnjRUfEe0SwcePQ==", - "+9OY8xkT9dM/rb2T6ACtOQ==", - "If2xFBD1p91iDD7ZrsfgjA==", - "QCFfoMhy8EleZAOpfRY88w==", - "NobWPk1Z6bHt5s9NHXt/pg==", - "nK6T4vV4384OIcqO5tQMhA==", - "Zov1EzK+VomiuwT1+ulQ8g==", - "pF98OKDvLUlnTzo7wmlpOw==", - "Wrq9YDsieAMC3Y2DSY5Rcg==" - ] -} diff --git a/application/basilisk/base/content/newtab/newTab.js b/application/basilisk/base/content/newtab/newTab.js index bbd2ef39d..1731edadc 100644 --- a/application/basilisk/base/content/newtab/newTab.js +++ b/application/basilisk/base/content/newtab/newTab.js @@ -11,7 +11,6 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/PageThumbs.jsm"); Cu.import("resource://gre/modules/BackgroundPageThumbs.jsm"); -Cu.import("resource:///modules/DirectoryLinksProvider.jsm"); Cu.import("resource://gre/modules/NewTabUtils.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "Rect", diff --git a/application/basilisk/base/content/newtab/newTab.xhtml b/application/basilisk/base/content/newtab/newTab.xhtml index eef51b4b2..7de1ff3d4 100644 --- a/application/basilisk/base/content/newtab/newTab.xhtml +++ b/application/basilisk/base/content/newtab/newTab.xhtml @@ -73,7 +73,6 @@ <div id="newtab-horizontal-margin"> <div class="newtab-side-margin"/> <div id="newtab-grid"> - <h1 id="topsites-heading"/> </div> <div class="newtab-side-margin"/> </div> diff --git a/application/basilisk/base/content/newtab/page.js b/application/basilisk/base/content/newtab/page.js index f7626ced2..7c19a9827 100644 --- a/application/basilisk/base/content/newtab/page.js +++ b/application/basilisk/base/content/newtab/page.js @@ -48,11 +48,6 @@ var gPage = { let enabled = gAllPages.enabled; this._updateAttributes(enabled); - // Update thumbnails to the new enhanced setting - if (aData == "browser.newtabpage.enhanced") { - this.update(); - } - // Initialize the whole page if we haven't done that, yet. if (enabled) { this._init(); @@ -79,10 +74,7 @@ var gPage = { update(reason = "") { // Update immediately if we're visible. if (!document.hidden) { - // Ignore updates where reason=links-changed as those signal that the - // provider's set of links changed. We don't want to update visible pages - // in that case, it is ok to wait until the user opens the next tab. - if (reason != "links-changed" && gGrid.ready) { + if (gGrid.ready) { gGrid.refresh(); } @@ -119,10 +111,6 @@ var gPage = { document.getElementById("newtab-search-submit").value = document.body.getAttribute("dir") == "ltr" ? "\u25B6" : "\u25C0"; - if (Services.prefs.getBoolPref("browser.newtabpage.compact")) { - document.body.classList.add("compact"); - } - // Initialize search. gSearch.init(); @@ -174,16 +162,6 @@ var gPage = { */ _handleUnloadEvent: function Page_handleUnloadEvent() { gAllPages.unregister(this); - // compute page life-span and send telemetry probe: using milli-seconds will leave - // many low buckets empty. Instead we use half-second precision to make low end - // of histogram linear and not lose the change in user attention - let delta = Math.round((Date.now() - this._firstVisibleTime) / 500); - if (this._suggestedTilePresent) { - Services.telemetry.getHistogramById("NEWTAB_PAGE_LIFE_SPAN_SUGGESTED").add(delta); - } - else { - Services.telemetry.getHistogramById("NEWTAB_PAGE_LIFE_SPAN").add(delta); - } }, /** @@ -258,40 +236,5 @@ var gPage = { }, onPageVisibleAndLoaded() { - // Send the index of the last visible tile. - this.reportLastVisibleTileIndex(); - // Maybe tell the user they can undo an initial automigration - this.maybeShowAutoMigrationUndoNotification(); - }, - - reportLastVisibleTileIndex() { - let cwu = window.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDOMWindowUtils); - - let rect = cwu.getBoundsWithoutFlushing(gGrid.node); - let nodes = cwu.nodesFromRect(rect.left, rect.top, 0, rect.width, - rect.height, 0, true, false); - - let i = -1; - let lastIndex = -1; - let sites = gGrid.sites; - - for (let node of nodes) { - if (node.classList && node.classList.contains("newtab-cell")) { - if (sites[++i]) { - lastIndex = i; - if (sites[i].link.targetedSite) { - // record that suggested tile is shown to use suggested-tiles-histogram - this._suggestedTilePresent = true; - } - } - } - } - - DirectoryLinksProvider.reportSitesAction(sites, "view", lastIndex); - }, - - maybeShowAutoMigrationUndoNotification() { - sendAsyncMessage("NewTab:MaybeShowAutoMigrationUndoNotification"); - }, + } }; diff --git a/application/basilisk/base/content/newtab/sites.js b/application/basilisk/base/content/newtab/sites.js index 9d103ce9b..00f81869a 100644 --- a/application/basilisk/base/content/newtab/sites.js +++ b/application/basilisk/base/content/newtab/sites.js @@ -62,7 +62,7 @@ Site.prototype = { this._updateAttributes(true); let changed = gPinnedLinks.pin(this._link, aIndex); if (changed) { - // render site again to remove suggested/sponsored tags + // render site again this._render(); } return changed; @@ -136,15 +136,6 @@ Site.prototype = { return str; }, - _getSuggestedTileExplanation: function() { - let targetedName = `<strong> ${this.link.targetedName} </strong>`; - let targetedSite = `<strong> ${this.link.targetedSite} </strong>`; - if (this.link.explanation) { - return this._newTabString(this.link.explanation, [targetedName, targetedSite]); - } - return newTabString("suggested.button", [targetedName]); - }, - /** * Checks for and modifies link at campaign end time */ @@ -155,11 +146,8 @@ Site.prototype = { this.link.url = Services.io.newURI(this.url, null, null).resolve("/"); // clear supplied images - this triggers thumbnail download for new url delete this.link.imageURI; - delete this.link.enhancedImageURI; // remove endTime to avoid further time checks delete this.link.endTime; - // clear enhanced-content image that may still exist in preloaded page - this._querySelector(".enhanced-content").style.backgroundImage = ""; gPinnedLinks.replace(oldUrl, this.link); } }, @@ -171,11 +159,8 @@ Site.prototype = { // first check for end time, as it may modify the link this._checkLinkEndTime(); // setup display variables - let enhanced = gAllPages.enhanced && DirectoryLinksProvider.getEnhancedLink(this.link); let url = this.url; - let title = enhanced && enhanced.title ? enhanced.title : - this.link.type == "history" ? this.link.baseDomain : - this.title; + let title = this.link.type == "history" ? this.link.baseDomain : this.title; let tooltip = (this.title == url ? this.title : this.title + "\n" + url); let link = this._querySelector(".newtab-link"); @@ -189,22 +174,6 @@ Site.prototype = { titleNode.style.backgroundColor = this.link.titleBgColor; } - // remove "suggested" attribute to avoid showing "suggested" tag - // after site was pinned or dropped - this.node.removeAttribute("suggested"); - - if (this.link.targetedSite) { - if (this.node.getAttribute("type") != "sponsored") { - this._querySelector(".newtab-sponsored").textContent = - newTabString("suggested.tag"); - } - - this.node.setAttribute("suggested", true); - let explanation = this._getSuggestedTileExplanation(); - this._querySelector(".newtab-suggested").innerHTML = - `<div class='newtab-suggested-bounds'> ${explanation} </div>`; - } - if (this.isPinned()) this._updateAttributes(true); // Capture the page if the thumbnail is missing, which will cause page.js @@ -244,8 +213,7 @@ Site.prototype = { */ refreshThumbnail: function Site_refreshThumbnail() { // Only enhance tiles if that feature is turned on - let link = gAllPages.enhanced && DirectoryLinksProvider.getEnhancedLink(this.link) || - this.link; + let link = this.link; let thumbnail = this._querySelector(".newtab-thumbnail.thumbnail"); if (link.bgColor) { @@ -267,16 +235,6 @@ Site.prototype = { placeholder.style.backgroundColor = "hsl(" + hue + ",80%,40%)"; placeholder.textContent = link.baseDomain.substr(0,1).toUpperCase(); } - - if (link.enhancedImageURI) { - let enhanced = this._querySelector(".enhanced-content"); - enhanced.style.backgroundImage = 'url("' + link.enhancedImageURI + '")'; - - if (this.link.type != link.type) { - this.node.setAttribute("type", "enhanced"); - this.enhancedId = link.directoryId; - } - } }, _ignoreHoverEvents: function(element) { @@ -296,13 +254,6 @@ Site.prototype = { this._node.addEventListener("dragstart", this, false); this._node.addEventListener("dragend", this, false); this._node.addEventListener("mouseover", this, false); - - // Specially treat the sponsored icon & suggested explanation - // text to prevent regular hover effects - let sponsored = this._querySelector(".newtab-sponsored"); - let suggested = this._querySelector(".newtab-suggested"); - this._ignoreHoverEvents(sponsored); - this._ignoreHoverEvents(suggested); }, /** @@ -333,31 +284,6 @@ Site.prototype = { .add(aIndex); }, - _toggleLegalText: function(buttonClass, explanationTextClass) { - let button = this._querySelector(buttonClass); - if (button.hasAttribute("active")) { - let explain = this._querySelector(explanationTextClass); - explain.parentNode.removeChild(explain); - - button.removeAttribute("active"); - } - else { - let explain = document.createElementNS(HTML_NAMESPACE, "div"); - explain.className = explanationTextClass.slice(1); // Slice off the first character, '.' - this.node.appendChild(explain); - - let link = '<a href="' + TILES_EXPLAIN_LINK + '">' + - newTabString("learn.link") + "</a>"; - let type = (this.node.getAttribute("suggested") && this.node.getAttribute("type") == "affiliate") ? - "suggested" : this.node.getAttribute("type"); - let icon = '<input type="button" class="newtab-control newtab-' + - (type == "enhanced" ? "customize" : "control-block") + '"/>'; - explain.innerHTML = newTabString(type + (type == "sponsored" ? ".explain2" : ".explain"), [icon, link]); - - button.setAttribute("active", "true"); - } - }, - /** * Handles site click events. */ @@ -376,48 +302,25 @@ Site.prototype = { action = "click"; } } - // Handle sponsored explanation link click - else if (target.parentElement.classList.contains("sponsored-explain")) { - action = "sponsored_link"; - } - else if (target.parentElement.classList.contains("suggested-explain")) { - action = "suggested_link"; - } // Only handle primary clicks for the remaining targets else if (button == 0) { aEvent.preventDefault(); if (target.classList.contains("newtab-control-block")) { - // Notify DirectoryLinksProvider of suggested tile block, this may - // affect if and how suggested tiles are recommended and needs to - // be reported before pages are updated inside block() call - if (this.link.targetedSite) { - DirectoryLinksProvider.handleSuggestedTileBlock(); - } this.block(); action = "block"; } - else if (target.classList.contains("sponsored-explain") || - target.classList.contains("newtab-sponsored")) { - this._toggleLegalText(".newtab-sponsored", ".sponsored-explain"); - action = "sponsored"; - } else if (pinned && target.classList.contains("newtab-control-pin")) { this.unpin(); action = "unpin"; } else if (!pinned && target.classList.contains("newtab-control-pin")) { if (this.pin()) { - // suggested link has changed - update rest of the pages + // link has changed - update rest of the pages gAllPages.update(gPage); } action = "pin"; } } - - // Report all link click actions - if (action) { - DirectoryLinksProvider.reportSitesAction(gGrid.sites, action, tileIndex); - } }, /** diff --git a/application/basilisk/base/content/nsContextMenu.js b/application/basilisk/base/content/nsContextMenu.js index 3f77dcb90..370e5ba60 100644 --- a/application/basilisk/base/content/nsContextMenu.js +++ b/application/basilisk/base/content/nsContextMenu.js @@ -4,7 +4,6 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -Components.utils.import("resource://gre/modules/ContextualIdentityService.jsm"); Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm"); Components.utils.import("resource://gre/modules/InlineSpellChecker.jsm"); Components.utils.import("resource://gre/modules/LoginManagerContextMenu.jsm"); @@ -113,7 +112,6 @@ nsContextMenu.prototype = { this.initLeaveDOMFullScreenItems(); this.initClickToPlayItems(); this.initPasswordManagerItems(); - this.initSyncItems(); }, initPageMenuSeparator: function CM_initPageMenuSeparator() { @@ -142,28 +140,11 @@ nsContextMenu.prototype = { this.onPlainTextLink = true; } - var inContainer = false; - if (gContextMenuContentData.userContextId) { - inContainer = true; - var item = document.getElementById("context-openlinkincontainertab"); - - item.setAttribute("data-usercontextid", gContextMenuContentData.userContextId); - - var label = - ContextualIdentityService.getUserContextLabel(gContextMenuContentData.userContextId); - item.setAttribute("label", - gBrowserBundle.formatStringFromName("userContextOpenLink.label", - [label], 1)); - } - var shouldShow = this.onSaveableLink || isMailtoInternal || this.onPlainTextLink; var isWindowPrivate = PrivateBrowsingUtils.isWindowPrivate(window); - var showContainers = Services.prefs.getBoolPref("privacy.userContext.enabled"); this.showItem("context-openlink", shouldShow && !isWindowPrivate); this.showItem("context-openlinkprivate", shouldShow); - this.showItem("context-openlinkintab", shouldShow && !inContainer); - this.showItem("context-openlinkincontainertab", shouldShow && inContainer); - this.showItem("context-openlinkinusercontext-menu", shouldShow && !isWindowPrivate && showContainers); + this.showItem("context-openlinkintab", shouldShow); this.showItem("context-openlinkincurrent", this.onPlainTextLink); this.showItem("context-sep-open", shouldShow); }, @@ -540,10 +521,6 @@ nsContextMenu.prototype = { popup.insertBefore(fragment, insertBeforeElement); }, - initSyncItems: function() { - gFxAccounts.initPageContextMenu(this); - }, - openPasswordManager: function() { LoginHelper.openPasswordManager(window, gContextMenuContentData.documentURIObject.host); }, @@ -958,13 +935,6 @@ nsContextMenu.prototype = { params[p] = extra[p]; } - // If we want to change userContextId, we must be sure that we don't - // propagate the referrer. - if ("userContextId" in params && - params.userContextId != gContextMenuContentData.userContextId) { - params.noReferrer = true; - } - return params; }, @@ -982,7 +952,7 @@ nsContextMenu.prototype = { }, // Open linked-to URL in a new tab. - openLinkInTab: function(event) { + openLinkInTab: function() { urlSecurityCheck(this.linkURL, this.principal); let referrerURI = gContextMenuContentData.documentURIObject; @@ -1003,7 +973,6 @@ nsContextMenu.prototype = { let params = { allowMixedContent: persistAllowMixedContentInChildTab, - userContextId: parseInt(event.target.getAttribute('data-usercontextid')), }; openLinkIn(this.linkURL, "tab", this._openLinkInParameters(params)); @@ -1779,8 +1748,4 @@ nsContextMenu.prototype = { menuItem.label = menuLabel; menuItem.accessKey = gNavigatorBundle.getString("contextMenuSearch.accesskey"); }, - createContainerMenu: function(aEvent) { - return createUserContextMenu(aEvent, true, - gContextMenuContentData.userContextId); - }, }; diff --git a/application/basilisk/base/content/sync/aboutSyncTabs-bindings.xml b/application/basilisk/base/content/sync/aboutSyncTabs-bindings.xml deleted file mode 100644 index e6108209a..000000000 --- a/application/basilisk/base/content/sync/aboutSyncTabs-bindings.xml +++ /dev/null @@ -1,46 +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/. --> - -<bindings id="tabBindings" - xmlns="http://www.mozilla.org/xbl" - xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" - xmlns:xbl="http://www.mozilla.org/xbl"> - - <binding id="tab-listing" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem"> - <content> - <xul:hbox flex="1"> - <xul:vbox pack="start"> - <xul:image class="tabIcon" - xbl:inherits="src=icon"/> - </xul:vbox> - <xul:vbox pack="start" flex="1"> - <xul:label xbl:inherits="value=title,selected" - crop="end" flex="1" class="title"/> - <xul:label xbl:inherits="value=url,selected" - crop="end" flex="1" class="url"/> - </xul:vbox> - </xul:hbox> - </content> - <handlers> - <handler event="dblclick" button="0"> - <![CDATA[ - RemoteTabViewer.openSelected(); - ]]> - </handler> - </handlers> - </binding> - - <binding id="client-listing" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem"> - <content> - <xul:hbox pack="start" align="center" onfocus="event.target.blur()" onselect="return false;"> - <xul:image/> - <xul:label xbl:inherits="value=clientName" - class="clientName" - crop="center" flex="1"/> - </xul:hbox> - </content> - </binding> -</bindings> diff --git a/application/basilisk/base/content/sync/aboutSyncTabs.css b/application/basilisk/base/content/sync/aboutSyncTabs.css deleted file mode 100644 index 5a353175b..000000000 --- a/application/basilisk/base/content/sync/aboutSyncTabs.css +++ /dev/null @@ -1,11 +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/. */ - -richlistitem[type="tab"] { - -moz-binding: url(chrome://browser/content/sync/aboutSyncTabs-bindings.xml#tab-listing); -} - -richlistitem[type="client"] { - -moz-binding: url(chrome://browser/content/sync/aboutSyncTabs-bindings.xml#client-listing); -} diff --git a/application/basilisk/base/content/sync/aboutSyncTabs.js b/application/basilisk/base/content/sync/aboutSyncTabs.js deleted file mode 100644 index f4bb607ea..000000000 --- a/application/basilisk/base/content/sync/aboutSyncTabs.js +++ /dev/null @@ -1,364 +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/. */ - -var Cu = Components.utils; - -Cu.import("resource://services-common/utils.js"); -Cu.import("resource://services-sync/main.js"); -Cu.import("resource:///modules/PlacesUIUtils.jsm"); -Cu.import("resource://gre/modules/PlacesUtils.jsm", this); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "Promise", - "resource://gre/modules/Promise.jsm"); - -#ifdef MOZ_SERVICES_CLOUDSYNC -XPCOMUtils.defineLazyModuleGetter(this, "CloudSync", - "resource://gre/modules/CloudSync.jsm"); -#endif - -var RemoteTabViewer = { - _tabsList: null, - - init: function () { - Services.obs.addObserver(this, "weave:service:login:finish", false); - Services.obs.addObserver(this, "weave:engine:sync:finish", false); - - Services.obs.addObserver(this, "cloudsync:tabs:update", false); - - this._tabsList = document.getElementById("tabsList"); - - this.buildList(true); - }, - - uninit: function () { - Services.obs.removeObserver(this, "weave:service:login:finish"); - Services.obs.removeObserver(this, "weave:engine:sync:finish"); - - Services.obs.removeObserver(this, "cloudsync:tabs:update"); - }, - - createItem: function (attrs) { - let item = document.createElement("richlistitem"); - - // Copy the attributes from the argument into the item. - for (let attr in attrs) { - item.setAttribute(attr, attrs[attr]); - } - - if (attrs["type"] == "tab") { - item.label = attrs.title != "" ? attrs.title : attrs.url; - } - - return item; - }, - - filterTabs: function (event) { - let val = event.target.value.toLowerCase(); - let numTabs = this._tabsList.getRowCount(); - let clientTabs = 0; - let currentClient = null; - - for (let i = 0; i < numTabs; i++) { - let item = this._tabsList.getItemAtIndex(i); - let hide = false; - if (item.getAttribute("type") == "tab") { - if (!item.getAttribute("url").toLowerCase().includes(val) && - !item.getAttribute("title").toLowerCase().includes(val)) { - hide = true; - } else { - clientTabs++; - } - } - else if (item.getAttribute("type") == "client") { - if (currentClient) { - if (clientTabs == 0) { - currentClient.hidden = true; - } - } - currentClient = item; - clientTabs = 0; - } - item.hidden = hide; - } - if (clientTabs == 0) { - currentClient.hidden = true; - } - }, - - openSelected: function () { - let items = this._tabsList.selectedItems; - let urls = []; - for (let i = 0; i < items.length; i++) { - if (items[i].getAttribute("type") == "tab") { - urls.push(items[i].getAttribute("url")); - let index = this._tabsList.getIndexOfItem(items[i]); - this._tabsList.removeItemAt(index); - } - } - if (urls.length) { - getTopWin().gBrowser.loadTabs(urls); - this._tabsList.clearSelection(); - } - }, - - bookmarkSingleTab: function () { - let item = this._tabsList.selectedItems[0]; - let uri = Weave.Utils.makeURI(item.getAttribute("url")); - let title = item.getAttribute("title"); - PlacesUIUtils.showBookmarkDialog({ action: "add" - , type: "bookmark" - , uri: uri - , title: title - , hiddenRows: [ "description" - , "location" - , "loadInSidebar" - , "keyword" ] - }, window.top); - }, - - bookmarkSelectedTabs: function () { - let items = this._tabsList.selectedItems; - let URIs = []; - for (let i = 0; i < items.length; i++) { - if (items[i].getAttribute("type") == "tab") { - let uri = Weave.Utils.makeURI(items[i].getAttribute("url")); - if (!uri) { - continue; - } - - URIs.push(uri); - } - } - if (URIs.length) { - PlacesUIUtils.showBookmarkDialog({ action: "add" - , type: "folder" - , URIList: URIs - , hiddenRows: [ "description" ] - }, window.top); - } - }, - - getIcon: function (iconUri, defaultIcon) { - try { - let iconURI = Weave.Utils.makeURI(iconUri); - return PlacesUtils.favicons.getFaviconLinkForIcon(iconURI).spec; - } catch (ex) { - // Do nothing. - } - - // Just give the provided default icon or the system's default. - return defaultIcon || PlacesUtils.favicons.defaultFavicon.spec; - }, - - _waitingForBuildList: false, - - _buildListRequested: false, - - buildList: function (forceSync) { - if (this._waitingForBuildList) { - this._buildListRequested = true; - return; - } - - this._waitingForBuildList = true; - this._buildListRequested = false; - - this._clearTabList(); - - if (Weave.Service.isLoggedIn) { - this._refetchTabs(forceSync); - this._generateWeaveTabList(); - } else { - // XXXzpao We should say something about not being logged in & not having data - // or tell the appropriate condition. (bug 583344) - } - - let complete = () => { - this._waitingForBuildList = false; - if (this._buildListRequested) { - CommonUtils.nextTick(this.buildList, this); - } - } - -#ifdef MOZ_SERVICES_CLOUDSYNC - if (CloudSync && CloudSync.ready && CloudSync().tabsReady && CloudSync().tabs.hasRemoteTabs()) { - this._generateCloudSyncTabList() - .then(complete, complete); - } else { - complete(); - } -#else - complete(); -#endif - }, - - _clearTabList: function () { - let list = this._tabsList; - - // Clear out existing richlistitems. - let count = list.getRowCount(); - if (count > 0) { - for (let i = count - 1; i >= 0; i--) { - list.removeItemAt(i); - } - } - }, - - _generateWeaveTabList: function () { - let engine = Weave.Service.engineManager.get("tabs"); - let list = this._tabsList; - - let seenURLs = new Set(); - let localURLs = engine.getOpenURLs(); - - for (let [, client] of Object.entries(engine.getAllClients())) { - // Create the client node, but don't add it in-case we don't show any tabs - let appendClient = true; - - client.tabs.forEach(function({title, urlHistory, icon}) { - let url = urlHistory[0]; - if (!url || localURLs.has(url) || seenURLs.has(url)) { - return; - } - seenURLs.add(url); - - if (appendClient) { - let attrs = { - type: "client", - clientName: client.clientName, - class: Weave.Service.clientsEngine.isMobile(client.id) ? "mobile" : "desktop" - }; - let clientEnt = this.createItem(attrs); - list.appendChild(clientEnt); - appendClient = false; - clientEnt.disabled = true; - } - let attrs = { - type: "tab", - title: title || url, - url: url, - icon: this.getIcon(icon), - } - let tab = this.createItem(attrs); - list.appendChild(tab); - }, this); - } - }, - - _generateCloudSyncTabList: function () { - let updateTabList = function (remoteTabs) { - let list = this._tabsList; - - for (let client of remoteTabs) { - let clientAttrs = { - type: "client", - clientName: client.name, - }; - - let clientEnt = this.createItem(clientAttrs); - list.appendChild(clientEnt); - - for (let tab of client.tabs) { - let tabAttrs = { - type: "tab", - title: tab.title, - url: tab.url, - icon: this.getIcon(tab.icon), - }; - let tabEnt = this.createItem(tabAttrs); - list.appendChild(tabEnt); - } - } - }.bind(this); - - return CloudSync().tabs.getRemoteTabs() - .then(updateTabList, Promise.reject.bind(Promise)); - }, - - adjustContextMenu: function (event) { - let mode = "all"; - switch (this._tabsList.selectedItems.length) { - case 0: - break; - case 1: - mode = "single" - break; - default: - mode = "multiple"; - break; - } - - let menu = document.getElementById("tabListContext"); - let el = menu.firstChild; - while (el) { - let showFor = el.getAttribute("showFor"); - if (showFor) { - el.hidden = showFor != mode && showFor != "all"; - } - - el = el.nextSibling; - } - }, - - _refetchTabs: function (force) { - if (!force) { - // Don't bother refetching tabs if we already did so recently - let lastFetch = 0; - try { - lastFetch = Services.prefs.getIntPref("services.sync.lastTabFetch"); - } - catch (e) { - /* Just use the default value of 0 */ - } - - let now = Math.floor(Date.now() / 1000); - if (now - lastFetch < 30) { - return false; - } - } - - // Ask Sync to just do the tabs engine if it can. - Weave.Service.sync(["tabs"]); - Services.prefs.setIntPref("services.sync.lastTabFetch", - Math.floor(Date.now() / 1000)); - - return true; - }, - - observe: function (subject, topic, data) { - switch (topic) { - case "weave:service:login:finish": - // A login has finished, which means that a Sync is about to start and - // we will eventually get to the "tabs" engine - but try and force the - // tab engine to sync first by passing |true| for the forceSync param. - this.buildList(true); - break; - case "weave:engine:sync:finish": - if (data == "tabs") { - // The tabs engine just finished, so re-build the list without - // forcing a new sync of the tabs engine. - this.buildList(false); - } - break; - case "cloudsync:tabs:update": - this.buildList(false); - break; - } - }, - - handleClick: function (event) { - if (event.target.getAttribute("type") != "tab") { - return; - } - - if (event.button == 1) { - let url = event.target.getAttribute("url"); - openUILink(url, event); - let index = this._tabsList.getIndexOfItem(event.target); - this._tabsList.removeItemAt(index); - } - } -} diff --git a/application/basilisk/base/content/sync/aboutSyncTabs.xul b/application/basilisk/base/content/sync/aboutSyncTabs.xul deleted file mode 100644 index a4aa0032f..000000000 --- a/application/basilisk/base/content/sync/aboutSyncTabs.xul +++ /dev/null @@ -1,68 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<!-- 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://browser/skin/" type="text/css"?> -<?xml-stylesheet href="chrome://browser/skin/aboutSyncTabs.css" type="text/css"?> -<?xml-stylesheet href="chrome://browser/content/sync/aboutSyncTabs.css" type="text/css"?> - -<!DOCTYPE window [ - <!ENTITY % aboutSyncTabsDTD SYSTEM "chrome://browser/locale/aboutSyncTabs.dtd"> - %aboutSyncTabsDTD; -]> - -<window id="tabs-display" - onload="RemoteTabViewer.init()" - onunload="RemoteTabViewer.uninit()" - xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" - xmlns:html="http://www.w3.org/1999/xhtml" - title="&tabs.otherDevices.label;"> - <script type="application/javascript;version=1.8" src="chrome://browser/content/sync/aboutSyncTabs.js"/> - <script type="application/javascript" src="chrome://browser/content/utilityOverlay.js"/> - <html:head> - <html:link rel="icon" href="chrome://browser/skin/sync-16.png"/> - </html:head> - - <popupset id="contextmenus"> - <menupopup id="tabListContext"> - <menuitem label="&tabs.context.openTab.label;" - accesskey="&tabs.context.openTab.accesskey;" - oncommand="RemoteTabViewer.openSelected()" - showFor="single"/> - <menuitem label="&tabs.context.bookmarkSingleTab.label;" - accesskey="&tabs.context.bookmarkSingleTab.accesskey;" - oncommand="RemoteTabViewer.bookmarkSingleTab(event)" - showFor="single"/> - <menuitem label="&tabs.context.openMultipleTabs.label;" - accesskey="&tabs.context.openMultipleTabs.accesskey;" - oncommand="RemoteTabViewer.openSelected()" - showFor="multiple"/> - <menuitem label="&tabs.context.bookmarkMultipleTabs.label;" - accesskey="&tabs.context.bookmarkMultipleTabs.accesskey;" - oncommand="RemoteTabViewer.bookmarkSelectedTabs()" - showFor="multiple"/> - <menuseparator/> - <menuitem label="&tabs.context.refreshList.label;" - accesskey="&tabs.context.refreshList.accesskey;" - oncommand="RemoteTabViewer.buildList()" - showFor="all"/> - </menupopup> - </popupset> - <richlistbox context="tabListContext" id="tabsList" seltype="multiple" - align="center" flex="1" - onclick="RemoteTabViewer.handleClick(event)" - oncontextmenu="RemoteTabViewer.adjustContextMenu(event)"> - <hbox id="headers" align="center"> - <label id="tabsListHeading" - value="&tabs.otherDevices.label;"/> - <spacer flex="1"/> - <textbox type="search" - emptytext="&tabs.searchText.label;" - oncommand="RemoteTabViewer.filterTabs(event)"/> - </hbox> - - </richlistbox> -</window> - diff --git a/application/basilisk/base/content/sync/addDevice.js b/application/basilisk/base/content/sync/addDevice.js deleted file mode 100644 index 0390d4397..000000000 --- a/application/basilisk/base/content/sync/addDevice.js +++ /dev/null @@ -1,157 +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/. */ - -var Ci = Components.interfaces; -var Cc = Components.classes; -var Cu = Components.utils; - -Cu.import("resource://services-sync/main.js"); -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); - -const PIN_PART_LENGTH = 4; - -const ADD_DEVICE_PAGE = 0; -const SYNC_KEY_PAGE = 1; -const DEVICE_CONNECTED_PAGE = 2; - -var gSyncAddDevice = { - - init: function init() { - this.pin1.setAttribute("maxlength", PIN_PART_LENGTH); - this.pin2.setAttribute("maxlength", PIN_PART_LENGTH); - this.pin3.setAttribute("maxlength", PIN_PART_LENGTH); - - this.nextFocusEl = {pin1: this.pin2, - pin2: this.pin3, - pin3: this.wizard.getButton("next")}; - - this.throbber = document.getElementById("pairDeviceThrobber"); - this.errorRow = document.getElementById("errorRow"); - - // Kick off a sync. That way the server will have the most recent data from - // this computer and it will show up immediately on the new device. - Weave.Service.scheduler.scheduleNextSync(0); - }, - - onPageShow: function onPageShow() { - this.wizard.getButton("back").hidden = true; - - switch (this.wizard.pageIndex) { - case ADD_DEVICE_PAGE: - this.onTextBoxInput(); - this.wizard.canRewind = false; - this.wizard.getButton("next").hidden = false; - this.pin1.focus(); - break; - case SYNC_KEY_PAGE: - this.wizard.canAdvance = false; - this.wizard.canRewind = true; - this.wizard.getButton("back").hidden = false; - this.wizard.getButton("next").hidden = true; - document.getElementById("weavePassphrase").value = - Weave.Utils.hyphenatePassphrase(Weave.Service.identity.syncKey); - break; - case DEVICE_CONNECTED_PAGE: - this.wizard.canAdvance = true; - this.wizard.canRewind = false; - this.wizard.getButton("cancel").hidden = true; - break; - } - }, - - onWizardAdvance: function onWizardAdvance() { - switch (this.wizard.pageIndex) { - case ADD_DEVICE_PAGE: - this.startTransfer(); - return false; - case DEVICE_CONNECTED_PAGE: - window.close(); - return false; - } - return true; - }, - - startTransfer: function startTransfer() { - this.errorRow.hidden = true; - // When onAbort is called, Weave may already be gone. - const JPAKE_ERROR_USERABORT = Weave.JPAKE_ERROR_USERABORT; - - let self = this; - let jpakeclient = this._jpakeclient = new Weave.JPAKEClient({ - onPaired: function onPaired() { - let credentials = {account: Weave.Service.identity.account, - password: Weave.Service.identity.basicPassword, - synckey: Weave.Service.identity.syncKey, - serverURL: Weave.Service.serverURL}; - jpakeclient.sendAndComplete(credentials); - }, - onComplete: function onComplete() { - delete self._jpakeclient; - self.wizard.pageIndex = DEVICE_CONNECTED_PAGE; - - // Schedule a Sync for soonish to fetch the data uploaded by the - // device with which we just paired. - Weave.Service.scheduler.scheduleNextSync(Weave.Service.scheduler.activeInterval); - }, - onAbort: function onAbort(error) { - delete self._jpakeclient; - - // Aborted by user, ignore. - if (error == JPAKE_ERROR_USERABORT) { - return; - } - - self.errorRow.hidden = false; - self.throbber.hidden = true; - self.pin1.value = self.pin2.value = self.pin3.value = ""; - self.pin1.disabled = self.pin2.disabled = self.pin3.disabled = false; - self.pin1.focus(); - } - }); - this.throbber.hidden = false; - this.pin1.disabled = this.pin2.disabled = this.pin3.disabled = true; - this.wizard.canAdvance = false; - - let pin = this.pin1.value + this.pin2.value + this.pin3.value; - let expectDelay = false; - jpakeclient.pairWithPIN(pin, expectDelay); - }, - - onWizardBack: function onWizardBack() { - if (this.wizard.pageIndex != SYNC_KEY_PAGE) - return true; - - this.wizard.pageIndex = ADD_DEVICE_PAGE; - return false; - }, - - onWizardCancel: function onWizardCancel() { - if (this._jpakeclient) { - this._jpakeclient.abort(); - delete this._jpakeclient; - } - return true; - }, - - onTextBoxInput: function onTextBoxInput(textbox) { - if (textbox && textbox.value.length == PIN_PART_LENGTH) - this.nextFocusEl[textbox.id].focus(); - - this.wizard.canAdvance = (this.pin1.value.length == PIN_PART_LENGTH - && this.pin2.value.length == PIN_PART_LENGTH - && this.pin3.value.length == PIN_PART_LENGTH); - }, - - goToSyncKeyPage: function goToSyncKeyPage() { - this.wizard.pageIndex = SYNC_KEY_PAGE; - } - -}; -// onWizardAdvance() and onPageShow() are run before init() so we'll set -// these up as lazy getters. -["wizard", "pin1", "pin2", "pin3"].forEach(function (id) { - XPCOMUtils.defineLazyGetter(gSyncAddDevice, id, function() { - return document.getElementById(id); - }); -}); diff --git a/application/basilisk/base/content/sync/addDevice.xul b/application/basilisk/base/content/sync/addDevice.xul deleted file mode 100644 index 83c3b7b3c..000000000 --- a/application/basilisk/base/content/sync/addDevice.xul +++ /dev/null @@ -1,129 +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/. --> - -<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> -<?xml-stylesheet href="chrome://browser/skin/syncSetup.css" type="text/css"?> -<?xml-stylesheet href="chrome://browser/skin/syncCommon.css" type="text/css"?> - -<!DOCTYPE window [ -<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd"> -<!ENTITY % syncBrandDTD SYSTEM "chrome://browser/locale/syncBrand.dtd"> -<!ENTITY % syncSetupDTD SYSTEM "chrome://browser/locale/syncSetup.dtd"> -%brandDTD; -%syncBrandDTD; -%syncSetupDTD; -]> -<wizard xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" - xmlns:html="http://www.w3.org/1999/xhtml" - id="wizard" - title="&pairDevice.title.label;" - windowtype="Sync:AddDevice" - persist="screenX screenY" - onwizardnext="return gSyncAddDevice.onWizardAdvance();" - onwizardback="return gSyncAddDevice.onWizardBack();" - onwizardcancel="gSyncAddDevice.onWizardCancel();" - onload="gSyncAddDevice.init();"> - - <script type="application/javascript" - src="chrome://browser/content/sync/addDevice.js"/> - <script type="application/javascript" - src="chrome://browser/content/sync/utils.js"/> - <script type="application/javascript" - src="chrome://browser/content/utilityOverlay.js"/> - <script type="application/javascript" - src="chrome://global/content/printUtils.js"/> - - <wizardpage id="addDevicePage" - label="&pairDevice.title.label;" - onpageshow="gSyncAddDevice.onPageShow();"> - <description> - &pairDevice.dialog.description.label; - <label class="text-link" - value="&addDevice.showMeHow.label;" - href="https://services.mozilla.com/sync/help/add-device"/> - </description> - <separator class="groove-thin"/> - <description> - &addDevice.dialog.enterCode.label; - </description> - <separator class="groove-thin"/> - <vbox align="center"> - <textbox id="pin1" - class="pin" - oninput="gSyncAddDevice.onTextBoxInput(this);" - onfocus="this.select();" - /> - <textbox id="pin2" - class="pin" - oninput="gSyncAddDevice.onTextBoxInput(this);" - onfocus="this.select();" - /> - <textbox id="pin3" - class="pin" - oninput="gSyncAddDevice.onTextBoxInput(this);" - onfocus="this.select();" - /> - </vbox> - <separator class="groove-thin"/> - <vbox id="pairDeviceThrobber" align="center" hidden="true"> - <image/> - </vbox> - <hbox id="errorRow" pack="center" hidden="true"> - <image class="statusIcon" status="error"/> - <label class="status" - value="&addDevice.dialog.tryAgain.label;"/> - </hbox> - <spacer flex="3"/> - <label class="text-link" - value="&addDevice.dontHaveDevice.label;" - onclick="gSyncAddDevice.goToSyncKeyPage();"/> - </wizardpage> - - <!-- Need a non-empty label here, otherwise we get a default label on Mac --> - <wizardpage id="syncKeyPage" - label=" " - onpageshow="gSyncAddDevice.onPageShow();"> - <description> - &addDevice.dialog.recoveryKey.label; - </description> - <spacer/> - - <groupbox> - <label value="&recoveryKeyEntry.label;" - accesskey="&recoveryKeyEntry.accesskey;" - control="weavePassphrase"/> - <textbox id="weavePassphrase" - readonly="true"/> - </groupbox> - - <groupbox align="center"> - <description>&recoveryKeyBackup.description;</description> - <hbox> - <button id="printSyncKeyButton" - label="&button.syncKeyBackup.print.label;" - accesskey="&button.syncKeyBackup.print.accesskey;" - oncommand="gSyncUtils.passphrasePrint('weavePassphrase');"/> - <button id="saveSyncKeyButton" - label="&button.syncKeyBackup.save.label;" - accesskey="&button.syncKeyBackup.save.accesskey;" - oncommand="gSyncUtils.passphraseSave('weavePassphrase');"/> - </hbox> - </groupbox> - </wizardpage> - - <wizardpage id="deviceConnectedPage" - label="&addDevice.dialog.connected.label;" - onpageshow="gSyncAddDevice.onPageShow();"> - <vbox align="center"> - <image id="successPageIcon"/> - </vbox> - <separator/> - <description class="normal"> - &addDevice.dialog.successful.label; - </description> - </wizardpage> - -</wizard> diff --git a/application/basilisk/base/content/sync/customize.css b/application/basilisk/base/content/sync/customize.css deleted file mode 100644 index 2bb62595d..000000000 --- a/application/basilisk/base/content/sync/customize.css +++ /dev/null @@ -1,28 +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/. */ - -:root { - font-size: 80%; -} - -#sync-customize-pane { - padding-inline-start: 74px; - background: top left url(chrome://browser/skin/sync-128.png) no-repeat; - background-size: 64px; -} - -#sync-customize-title { - margin-inline-start: 0; - padding-bottom: 0.5em; - font-weight: bold; -} - -#sync-customize-subtitle { - font-size: 90%; -} - -checkbox { - margin: 0; - padding: 0.5em 0 0; -} diff --git a/application/basilisk/base/content/sync/customize.js b/application/basilisk/base/content/sync/customize.js deleted file mode 100644 index f431ac58c..000000000 --- a/application/basilisk/base/content/sync/customize.js +++ /dev/null @@ -1,25 +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/. */ - -"use strict"; - -Components.utils.import("resource://gre/modules/Services.jsm"); - -addEventListener("dialogaccept", function () { - let pane = document.getElementById("sync-customize-pane"); - // First determine what the preference for the "global" sync enabled pref - // should be based on the engines selected. - let prefElts = pane.querySelectorAll("preferences > preference"); - let syncEnabled = false; - for (let elt of prefElts) { - if (elt.name.startsWith("services.sync.") && elt.value) { - syncEnabled = true; - break; - } - } - Services.prefs.setBoolPref("services.sync.enabled", syncEnabled); - // and write the individual prefs. - pane.writePreferences(true); - window.arguments[0].accepted = true; -}); diff --git a/application/basilisk/base/content/sync/customize.xul b/application/basilisk/base/content/sync/customize.xul deleted file mode 100644 index 827edf565..000000000 --- a/application/basilisk/base/content/sync/customize.xul +++ /dev/null @@ -1,62 +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/. --> - -<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> -<?xml-stylesheet href="chrome://browser/content/sync/customize.css" type="text/css"?> - -<!DOCTYPE dialog [ -<!ENTITY % syncCustomizeDTD SYSTEM "chrome://browser/locale/syncCustomize.dtd"> -%syncCustomizeDTD; -]> -<dialog id="sync-customize" - windowtype="Sync:Customize" - xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" - xmlns:html="http://www.w3.org/1999/xhtml" - title="&syncCustomize.dialog.title;" - buttonlabelaccept="&syncCustomize.acceptButton.label;" - buttons="accept"> - - <prefpane id="sync-customize-pane"> - <preferences> - <preference id="engine.bookmarks" name="services.sync.engine.bookmarks" type="bool"/> - <preference id="engine.history" name="services.sync.engine.history" type="bool"/> - <preference id="engine.tabs" name="services.sync.engine.tabs" type="bool"/> - <preference id="engine.passwords" name="services.sync.engine.passwords" type="bool"/> - <preference id="engine.addons" name="services.sync.engine.addons" type="bool"/> - <preference id="engine.prefs" name="services.sync.engine.prefs" type="bool"/> - </preferences> - - <label id="sync-customize-title" value="&syncCustomize.title;"/> - <description id="sync-customize-subtitle" - value="&syncCustomize.description;"/> - - <vbox align="start"> - <checkbox label="&engine.tabs.label;" - accesskey="&engine.tabs.accesskey;" - preference="engine.tabs"/> - <checkbox label="&engine.bookmarks.label;" - accesskey="&engine.bookmarks.accesskey;" - preference="engine.bookmarks"/> - <checkbox label="&engine.passwords.label;" - accesskey="&engine.passwords.accesskey;" - preference="engine.passwords"/> - <checkbox label="&engine.history.label;" - accesskey="&engine.history.accesskey;" - preference="engine.history"/> - <checkbox label="&engine.addons.label;" - accesskey="&engine.addons.accesskey;" - preference="engine.addons"/> - <checkbox label="&engine.prefs.label;" - accesskey="&engine.prefs.accesskey;" - preference="engine.prefs"/> - </vbox> - - </prefpane> - - <script type="application/javascript" - src="chrome://browser/content/sync/customize.js" /> - -</dialog> diff --git a/application/basilisk/base/content/sync/genericChange.js b/application/basilisk/base/content/sync/genericChange.js deleted file mode 100644 index 51a74f1b1..000000000 --- a/application/basilisk/base/content/sync/genericChange.js +++ /dev/null @@ -1,233 +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/. */ - -var Ci = Components.interfaces; -var Cc = Components.classes; - -Components.utils.import("resource://services-sync/main.js"); -Components.utils.import("resource://gre/modules/Services.jsm"); - -var Change = { - _dialog: null, - _dialogType: null, - _status: null, - _statusIcon: null, - _firstBox: null, - _secondBox: null, - - get _passphraseBox() { - delete this._passphraseBox; - return this._passphraseBox = document.getElementById("passphraseBox"); - }, - - get _currentPasswordInvalid() { - return Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED; - }, - - get _updatingPassphrase() { - return this._dialogType == "UpdatePassphrase"; - }, - - onLoad: function Change_onLoad() { - /* Load labels */ - let introText = document.getElementById("introText"); - let warningText = document.getElementById("warningText"); - - // load some other elements & info from the window - this._dialog = document.getElementById("change-dialog"); - this._dialogType = window.arguments[0]; - this._duringSetup = window.arguments[1]; - this._status = document.getElementById("status"); - this._statusIcon = document.getElementById("statusIcon"); - this._statusRow = document.getElementById("statusRow"); - this._firstBox = document.getElementById("textBox1"); - this._secondBox = document.getElementById("textBox2"); - - this._dialog.getButton("finish").disabled = true; - this._dialog.getButton("back").hidden = true; - - this._stringBundle = - Services.strings.createBundle("chrome://browser/locale/syncGenericChange.properties"); - - switch (this._dialogType) { - case "UpdatePassphrase": - case "ResetPassphrase": - document.getElementById("textBox1Row").hidden = true; - document.getElementById("textBox2Row").hidden = true; - document.getElementById("passphraseLabel").value - = this._str("new.recoverykey.label"); - document.getElementById("passphraseSpacer").hidden = false; - - if (this._updatingPassphrase) { - document.getElementById("passphraseHelpBox").hidden = false; - document.title = this._str("new.recoverykey.title"); - introText.textContent = this._str("new.recoverykey.introText"); - this._dialog.getButton("finish").label - = this._str("new.recoverykey.acceptButton"); - } - else { - document.getElementById("generatePassphraseButton").hidden = false; - document.getElementById("passphraseBackupButtons").hidden = false; - this._passphraseBox.setAttribute("readonly", "true"); - let pp = Weave.Service.identity.syncKey; - if (Weave.Utils.isPassphrase(pp)) - pp = Weave.Utils.hyphenatePassphrase(pp); - this._passphraseBox.value = pp; - this._passphraseBox.focus(); - document.title = this._str("change.recoverykey.title"); - introText.textContent = this._str("change.synckey.introText2"); - warningText.textContent = this._str("change.recoverykey.warningText"); - this._dialog.getButton("finish").label - = this._str("change.recoverykey.acceptButton"); - if (this._duringSetup) { - this._dialog.getButton("finish").disabled = false; - } - } - break; - case "ChangePassword": - document.getElementById("passphraseRow").hidden = true; - let box1label = document.getElementById("textBox1Label"); - let box2label = document.getElementById("textBox2Label"); - box1label.value = this._str("new.password.label"); - - if (this._currentPasswordInvalid) { - document.title = this._str("new.password.title"); - introText.textContent = this._str("new.password.introText"); - this._dialog.getButton("finish").label - = this._str("new.password.acceptButton"); - document.getElementById("textBox2Row").hidden = true; - } - else { - document.title = this._str("change.password.title"); - box2label.value = this._str("new.password.confirm"); - introText.textContent = this._str("change.password3.introText"); - warningText.textContent = this._str("change.password.warningText"); - this._dialog.getButton("finish").label - = this._str("change.password.acceptButton"); - } - break; - } - document.getElementById("change-page") - .setAttribute("label", document.title); - }, - - _clearStatus: function _clearStatus() { - this._status.value = ""; - this._statusIcon.removeAttribute("status"); - }, - - _updateStatus: function Change__updateStatus(str, state) { - this._updateStatusWithString(this._str(str), state); - }, - - _updateStatusWithString: function Change__updateStatusWithString(string, state) { - this._statusRow.hidden = false; - this._status.value = string; - this._statusIcon.setAttribute("status", state); - - let error = state == "error"; - this._dialog.getButton("cancel").disabled = !error; - this._dialog.getButton("finish").disabled = !error; - document.getElementById("printSyncKeyButton").disabled = !error; - document.getElementById("saveSyncKeyButton").disabled = !error; - - if (state == "success") - window.setTimeout(window.close, 1500); - }, - - onDialogAccept: function() { - switch (this._dialogType) { - case "UpdatePassphrase": - case "ResetPassphrase": - return this.doChangePassphrase(); - case "ChangePassword": - return this.doChangePassword(); - } - return undefined; - }, - - doGeneratePassphrase: function () { - let passphrase = Weave.Utils.generatePassphrase(); - this._passphraseBox.value = Weave.Utils.hyphenatePassphrase(passphrase); - this._dialog.getButton("finish").disabled = false; - }, - - doChangePassphrase: function Change_doChangePassphrase() { - let pp = Weave.Utils.normalizePassphrase(this._passphraseBox.value); - if (this._updatingPassphrase) { - Weave.Service.identity.syncKey = pp; - if (Weave.Service.login()) { - this._updateStatus("change.recoverykey.success", "success"); - Weave.Service.persistLogin(); - Weave.Service.scheduler.delayedAutoConnect(0); - } - else { - this._updateStatus("new.passphrase.status.incorrect", "error"); - } - } - else { - this._updateStatus("change.recoverykey.label", "active"); - - if (Weave.Service.changePassphrase(pp)) - this._updateStatus("change.recoverykey.success", "success"); - else - this._updateStatus("change.recoverykey.error", "error"); - } - - return false; - }, - - doChangePassword: function Change_doChangePassword() { - if (this._currentPasswordInvalid) { - Weave.Service.identity.basicPassword = this._firstBox.value; - if (Weave.Service.login()) { - this._updateStatus("change.password.status.success", "success"); - Weave.Service.persistLogin(); - } - else { - this._updateStatus("new.password.status.incorrect", "error"); - } - } - else { - this._updateStatus("change.password.status.active", "active"); - - if (Weave.Service.changePassword(this._firstBox.value)) - this._updateStatus("change.password.status.success", "success"); - else - this._updateStatus("change.password.status.error", "error"); - } - - return false; - }, - - validate: function (event) { - let valid = false; - let errorString = ""; - - if (this._dialogType == "ChangePassword") { - if (this._currentPasswordInvalid) - [valid, errorString] = gSyncUtils.validatePassword(this._firstBox); - else - [valid, errorString] = gSyncUtils.validatePassword(this._firstBox, this._secondBox); - } - else { - if (!this._updatingPassphrase) - return; - - valid = this._passphraseBox.value != ""; - } - - if (errorString == "") - this._clearStatus(); - else - this._updateStatusWithString(errorString, "error"); - - this._statusRow.hidden = valid; - this._dialog.getButton("finish").disabled = !valid; - }, - - _str: function Change__string(str) { - return this._stringBundle.GetStringFromName(str); - } -}; diff --git a/application/basilisk/base/content/sync/genericChange.xul b/application/basilisk/base/content/sync/genericChange.xul deleted file mode 100644 index db74a1b31..000000000 --- a/application/basilisk/base/content/sync/genericChange.xul +++ /dev/null @@ -1,123 +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/. --> - -<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> -<?xml-stylesheet href="chrome://browser/skin/syncSetup.css" type="text/css"?> -<?xml-stylesheet href="chrome://browser/skin/syncCommon.css" type="text/css"?> - -<!DOCTYPE window [ -<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd"> -<!ENTITY % syncBrandDTD SYSTEM "chrome://browser/locale/syncBrand.dtd"> -<!ENTITY % syncSetupDTD SYSTEM "chrome://browser/locale/syncSetup.dtd"> -%brandDTD; -%syncBrandDTD; -%syncSetupDTD; -]> -<wizard xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" - xmlns:html="http://www.w3.org/1999/xhtml" - id="change-dialog" - windowtype="Weave:ChangeSomething" - persist="screenX screenY" - onwizardnext="Change.onLoad()" - onwizardfinish="return Change.onDialogAccept();"> - - <script type="application/javascript" - src="chrome://browser/content/sync/genericChange.js"/> - <script type="application/javascript" - src="chrome://browser/content/sync/utils.js"/> - <script type="application/javascript" - src="chrome://global/content/printUtils.js"/> - - <wizardpage id="change-page" - label=""> - - <description id="introText"> - </description> - - <separator class="thin"/> - - <groupbox> - <grid> - <columns> - <column align="right"/> - <column flex="3"/> - <column flex="1"/> - </columns> - <rows> - <row id="textBox1Row" align="center"> - <label id="textBox1Label" control="textBox1"/> - <textbox id="textBox1" type="password" oninput="Change.validate()"/> - <spacer/> - </row> - <row id="textBox2Row" align="center"> - <label id="textBox2Label" control="textBox2"/> - <textbox id="textBox2" type="password" oninput="Change.validate()"/> - <spacer/> - </row> - </rows> - </grid> - - <vbox id="passphraseRow"> - <hbox flex="1"> - <label id="passphraseLabel" control="passphraseBox"/> - <spacer flex="1"/> - <label id="generatePassphraseButton" - hidden="true" - value="&syncGenerateNewKey.label;" - class="text-link" - onclick="event.stopPropagation(); - Change.doGeneratePassphrase();"/> - </hbox> - <textbox id="passphraseBox" - flex="1" - onfocus="this.select()" - oninput="Change.validate()"/> - </vbox> - - <vbox id="feedback" pack="center"> - <hbox id="statusRow" align="center"> - <image id="statusIcon" class="statusIcon"/> - <label id="status" class="status" value=" "/> - </hbox> - </vbox> - </groupbox> - - <separator class="thin"/> - - <hbox id="passphraseBackupButtons" - hidden="true" - pack="center"> - <button id="printSyncKeyButton" - label="&button.syncKeyBackup.print.label;" - accesskey="&button.syncKeyBackup.print.accesskey;" - oncommand="gSyncUtils.passphrasePrint('passphraseBox');"/> - <button id="saveSyncKeyButton" - label="&button.syncKeyBackup.save.label;" - accesskey="&button.syncKeyBackup.save.accesskey;" - oncommand="gSyncUtils.passphraseSave('passphraseBox');"/> - </hbox> - - <vbox id="passphraseHelpBox" - hidden="true"> - <description> - &existingRecoveryKey.description; - <label class="text-link" - href="https://services.mozilla.com/sync/help/manual-setup"> - &addDevice.showMeHow.label; - </label> - </description> - </vbox> - - <spacer id="passphraseSpacer" - flex="1" - hidden="true"/> - - <description id="warningText" class="data"> - </description> - - <spacer flex="1"/> - </wizardpage> -</wizard> diff --git a/application/basilisk/base/content/sync/key.xhtml b/application/basilisk/base/content/sync/key.xhtml deleted file mode 100644 index 1363132e7..000000000 --- a/application/basilisk/base/content/sync/key.xhtml +++ /dev/null @@ -1,54 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<!-- 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/. --> - -<!DOCTYPE html [ - <!ENTITY % htmlDTD PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd"> - %htmlDTD; - <!ENTITY % syncBrandDTD SYSTEM "chrome://browser/locale/syncBrand.dtd"> - %syncBrandDTD; - <!ENTITY % syncKeyDTD SYSTEM "chrome://browser/locale/syncKey.dtd"> - %syncKeyDTD; - <!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd" > - %globalDTD; -]> -<html xmlns="http://www.w3.org/1999/xhtml"> -<head> - <title>&syncKey.page.title;</title> - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> - <meta name="robots" content="noindex"/> - <style type="text/css"> - #synckey { font-size: 150% } - footer { font-size: 70% } - /* Bug 575675: Need to have an a:visited rule in a chrome document. */ - a:visited { color: purple; } - </style> -</head> - -<body dir="&locale.dir;"> -<h1>&syncKey.page.title;</h1> - -<p id="synckey" dir="ltr">SYNCKEY</p> - -<p>&syncKey.page.description2;</p> - -<div id="column1"> - <h2>&syncKey.keepItSecret.heading;</h2> - <p>&syncKey.keepItSecret.description;</p> -</div> - -<div id="column2"> - <h2>&syncKey.keepItSafe.heading;</h2> - <p><em>&syncKey.keepItSafe1.description;</em>&syncKey.keepItSafe2.description;<em>&syncKey.keepItSafe3.description;</em>&syncKey.keepItSafe4a.description;</p> -</div> - -<p>&syncKey.findOutMore1.label;<a href="https://services.mozilla.com">https://services.mozilla.com</a>&syncKey.findOutMore2.label;</p> - -<footer> - &syncKey.footer1.label;<a id="tosLink" href="termsURL">termsURL</a>&syncKey.footer2.label;<a id="ppLink" href="privacyURL">privacyURL</a>&syncKey.footer3.label; -</footer> - -</body> -</html> diff --git a/application/basilisk/base/content/sync/quota.js b/application/basilisk/base/content/sync/quota.js deleted file mode 100644 index b416a44cc..000000000 --- a/application/basilisk/base/content/sync/quota.js +++ /dev/null @@ -1,247 +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/. */ - -const Ci = Components.interfaces; -const Cc = Components.classes; -const Cr = Components.results; -const Cu = Components.utils; - -Cu.import("resource://services-sync/main.js"); -Cu.import("resource://gre/modules/DownloadUtils.jsm"); - -var gSyncQuota = { - - init: function init() { - this.bundle = document.getElementById("quotaStrings"); - let caption = document.getElementById("treeCaption"); - caption.firstChild.nodeValue = this.bundle.getString("quota.treeCaption.label"); - - gUsageTreeView.init(); - this.tree = document.getElementById("usageTree"); - this.tree.view = gUsageTreeView; - - this.loadData(); - }, - - loadData: function loadData() { - this._usage_req = Weave.Service.getStorageInfo(Weave.INFO_COLLECTION_USAGE, - function (error, usage) { - delete gSyncQuota._usage_req; - // displayUsageData handles null values, so no need to check 'error'. - gUsageTreeView.displayUsageData(usage); - }); - - let usageLabel = document.getElementById("usageLabel"); - let bundle = this.bundle; - - this._quota_req = Weave.Service.getStorageInfo(Weave.INFO_QUOTA, - function (error, quota) { - delete gSyncQuota._quota_req; - - if (error) { - usageLabel.value = bundle.getString("quota.usageError.label"); - return; - } - let used = gSyncQuota.convertKB(quota[0]); - if (!quota[1]) { - // No quota on the server. - usageLabel.value = bundle.getFormattedString( - "quota.usageNoQuota.label", used); - return; - } - let percent = Math.round(100 * quota[0] / quota[1]); - let total = gSyncQuota.convertKB(quota[1]); - usageLabel.value = bundle.getFormattedString( - "quota.usagePercentage.label", [percent].concat(used).concat(total)); - }); - }, - - onCancel: function onCancel() { - if (this._usage_req) { - this._usage_req.abort(); - } - if (this._quota_req) { - this._quota_req.abort(); - } - return true; - }, - - onAccept: function onAccept() { - let engines = gUsageTreeView.getEnginesToDisable(); - for each (let engine in engines) { - Weave.Service.engineManager.get(engine).enabled = false; - } - if (engines.length) { - // The 'Weave' object will disappear once the window closes. - let Service = Weave.Service; - Weave.Utils.nextTick(function() { Service.sync(); }); - } - return this.onCancel(); - }, - - convertKB: function convertKB(value) { - return DownloadUtils.convertByteUnits(value * 1024); - } - -}; - -var gUsageTreeView = { - - _ignored: {keys: true, - meta: true, - clients: true}, - - /* - * Internal data structures underlaying the tree. - */ - _collections: [], - _byname: {}, - - init: function init() { - let retrievingLabel = gSyncQuota.bundle.getString("quota.retrieving.label"); - for each (let engine in Weave.Service.engineManager.getEnabled()) { - if (this._ignored[engine.name]) - continue; - - // Some engines use the same pref, which means they can only be turned on - // and off together. We need to combine them here as well. - let existing = this._byname[engine.prefName]; - if (existing) { - existing.engines.push(engine.name); - continue; - } - - let obj = {name: engine.prefName, - title: this._collectionTitle(engine), - engines: [engine.name], - enabled: true, - sizeLabel: retrievingLabel}; - this._collections.push(obj); - this._byname[engine.prefName] = obj; - } - }, - - _collectionTitle: function _collectionTitle(engine) { - try { - return gSyncQuota.bundle.getString( - "collection." + engine.prefName + ".label"); - } catch (ex) { - return engine.Name; - } - }, - - /* - * Process the quota information as returned by info/collection_usage. - */ - displayUsageData: function displayUsageData(data) { - for each (let coll in this._collections) { - coll.size = 0; - // If we couldn't retrieve any data, just blank out the label. - if (!data) { - coll.sizeLabel = ""; - continue; - } - - for each (let engineName in coll.engines) - coll.size += data[engineName] || 0; - let sizeLabel = ""; - sizeLabel = gSyncQuota.bundle.getFormattedString( - "quota.sizeValueUnit.label", gSyncQuota.convertKB(coll.size)); - coll.sizeLabel = sizeLabel; - } - let sizeColumn = this.treeBox.columns.getNamedColumn("size"); - this.treeBox.invalidateColumn(sizeColumn); - }, - - /* - * Handle click events on the tree. - */ - onTreeClick: function onTreeClick(event) { - if (event.button == 2) - return; - - let cell = this.treeBox.getCellAt(event.clientX, event.clientY); - if (cell.col && cell.col.id == "enabled") - this.toggle(cell.row); - }, - - /* - * Toggle enabled state of an engine. - */ - toggle: function toggle(row) { - // Update the tree - let collection = this._collections[row]; - collection.enabled = !collection.enabled; - this.treeBox.invalidateRow(row); - }, - - /* - * Return a list of engines (or rather their pref names) that should be - * disabled. - */ - getEnginesToDisable: function getEnginesToDisable() { - // Tycho: return [coll.name for each (coll in this._collections) if (!coll.enabled)]; - let engines = []; - for each (let coll in this._collections) { - if (!coll.enabled) { - engines.push(coll.name); - } - } - return engines; - }, - - // nsITreeView - - get rowCount() { - return this._collections.length; - }, - - getRowProperties: function(index) { return ""; }, - getCellProperties: function(row, col) { return ""; }, - getColumnProperties: function(col) { return ""; }, - isContainer: function(index) { return false; }, - isContainerOpen: function(index) { return false; }, - isContainerEmpty: function(index) { return false; }, - isSeparator: function(index) { return false; }, - isSorted: function() { return false; }, - canDrop: function(index, orientation, dataTransfer) { return false; }, - drop: function(row, orientation, dataTransfer) {}, - getParentIndex: function(rowIndex) {}, - hasNextSibling: function(rowIndex, afterIndex) { return false; }, - getLevel: function(index) { return 0; }, - getImageSrc: function(row, col) {}, - - getCellValue: function(row, col) { - return this._collections[row].enabled; - }, - - getCellText: function getCellText(row, col) { - let collection = this._collections[row]; - switch (col.id) { - case "collection": - return collection.title; - case "size": - return collection.sizeLabel; - default: - return ""; - } - }, - - setTree: function setTree(tree) { - this.treeBox = tree; - }, - - toggleOpenState: function(index) {}, - cycleHeader: function(col) {}, - selectionChanged: function() {}, - cycleCell: function(row, col) {}, - isEditable: function(row, col) { return false; }, - isSelectable: function (row, col) { return false; }, - setCellValue: function(row, col, value) {}, - setCellText: function(row, col, value) {}, - performAction: function(action) {}, - performActionOnRow: function(action, row) {}, - performActionOnCell: function(action, row, col) {} - -}; diff --git a/application/basilisk/base/content/sync/quota.xul b/application/basilisk/base/content/sync/quota.xul deleted file mode 100644 index 99e6ed78b..000000000 --- a/application/basilisk/base/content/sync/quota.xul +++ /dev/null @@ -1,65 +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/. --> - -<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> -<?xml-stylesheet href="chrome://browser/skin/syncQuota.css"?> - -<!DOCTYPE dialog [ -<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd"> -<!ENTITY % syncBrandDTD SYSTEM "chrome://browser/locale/syncBrand.dtd"> -<!ENTITY % syncQuotaDTD SYSTEM "chrome://browser/locale/syncQuota.dtd"> -%brandDTD; -%syncBrandDTD; -%syncQuotaDTD; -]> -<dialog id="quotaDialog" - windowtype="Sync:ViewQuota" - persist="screenX screenY width height" - xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" - xmlns:html="http://www.w3.org/1999/xhtml" - onload="gSyncQuota.init()" - buttons="accept,cancel" - title=""a.dialogTitle.label;" - ondialogcancel="return gSyncQuota.onCancel();" - ondialogaccept="return gSyncQuota.onAccept();"> - - <script type="application/javascript" - src="chrome://browser/content/sync/quota.js"/> - - <stringbundleset id="stringbundleset"> - <stringbundle id="quotaStrings" - src="chrome://browser/locale/syncQuota.properties"/> - </stringbundleset> - - <vbox flex="1"> - <label id="usageLabel" - value=""a.retrievingInfo.label;"/> - <separator/> - <tree id="usageTree" - seltype="single" - hidecolumnpicker="true" - onclick="gUsageTreeView.onTreeClick(event);" - flex="1"> - <treecols> - <treecol id="enabled" - type="checkbox" - fixed="true"/> - <splitter class="tree-splitter"/> - <treecol id="collection" - label=""a.typeColumn.label;" - flex="1"/> - <splitter class="tree-splitter"/> - <treecol id="size" - label=""a.sizeColumn.label;" - flex="1"/> - </treecols> - <treechildren flex="1"/> - </tree> - <separator/> - <description id="treeCaption"> </description> - </vbox> - -</dialog> diff --git a/application/basilisk/base/content/sync/setup.js b/application/basilisk/base/content/sync/setup.js deleted file mode 100644 index f9dae1bd4..000000000 --- a/application/basilisk/base/content/sync/setup.js +++ /dev/null @@ -1,1060 +0,0 @@ -// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- -/* 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/. */ - -var Ci = Components.interfaces; -var Cc = Components.classes; -var Cr = Components.results; -var Cu = Components.utils; - -// page consts - -const PAIR_PAGE = 0; -const INTRO_PAGE = 1; -const NEW_ACCOUNT_START_PAGE = 2; -const EXISTING_ACCOUNT_CONNECT_PAGE = 3; -const EXISTING_ACCOUNT_LOGIN_PAGE = 4; -const OPTIONS_PAGE = 5; -const OPTIONS_CONFIRM_PAGE = 6; - -// Broader than we'd like, but after this changed from api-secure.recaptcha.net -// we had no choice. At least we only do this for the duration of setup. -// See discussion in Bugs 508112 and 653307. -const RECAPTCHA_DOMAIN = "https://www.google.com"; - -const PIN_PART_LENGTH = 4; - -Cu.import("resource://services-sync/main.js"); -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/PlacesUtils.jsm"); -Cu.import("resource://gre/modules/PluralForm.jsm"); - - -function setVisibility(element, visible) { - element.style.visibility = visible ? "visible" : "hidden"; -} - -var gSyncSetup = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports, - Ci.nsIWebProgressListener, - Ci.nsISupportsWeakReference]), - - captchaBrowser: null, - wizard: null, - _disabledSites: [], - - status: { - password: false, - email: false, - server: false - }, - - get _remoteSites() { - return [Weave.Service.serverURL, RECAPTCHA_DOMAIN]; - }, - - get _usingMainServers() { - if (this._settingUpNew) - return document.getElementById("server").selectedIndex == 0; - return document.getElementById("existingServer").selectedIndex == 0; - }, - - init: function () { - let obs = [ - ["weave:service:change-passphrase", "onResetPassphrase"], - ["weave:service:login:start", "onLoginStart"], - ["weave:service:login:error", "onLoginEnd"], - ["weave:service:login:finish", "onLoginEnd"]]; - - // Add the observers now and remove them on unload - let self = this; - let addRem = function(add) { - obs.forEach(function([topic, func]) { - // XXXzpao This should use Services.obs.* but Weave's Obs does nice handling - // of `this`. Fix in a followup. (bug 583347) - if (add) - Weave.Svc.Obs.add(topic, self[func], self); - else - Weave.Svc.Obs.remove(topic, self[func], self); - }); - }; - addRem(true); - window.addEventListener("unload", () => addRem(false), false); - - window.setTimeout(function () { - // Force Service to be loaded so that engines are registered. - // See Bug 670082. - Weave.Service; - }, 0); - - this.captchaBrowser = document.getElementById("captcha"); - - this.wizardType = null; - if (window.arguments && window.arguments[0]) { - this.wizardType = window.arguments[0]; - } - switch (this.wizardType) { - case null: - this.wizard.pageIndex = INTRO_PAGE; - // Fall through! - case "pair": - this.captchaBrowser.addProgressListener(this); - Weave.Svc.Prefs.set("firstSync", "notReady"); - break; - case "reset": - this._resettingSync = true; - this.wizard.pageIndex = OPTIONS_PAGE; - break; - } - - this.wizard.getButton("extra1").label = - this._stringBundle.GetStringFromName("button.syncOptions.label"); - - // Remember these values because the options pages change them temporarily. - this._nextButtonLabel = this.wizard.getButton("next").label; - this._nextButtonAccesskey = this.wizard.getButton("next") - .getAttribute("accesskey"); - this._backButtonLabel = this.wizard.getButton("back").label; - this._backButtonAccesskey = this.wizard.getButton("back") - .getAttribute("accesskey"); - }, - - startNewAccountSetup: function () { - if (!Weave.Utils.ensureMPUnlocked()) - return; - this._settingUpNew = true; - this.wizard.pageIndex = NEW_ACCOUNT_START_PAGE; - }, - - useExistingAccount: function () { - if (!Weave.Utils.ensureMPUnlocked()) - return; - this._settingUpNew = false; - if (this.wizardType == "pair") { - // We're already pairing, so there's no point in pairing again. - // Go straight to the manual login page. - this.wizard.pageIndex = EXISTING_ACCOUNT_LOGIN_PAGE; - } else { - this.wizard.pageIndex = EXISTING_ACCOUNT_CONNECT_PAGE; - } - }, - - resetPassphrase: function resetPassphrase() { - // Apply the existing form fields so that - // Weave.Service.changePassphrase() has the necessary credentials. - Weave.Service.identity.account = document.getElementById("existingAccountName").value; - Weave.Service.identity.basicPassword = document.getElementById("existingPassword").value; - - // Generate a new passphrase so that Weave.Service.login() will - // actually do something. - let passphrase = Weave.Utils.generatePassphrase(); - Weave.Service.identity.syncKey = passphrase; - - // Only open the dialog if username + password are actually correct. - Weave.Service.login(); - if ([Weave.LOGIN_FAILED_INVALID_PASSPHRASE, - Weave.LOGIN_FAILED_NO_PASSPHRASE, - Weave.LOGIN_SUCCEEDED].indexOf(Weave.Status.login) == -1) { - return; - } - - // Hide any errors about the passphrase, we know it's not right. - let feedback = document.getElementById("existingPassphraseFeedbackRow"); - feedback.hidden = true; - let el = document.getElementById("existingPassphrase"); - el.value = Weave.Utils.hyphenatePassphrase(passphrase); - - // changePassphrase() will sync, make sure we set the "firstSync" pref - // according to the user's pref. - Weave.Svc.Prefs.reset("firstSync"); - this.setupInitialSync(); - gSyncUtils.resetPassphrase(true); - }, - - onResetPassphrase: function () { - document.getElementById("existingPassphrase").value = - Weave.Utils.hyphenatePassphrase(Weave.Service.identity.syncKey); - this.checkFields(); - this.wizard.advance(); - }, - - onLoginStart: function () { - this.toggleLoginFeedback(false); - }, - - onLoginEnd: function () { - this.toggleLoginFeedback(true); - }, - - sendCredentialsAfterSync: function () { - let send = function() { - Services.obs.removeObserver("weave:service:sync:finish", send); - Services.obs.removeObserver("weave:service:sync:error", send); - let credentials = {account: Weave.Service.identity.account, - password: Weave.Service.identity.basicPassword, - synckey: Weave.Service.identity.syncKey, - serverURL: Weave.Service.serverURL}; - this._jpakeclient.sendAndComplete(credentials); - }.bind(this); - Services.obs.addObserver("weave:service:sync:finish", send, false); - Services.obs.addObserver("weave:service:sync:error", send, false); - }, - - toggleLoginFeedback: function (stop) { - document.getElementById("login-throbber").hidden = stop; - let password = document.getElementById("existingPasswordFeedbackRow"); - let server = document.getElementById("existingServerFeedbackRow"); - let passphrase = document.getElementById("existingPassphraseFeedbackRow"); - - if (!stop || (Weave.Status.login == Weave.LOGIN_SUCCEEDED)) { - password.hidden = server.hidden = passphrase.hidden = true; - return; - } - - let feedback; - switch (Weave.Status.login) { - case Weave.LOGIN_FAILED_NETWORK_ERROR: - case Weave.LOGIN_FAILED_SERVER_ERROR: - feedback = server; - break; - case Weave.LOGIN_FAILED_LOGIN_REJECTED: - case Weave.LOGIN_FAILED_NO_USERNAME: - case Weave.LOGIN_FAILED_NO_PASSWORD: - feedback = password; - break; - case Weave.LOGIN_FAILED_INVALID_PASSPHRASE: - feedback = passphrase; - break; - } - this._setFeedbackMessage(feedback, false, Weave.Status.login); - }, - - setupInitialSync: function () { - let action = document.getElementById("mergeChoiceRadio").selectedItem.id; - switch (action) { - case "resetClient": - // if we're not resetting sync, we don't need to explicitly - // call resetClient - if (!this._resettingSync) - return; - // otherwise, fall through - case "wipeClient": - case "wipeRemote": - Weave.Svc.Prefs.set("firstSync", action); - break; - } - }, - - // fun with validation! - checkFields: function () { - this.wizard.canAdvance = this.readyToAdvance(); - }, - - readyToAdvance: function () { - switch (this.wizard.pageIndex) { - case INTRO_PAGE: - return false; - case NEW_ACCOUNT_START_PAGE: - for (let i in this.status) { - if (!this.status[i]) - return false; - } - if (this._usingMainServers) - return document.getElementById("tos").checked; - - return true; - case EXISTING_ACCOUNT_LOGIN_PAGE: - let hasUser = document.getElementById("existingAccountName").value != ""; - let hasPass = document.getElementById("existingPassword").value != ""; - let hasKey = document.getElementById("existingPassphrase").value != ""; - - if (hasUser && hasPass && hasKey) { - if (this._usingMainServers) - return true; - - if (this._validateServer(document.getElementById("existingServer"))) { - return true; - } - } - return false; - } - // Default, e.g. wizard's special page -1 etc. - return true; - }, - - onPINInput: function onPINInput(textbox) { - if (textbox && textbox.value.length == PIN_PART_LENGTH) { - this.nextFocusEl[textbox.id].focus(); - } - this.wizard.canAdvance = (this.pin1.value.length == PIN_PART_LENGTH && - this.pin2.value.length == PIN_PART_LENGTH && - this.pin3.value.length == PIN_PART_LENGTH); - }, - - onEmailInput: function () { - // Check account validity when the user stops typing for 1 second. - if (this._checkAccountTimer) - window.clearTimeout(this._checkAccountTimer); - this._checkAccountTimer = window.setTimeout(function () { - gSyncSetup.checkAccount(); - }, 1000); - }, - - checkAccount: function() { - delete this._checkAccountTimer; - let value = Weave.Utils.normalizeAccount( - document.getElementById("weaveEmail").value); - if (!value) { - this.status.email = false; - this.checkFields(); - return; - } - - let re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; - let feedback = document.getElementById("emailFeedbackRow"); - let valid = re.test(value); - - let str = ""; - if (!valid) { - str = "invalidEmail.label"; - } else { - let availCheck = Weave.Service.checkAccount(value); - valid = availCheck == "available"; - if (!valid) { - if (availCheck == "notAvailable") - str = "usernameNotAvailable.label"; - else - str = availCheck; - } - } - - this._setFeedbackMessage(feedback, valid, str); - this.status.email = valid; - if (valid) - Weave.Service.identity.account = value; - this.checkFields(); - }, - - onPasswordChange: function () { - let password = document.getElementById("weavePassword"); - let pwconfirm = document.getElementById("weavePasswordConfirm"); - let [valid, errorString] = gSyncUtils.validatePassword(password, pwconfirm); - - let feedback = document.getElementById("passwordFeedbackRow"); - this._setFeedback(feedback, valid, errorString); - - this.status.password = valid; - this.checkFields(); - }, - - onPageShow: function() { - switch (this.wizard.pageIndex) { - case PAIR_PAGE: - this.wizard.getButton("back").hidden = true; - this.wizard.getButton("extra1").hidden = true; - this.onPINInput(); - this.pin1.focus(); - break; - case INTRO_PAGE: - // We may not need the captcha in the Existing Account branch of the - // wizard. However, we want to preload it to avoid any flickering while - // the Create Account page is shown. - this.loadCaptcha(); - this.wizard.getButton("next").hidden = true; - this.wizard.getButton("back").hidden = true; - this.wizard.getButton("extra1").hidden = true; - this.checkFields(); - break; - case NEW_ACCOUNT_START_PAGE: - this.wizard.getButton("extra1").hidden = false; - this.wizard.getButton("next").hidden = false; - this.wizard.getButton("back").hidden = false; - this.onServerCommand(); - this.wizard.canRewind = true; - this.checkFields(); - break; - case EXISTING_ACCOUNT_CONNECT_PAGE: - Weave.Svc.Prefs.set("firstSync", "existingAccount"); - this.wizard.getButton("next").hidden = false; - this.wizard.getButton("back").hidden = false; - this.wizard.getButton("extra1").hidden = false; - this.wizard.canAdvance = false; - this.wizard.canRewind = true; - this.startEasySetup(); - break; - case EXISTING_ACCOUNT_LOGIN_PAGE: - this.wizard.getButton("next").hidden = false; - this.wizard.getButton("back").hidden = false; - this.wizard.getButton("extra1").hidden = false; - this.wizard.canRewind = true; - this.checkFields(); - break; - case OPTIONS_PAGE: - this.wizard.canRewind = false; - this.wizard.canAdvance = true; - if (!this._resettingSync) { - this.wizard.getButton("next").label = - this._stringBundle.GetStringFromName("button.syncOptionsDone.label"); - this.wizard.getButton("next").removeAttribute("accesskey"); - } - this.wizard.getButton("next").hidden = false; - this.wizard.getButton("back").hidden = true; - this.wizard.getButton("cancel").hidden = !this._resettingSync; - this.wizard.getButton("extra1").hidden = true; - document.getElementById("syncComputerName").value = Weave.Service.clientsEngine.localName; - document.getElementById("syncOptions").collapsed = this._resettingSync; - document.getElementById("mergeOptions").collapsed = this._settingUpNew; - break; - case OPTIONS_CONFIRM_PAGE: - this.wizard.canRewind = true; - this.wizard.canAdvance = true; - this.wizard.getButton("back").label = - this._stringBundle.GetStringFromName("button.syncOptionsCancel.label"); - this.wizard.getButton("back").removeAttribute("accesskey"); - this.wizard.getButton("back").hidden = this._resettingSync; - this.wizard.getButton("next").hidden = false; - this.wizard.getButton("finish").hidden = true; - break; - } - }, - - onWizardAdvance: function () { - // Check pageIndex so we don't prompt before the Sync setup wizard appears. - // This is a fallback in case the Master Password gets locked mid-wizard. - if ((this.wizard.pageIndex >= 0) && - !Weave.Utils.ensureMPUnlocked()) { - return false; - } - - switch (this.wizard.pageIndex) { - case PAIR_PAGE: - this.startPairing(); - return false; - case NEW_ACCOUNT_START_PAGE: - // If the user selects Next (e.g. by hitting enter) when we haven't - // executed the delayed checks yet, execute them immediately. - if (this._checkAccountTimer) { - this.checkAccount(); - } - if (this._checkServerTimer) { - this.checkServer(); - } - if (!this.wizard.canAdvance) { - return false; - } - - let doc = this.captchaBrowser.contentDocument; - let getField = function getField(field) { - let node = doc.getElementById("recaptcha_" + field + "_field"); - return node && node.value; - }; - - // Display throbber - let feedback = document.getElementById("captchaFeedback"); - let image = feedback.firstChild; - let label = image.nextSibling; - image.setAttribute("status", "active"); - label.value = this._stringBundle.GetStringFromName("verifying.label"); - setVisibility(feedback, true); - - let password = document.getElementById("weavePassword").value; - let email = Weave.Utils.normalizeAccount( - document.getElementById("weaveEmail").value); - let challenge = getField("challenge"); - let response = getField("response"); - - let error = Weave.Service.createAccount(email, password, - challenge, response); - - if (error == null) { - Weave.Service.identity.account = email; - Weave.Service.identity.basicPassword = password; - Weave.Service.identity.syncKey = Weave.Utils.generatePassphrase(); - this._handleNoScript(false); - Weave.Svc.Prefs.set("firstSync", "newAccount"); - this.wizardFinish(); - return false; - } - - image.setAttribute("status", "error"); - label.value = Weave.Utils.getErrorString(error); - return false; - case EXISTING_ACCOUNT_LOGIN_PAGE: - Weave.Service.identity.account = Weave.Utils.normalizeAccount( - document.getElementById("existingAccountName").value); - Weave.Service.identity.basicPassword = - document.getElementById("existingPassword").value; - let pp = document.getElementById("existingPassphrase").value; - Weave.Service.identity.syncKey = Weave.Utils.normalizePassphrase(pp); - if (Weave.Service.login()) { - this.wizardFinish(); - } - return false; - case OPTIONS_PAGE: - let desc = document.getElementById("mergeChoiceRadio").selectedIndex; - // No confirmation needed on new account setup or merge option - // with existing account. - if (this._settingUpNew || (!this._resettingSync && desc == 0)) - return this.returnFromOptions(); - return this._handleChoice(); - case OPTIONS_CONFIRM_PAGE: - if (this._resettingSync) { - this.wizardFinish(); - return false; - } - return this.returnFromOptions(); - } - return true; - }, - - onWizardBack: function () { - switch (this.wizard.pageIndex) { - case NEW_ACCOUNT_START_PAGE: - this.wizard.pageIndex = INTRO_PAGE; - return false; - case EXISTING_ACCOUNT_CONNECT_PAGE: - this.abortEasySetup(); - this.wizard.pageIndex = INTRO_PAGE; - return false; - case EXISTING_ACCOUNT_LOGIN_PAGE: - // If we were already pairing on entry, we went straight to the manual - // login page. If subsequently we go back, return to the page that lets - // us choose whether we already have an account. - if (this.wizardType == "pair") { - this.wizard.pageIndex = INTRO_PAGE; - return false; - } - return true; - case OPTIONS_CONFIRM_PAGE: - // Backing up from the confirmation page = resetting first sync to merge. - document.getElementById("mergeChoiceRadio").selectedIndex = 0; - return this.returnFromOptions(); - } - return true; - }, - - wizardFinish: function () { - this.setupInitialSync(); - - if (this.wizardType == "pair") { - this.completePairing(); - } - - if (!this._resettingSync) { - function isChecked(element) { - return document.getElementById(element).hasAttribute("checked"); - } - - let prefs = ["engine.bookmarks", "engine.passwords", "engine.history", - "engine.tabs", "engine.prefs", "engine.addons"]; - for (let i = 0;i < prefs.length;i++) { - Weave.Svc.Prefs.set(prefs[i], isChecked(prefs[i])); - } - this._handleNoScript(false); - if (Weave.Svc.Prefs.get("firstSync", "") == "notReady") - Weave.Svc.Prefs.reset("firstSync"); - - Weave.Service.persistLogin(); - Weave.Svc.Obs.notify("weave:service:setup-complete"); - } - Weave.Utils.nextTick(Weave.Service.sync, Weave.Service); - window.close(); - }, - - onWizardCancel: function () { - if (this._resettingSync) - return; - - this.abortEasySetup(); - this._handleNoScript(false); - Weave.Service.startOver(); - }, - - onSyncOptions: function () { - this._beforeOptionsPage = this.wizard.pageIndex; - this.wizard.pageIndex = OPTIONS_PAGE; - }, - - returnFromOptions: function() { - this.wizard.getButton("next").label = this._nextButtonLabel; - this.wizard.getButton("next").setAttribute("accesskey", - this._nextButtonAccesskey); - this.wizard.getButton("back").label = this._backButtonLabel; - this.wizard.getButton("back").setAttribute("accesskey", - this._backButtonAccesskey); - this.wizard.getButton("cancel").hidden = false; - this.wizard.getButton("extra1").hidden = false; - this.wizard.pageIndex = this._beforeOptionsPage; - return false; - }, - - startPairing: function startPairing() { - this.pairDeviceErrorRow.hidden = true; - // When onAbort is called, Weave may already be gone. - const JPAKE_ERROR_USERABORT = Weave.JPAKE_ERROR_USERABORT; - - let self = this; - let jpakeclient = this._jpakeclient = new Weave.JPAKEClient({ - onPaired: function onPaired() { - self.wizard.pageIndex = INTRO_PAGE; - }, - onComplete: function onComplete() { - // This method will never be called since SendCredentialsController - // will take over after the wizard completes. - }, - onAbort: function onAbort(error) { - delete self._jpakeclient; - - // Aborted by user, ignore. The window is almost certainly going to close - // or is already closed. - if (error == JPAKE_ERROR_USERABORT) { - return; - } - - self.pairDeviceErrorRow.hidden = false; - self.pairDeviceThrobber.hidden = true; - self.pin1.value = self.pin2.value = self.pin3.value = ""; - self.pin1.disabled = self.pin2.disabled = self.pin3.disabled = false; - if (self.wizard.pageIndex == PAIR_PAGE) { - self.pin1.focus(); - } - } - }); - this.pairDeviceThrobber.hidden = false; - this.pin1.disabled = this.pin2.disabled = this.pin3.disabled = true; - this.wizard.canAdvance = false; - - let pin = this.pin1.value + this.pin2.value + this.pin3.value; - let expectDelay = true; - jpakeclient.pairWithPIN(pin, expectDelay); - }, - - completePairing: function completePairing() { - if (!this._jpakeclient) { - // The channel was aborted while we were setting up the account - // locally. XXX TODO should we do anything here, e.g. tell - // the user on the last wizard page that it's ok, they just - // have to pair again? - return; - } - let controller = new Weave.SendCredentialsController(this._jpakeclient, - Weave.Service); - this._jpakeclient.controller = controller; - }, - - startEasySetup: function () { - // Don't do anything if we have a client already (e.g. we went to - // Sync Options and just came back). - if (this._jpakeclient) - return; - - // When onAbort is called, Weave may already be gone - const JPAKE_ERROR_USERABORT = Weave.JPAKE_ERROR_USERABORT; - - let self = this; - this._jpakeclient = new Weave.JPAKEClient({ - displayPIN: function displayPIN(pin) { - document.getElementById("easySetupPIN1").value = pin.slice(0, 4); - document.getElementById("easySetupPIN2").value = pin.slice(4, 8); - document.getElementById("easySetupPIN3").value = pin.slice(8); - }, - - onPairingStart: function onPairingStart() {}, - - onComplete: function onComplete(credentials) { - Weave.Service.identity.account = credentials.account; - Weave.Service.identity.basicPassword = credentials.password; - Weave.Service.identity.syncKey = credentials.synckey; - Weave.Service.serverURL = credentials.serverURL; - gSyncSetup.wizardFinish(); - }, - - onAbort: function onAbort(error) { - delete self._jpakeclient; - - // Ignore if wizard is aborted. - if (error == JPAKE_ERROR_USERABORT) - return; - - // Automatically go to manual setup if we couldn't acquire a channel. - if (error == Weave.JPAKE_ERROR_CHANNEL) { - self.wizard.pageIndex = EXISTING_ACCOUNT_LOGIN_PAGE; - return; - } - - // Restart on all other errors. - self.startEasySetup(); - } - }); - this._jpakeclient.receiveNoPIN(); - }, - - abortEasySetup: function () { - document.getElementById("easySetupPIN1").value = ""; - document.getElementById("easySetupPIN2").value = ""; - document.getElementById("easySetupPIN3").value = ""; - if (!this._jpakeclient) - return; - - this._jpakeclient.abort(); - delete this._jpakeclient; - }, - - manualSetup: function () { - this.abortEasySetup(); - this.wizard.pageIndex = EXISTING_ACCOUNT_LOGIN_PAGE; - }, - - // _handleNoScript is needed because it blocks the captcha. So we temporarily - // allow the necessary sites so that we can verify the user is in fact a human. - // This was done with the help of Giorgio (NoScript author). See bug 508112. - _handleNoScript: function (addExceptions) { - // if NoScript isn't installed, or is disabled, bail out. - let ns = Cc["@maone.net/noscript-service;1"]; - if (ns == null) - return; - - ns = ns.getService().wrappedJSObject; - if (addExceptions) { - this._remoteSites.forEach(function(site) { - site = ns.getSite(site); - if (!ns.isJSEnabled(site)) { - this._disabledSites.push(site); // save status - ns.setJSEnabled(site, true); // allow site - } - }, this); - } - else { - this._disabledSites.forEach(function(site) { - ns.setJSEnabled(site, false); - }); - this._disabledSites = []; - } - }, - - onExistingServerCommand: function () { - let control = document.getElementById("existingServer"); - if (control.selectedIndex == 0) { - control.removeAttribute("editable"); - Weave.Svc.Prefs.reset("serverURL"); - } else { - control.setAttribute("editable", "true"); - // Force a style flush to ensure that the binding is attached. - control.clientTop; - control.value = ""; - control.inputField.focus(); - } - document.getElementById("existingServerFeedbackRow").hidden = true; - this.checkFields(); - }, - - onExistingServerInput: function () { - // Check custom server validity when the user stops typing for 1 second. - if (this._existingServerTimer) - window.clearTimeout(this._existingServerTimer); - this._existingServerTimer = window.setTimeout(function () { - gSyncSetup.checkFields(); - }, 1000); - }, - - onServerCommand: function () { - setVisibility(document.getElementById("TOSRow"), this._usingMainServers); - let control = document.getElementById("server"); - if (!this._usingMainServers) { - control.setAttribute("editable", "true"); - // Force a style flush to ensure that the binding is attached. - control.clientTop; - control.value = ""; - control.inputField.focus(); - // checkServer() will call checkAccount() and checkFields(). - this.checkServer(); - return; - } - control.removeAttribute("editable"); - Weave.Svc.Prefs.reset("serverURL"); - if (this._settingUpNew) { - this.loadCaptcha(); - } - this.checkAccount(); - this.status.server = true; - document.getElementById("serverFeedbackRow").hidden = true; - this.checkFields(); - }, - - onServerInput: function () { - // Check custom server validity when the user stops typing for 1 second. - if (this._checkServerTimer) - window.clearTimeout(this._checkServerTimer); - this._checkServerTimer = window.setTimeout(function () { - gSyncSetup.checkServer(); - }, 1000); - }, - - checkServer: function () { - delete this._checkServerTimer; - let el = document.getElementById("server"); - let valid = false; - let feedback = document.getElementById("serverFeedbackRow"); - if (el.value) { - valid = this._validateServer(el); - let str = valid ? "" : "serverInvalid.label"; - this._setFeedbackMessage(feedback, valid, str); - } - else - this._setFeedbackMessage(feedback, true); - - // Recheck account against the new server. - if (valid) - this.checkAccount(); - - this.status.server = valid; - this.checkFields(); - }, - - _validateServer: function (element) { - let valid = false; - let val = element.value; - if (!val) - return false; - - let uri = Weave.Utils.makeURI(val); - - if (!uri) - uri = Weave.Utils.makeURI("https://" + val); - - if (uri && this._settingUpNew) { - function isValid(uri) { - Weave.Service.serverURL = uri.spec; - let check = Weave.Service.checkAccount("a"); - return (check == "available" || check == "notAvailable"); - } - - if (uri.schemeIs("http")) { - uri.scheme = "https"; - if (isValid(uri)) - valid = true; - else - // setting the scheme back to http - uri.scheme = "http"; - } - if (!valid) - valid = isValid(uri); - - if (valid) { - this.loadCaptcha(); - } - } - else if (uri) { - valid = true; - Weave.Service.serverURL = uri.spec; - } - - if (valid) - element.value = Weave.Service.serverURL; - else - Weave.Svc.Prefs.reset("serverURL"); - - return valid; - }, - - _handleChoice: function () { - let desc = document.getElementById("mergeChoiceRadio").selectedIndex; - document.getElementById("chosenActionDeck").selectedIndex = desc; - switch (desc) { - case 1: - if (this._case1Setup) - break; - - let places_db = PlacesUtils.history - .QueryInterface(Ci.nsPIPlacesDatabase) - .DBConnection; - if (Weave.Service.engineManager.get("history").enabled) { - let daysOfHistory = 0; - let stm = places_db.createStatement( - "SELECT ROUND(( " + - "strftime('%s','now','localtime','utc') - " + - "( " + - "SELECT visit_date FROM moz_historyvisits " + - "ORDER BY visit_date ASC LIMIT 1 " + - ")/1000000 " + - ")/86400) AS daysOfHistory "); - - if (stm.step()) - daysOfHistory = stm.getInt32(0); - // Support %S for historical reasons (see bug 600141) - document.getElementById("historyCount").value = - PluralForm.get(daysOfHistory, - this._stringBundle.GetStringFromName("historyDaysCount.label")) - .replace("%S", daysOfHistory) - .replace("#1", daysOfHistory); - } else { - document.getElementById("historyCount").hidden = true; - } - - if (Weave.Service.engineManager.get("bookmarks").enabled) { - let bookmarks = 0; - let stm = places_db.createStatement( - "SELECT count(*) AS bookmarks " + - "FROM moz_bookmarks b " + - "LEFT JOIN moz_bookmarks t ON " + - "b.parent = t.id WHERE b.type = 1 AND t.parent <> :tag"); - stm.params.tag = PlacesUtils.tagsFolderId; - if (stm.executeStep()) - bookmarks = stm.row.bookmarks; - // Support %S for historical reasons (see bug 600141) - document.getElementById("bookmarkCount").value = - PluralForm.get(bookmarks, - this._stringBundle.GetStringFromName("bookmarksCount.label")) - .replace("%S", bookmarks) - .replace("#1", bookmarks); - } else { - document.getElementById("bookmarkCount").hidden = true; - } - - if (Weave.Service.engineManager.get("passwords").enabled) { - let logins = Services.logins.getAllLogins({}); - // Support %S for historical reasons (see bug 600141) - document.getElementById("passwordCount").value = - PluralForm.get(logins.length, - this._stringBundle.GetStringFromName("passwordsCount.label")) - .replace("%S", logins.length) - .replace("#1", logins.length); - } else { - document.getElementById("passwordCount").hidden = true; - } - - if (!Weave.Service.engineManager.get("prefs").enabled) { - document.getElementById("prefsWipe").hidden = true; - } - - let addonsEngine = Weave.Service.engineManager.get("addons"); - if (addonsEngine.enabled) { - let ids = addonsEngine._store.getAllIDs(); - let blessedcount = Object.keys(ids).filter(id => ids[id]).length; - // bug 600141 does not apply, as this does not have to support existing strings - document.getElementById("addonCount").value = - PluralForm.get(blessedcount, - this._stringBundle.GetStringFromName("addonsCount.label")) - .replace("#1", blessedcount); - } else { - document.getElementById("addonCount").hidden = true; - } - - this._case1Setup = true; - break; - case 2: - if (this._case2Setup) - break; - let count = 0; - function appendNode(label) { - let box = document.getElementById("clientList"); - let node = document.createElement("label"); - node.setAttribute("value", label); - node.setAttribute("class", "data indent"); - box.appendChild(node); - } - - for (let name of Weave.Service.clientsEngine.stats.names) { - // Don't list the current client - if (name == Weave.Service.clientsEngine.localName) - continue; - - // Only show the first several client names - if (++count <= 5) - appendNode(name); - } - if (count > 5) { - // Support %S for historical reasons (see bug 600141) - let label = - PluralForm.get(count - 5, - this._stringBundle.GetStringFromName("additionalClientCount.label")) - .replace("%S", count - 5) - .replace("#1", count - 5); - appendNode(label); - } - this._case2Setup = true; - break; - } - - return true; - }, - - // sets class and string on a feedback element - // if no property string is passed in, we clear label/style - _setFeedback: function (element, success, string) { - element.hidden = success || !string; - let classname = success ? "success" : "error"; - let image = element.getElementsByAttribute("class", "statusIcon")[0]; - image.setAttribute("status", classname); - let label = element.getElementsByAttribute("class", "status")[0]; - label.value = string; - }, - - // shim - _setFeedbackMessage: function (element, success, string) { - let str = ""; - if (string) { - try { - str = this._stringBundle.GetStringFromName(string); - } catch (e) {} - - if (!str) - str = Weave.Utils.getErrorString(string); - } - this._setFeedback(element, success, str); - }, - - loadCaptcha: function loadCaptcha() { - let captchaURI = Weave.Service.miscAPI + "captcha_html"; - // First check for NoScript and whitelist the right sites. - this._handleNoScript(true); - if (this.captchaBrowser.currentURI.spec != captchaURI) { - this.captchaBrowser.loadURI(captchaURI); - } - }, - - onStateChange: function(webProgress, request, stateFlags, status) { - // We're only looking for the end of the frame load - if ((stateFlags & Ci.nsIWebProgressListener.STATE_STOP) == 0) - return; - if ((stateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK) == 0) - return; - if ((stateFlags & Ci.nsIWebProgressListener.STATE_IS_WINDOW) == 0) - return; - - // If we didn't find a captcha, assume it's not needed and don't show it. - let responseStatus = request.QueryInterface(Ci.nsIHttpChannel).responseStatus; - setVisibility(this.captchaBrowser, responseStatus != 404); - // XXX TODO we should really log any responseStatus other than 200 - }, - onProgressChange: function() {}, - onStatusChange: function() {}, - onSecurityChange: function() {}, - onLocationChange: function () {} -}; - -// Define lazy getters for various XUL elements. -// -// onWizardAdvance() and onPageShow() are run before init(), so we'll even -// define things that will almost certainly be used (like 'wizard') as a lazy -// getter here. -["wizard", - "pin1", - "pin2", - "pin3", - "pairDeviceErrorRow", - "pairDeviceThrobber"].forEach(function (id) { - XPCOMUtils.defineLazyGetter(gSyncSetup, id, function() { - return document.getElementById(id); - }); -}); -XPCOMUtils.defineLazyGetter(gSyncSetup, "nextFocusEl", function () { - return {pin1: this.pin2, - pin2: this.pin3, - pin3: this.wizard.getButton("next")}; -}); -XPCOMUtils.defineLazyGetter(gSyncSetup, "_stringBundle", function() { - return Services.strings.createBundle("chrome://browser/locale/syncSetup.properties"); -}); diff --git a/application/basilisk/base/content/sync/setup.xul b/application/basilisk/base/content/sync/setup.xul deleted file mode 100644 index 11c085931..000000000 --- a/application/basilisk/base/content/sync/setup.xul +++ /dev/null @@ -1,490 +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/. --> - -<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> -<?xml-stylesheet href="chrome://browser/skin/syncSetup.css" type="text/css"?> -<?xml-stylesheet href="chrome://browser/skin/syncCommon.css" type="text/css"?> - -<!DOCTYPE window [ -<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd"> -<!ENTITY % syncBrandDTD SYSTEM "chrome://browser/locale/syncBrand.dtd"> -<!ENTITY % syncSetupDTD SYSTEM "chrome://browser/locale/syncSetup.dtd"> -%brandDTD; -%syncBrandDTD; -%syncSetupDTD; -]> -<wizard id="wizard" - title="&accountSetupTitle.label;" - windowtype="Weave:AccountSetup" - persist="screenX screenY" - xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" - xmlns:html="http://www.w3.org/1999/xhtml" - onwizardnext="return gSyncSetup.onWizardAdvance()" - onwizardback="return gSyncSetup.onWizardBack()" - onwizardcancel="gSyncSetup.onWizardCancel()" - onload="gSyncSetup.init()"> - - <script type="application/javascript" - src="chrome://browser/content/sync/setup.js"/> - <script type="application/javascript" - src="chrome://browser/content/sync/utils.js"/> - <script type="application/javascript" - src="chrome://browser/content/utilityOverlay.js"/> - <script type="application/javascript" - src="chrome://global/content/printUtils.js"/> - - <wizardpage id="addDevicePage" - label="&pairDevice.title.label;" - onpageshow="gSyncSetup.onPageShow()"> - <description> - &pairDevice.dialog.description.label; - <label class="text-link" - value="&addDevice.showMeHow.label;" - href="https://services.mozilla.com/sync/help/add-device"/> - </description> - <separator class="groove-thin"/> - <description> - &addDevice.dialog.enterCode.label; - </description> - <separator class="groove-thin"/> - <vbox align="center"> - <textbox id="pin1" - class="pin" - oninput="gSyncSetup.onPINInput(this);" - onfocus="this.select();" - /> - <textbox id="pin2" - class="pin" - oninput="gSyncSetup.onPINInput(this);" - onfocus="this.select();" - /> - <textbox id="pin3" - class="pin" - oninput="gSyncSetup.onPINInput(this);" - onfocus="this.select();" - /> - </vbox> - <separator class="groove-thin"/> - <vbox id="pairDeviceThrobber" align="center" hidden="true"> - <image/> - </vbox> - <hbox id="pairDeviceErrorRow" pack="center" hidden="true"> - <image class="statusIcon" status="error"/> - <label class="status" - value="&addDevice.dialog.tryAgain.label;"/> - </hbox> - </wizardpage> - - <wizardpage id="pickSetupType" - label="&syncBrand.fullName.label;" - onpageshow="gSyncSetup.onPageShow()"> - <vbox align="center" flex="1"> - <description style="padding: 0 7em;"> - &setup.pickSetupType.description2; - </description> - <spacer flex="3"/> - <button id="newAccount" - class="accountChoiceButton" - label="&button.createNewAccount.label;" - oncommand="gSyncSetup.startNewAccountSetup()" - align="center"/> - <spacer flex="1"/> - </vbox> - <separator class="groove"/> - <vbox align="center" flex="1"> - <spacer flex="1"/> - <button id="existingAccount" - class="accountChoiceButton" - label="&button.haveAccount.label;" - oncommand="gSyncSetup.useExistingAccount()"/> - <spacer flex="3"/> - </vbox> - </wizardpage> - - <wizardpage label="&setup.newAccountDetailsPage.title.label;" - id="newAccountStart" - onextra1="gSyncSetup.onSyncOptions()" - onpageshow="gSyncSetup.onPageShow();"> - <grid> - <columns> - <column/> - <column class="inputColumn" flex="1"/> - </columns> - <rows> - <row id="emailRow" align="center"> - <label value="&setup.emailAddress.label;" - accesskey="&setup.emailAddress.accesskey;" - control="weaveEmail"/> - <textbox id="weaveEmail" - oninput="gSyncSetup.onEmailInput()"/> - </row> - <row id="emailFeedbackRow" align="center" hidden="true"> - <spacer/> - <hbox> - <image class="statusIcon"/> - <label class="status" value=" "/> - </hbox> - </row> - <row id="passwordRow" align="center"> - <label value="&setup.choosePassword.label;" - accesskey="&setup.choosePassword.accesskey;" - control="weavePassword"/> - <textbox id="weavePassword" - type="password" - onchange="gSyncSetup.onPasswordChange()"/> - </row> - <row id="confirmRow" align="center"> - <label value="&setup.confirmPassword.label;" - accesskey="&setup.confirmPassword.accesskey;" - control="weavePasswordConfirm"/> - <textbox id="weavePasswordConfirm" - type="password" - onchange="gSyncSetup.onPasswordChange()"/> - </row> - <row id="passwordFeedbackRow" align="center" hidden="true"> - <spacer/> - <hbox> - <image class="statusIcon"/> - <label class="status" value=" "/> - </hbox> - </row> - <row align="center"> - <label control="server" - value="&server.label;"/> - <menulist id="server" - oncommand="gSyncSetup.onServerCommand()" - oninput="gSyncSetup.onServerInput()"> - <menupopup> - <menuitem label="&serverType.default.label;" - value="main"/> - <menuitem label="&serverType.custom2.label;" - value="custom"/> - </menupopup> - </menulist> - </row> - <row id="serverFeedbackRow" align="center" hidden="true"> - <spacer/> - <hbox> - <image class="statusIcon"/> - <label class="status" value=" "/> - </hbox> - </row> - <row id="TOSRow" align="center"> - <spacer/> - <hbox align="center"> - <checkbox id="tos" - accesskey="&setup.tosAgree1.accesskey;" - oncommand="this.focus(); gSyncSetup.checkFields();"/> - <description id="tosDesc" - flex="1" - onclick="document.getElementById('tos').focus(); - document.getElementById('tos').click()"> - &setup.tosAgree1.label; - <label class="text-link" - onclick="event.stopPropagation();gSyncUtils.openToS();"> - &setup.tosLink.label; - </label> - &setup.tosAgree2.label; - <label class="text-link" - onclick="event.stopPropagation();gSyncUtils.openPrivacyPolicy();"> - &setup.ppLink.label; - </label> - &setup.tosAgree3.label; - </description> - </hbox> - </row> - </rows> - </grid> - <spacer flex="1"/> - <vbox flex="1" align="center"> - <browser height="150" - width="500" - id="captcha" - type="content" - disablehistory="true"/> - <spacer flex="1"/> - <hbox id="captchaFeedback"> - <image class="statusIcon"/> - <label class="status" value=" "/> - </hbox> - </vbox> - </wizardpage> - - <wizardpage id="addDevice" - label="&pairDevice.title.label;" - onextra1="gSyncSetup.onSyncOptions()" - onpageshow="gSyncSetup.onPageShow()"> - <description> - &pairDevice.setup.description.label; - <label class="text-link" - value="&addDevice.showMeHow.label;" - href="https://services.mozilla.com/sync/help/easy-setup"/> - </description> - <label value="&addDevice.setup.enterCode.label;" - control="easySetupPIN1"/> - <spacer flex="1"/> - <vbox align="center" flex="1"> - <textbox id="easySetupPIN1" - class="pin" - value="" - readonly="true" - /> - <textbox id="easySetupPIN2" - class="pin" - value="" - readonly="true" - /> - <textbox id="easySetupPIN3" - class="pin" - value="" - readonly="true" - /> - </vbox> - <spacer flex="3"/> - <label class="text-link" - value="&addDevice.dontHaveDevice.label;" - onclick="gSyncSetup.manualSetup();"/> - </wizardpage> - - <wizardpage id="existingAccount" - label="&setup.signInPage.title.label;" - onextra1="gSyncSetup.onSyncOptions()" - onpageshow="gSyncSetup.onPageShow()"> - <grid> - <columns> - <column/> - <column class="inputColumn" flex="1"/> - </columns> - <rows> - <row id="existingAccountRow" align="center"> - <label id="existingAccountLabel" - value="&signIn.account2.label;" - accesskey="&signIn.account2.accesskey;" - control="existingAccount"/> - <textbox id="existingAccountName" - oninput="gSyncSetup.checkFields(event)" - onchange="gSyncSetup.checkFields(event)"/> - </row> - <row id="existingPasswordRow" align="center"> - <label id="existingPasswordLabel" - value="&signIn.password.label;" - accesskey="&signIn.password.accesskey;" - control="existingPassword"/> - <textbox id="existingPassword" - type="password" - onkeyup="gSyncSetup.checkFields(event)" - onchange="gSyncSetup.checkFields(event)"/> - </row> - <row id="existingPasswordFeedbackRow" align="center" hidden="true"> - <spacer/> - <hbox> - <image class="statusIcon"/> - <label class="status" value=" "/> - </hbox> - </row> - <row align="center"> - <spacer/> - <label class="text-link" - value="&resetPassword.label;" - onclick="gSyncUtils.resetPassword(); return false;"/> - </row> - <row align="center"> - <label control="existingServer" - value="&server.label;"/> - <menulist id="existingServer" - oncommand="gSyncSetup.onExistingServerCommand()" - oninput="gSyncSetup.onExistingServerInput()"> - <menupopup> - <menuitem label="&serverType.default.label;" - value="main"/> - <menuitem label="&serverType.custom2.label;" - value="custom"/> - </menupopup> - </menulist> - </row> - <row id="existingServerFeedbackRow" align="center" hidden="true"> - <spacer/> - <hbox> - <image class="statusIcon"/> - <vbox> - <label class="status" value=" "/> - </vbox> - </hbox> - </row> - </rows> - </grid> - - <groupbox> - <label id="existingPassphraseLabel" - value="&signIn.recoveryKey.label;" - accesskey="&signIn.recoveryKey.accesskey;" - control="existingPassphrase"/> - <textbox id="existingPassphrase" - oninput="gSyncSetup.checkFields()"/> - <hbox id="login-throbber" hidden="true"> - <image/> - <label value="&verifying.label;"/> - </hbox> - <vbox align="left" id="existingPassphraseFeedbackRow" hidden="true"> - <hbox> - <image class="statusIcon"/> - <label class="status" value=" "/> - </hbox> - </vbox> - </groupbox> - - <vbox id="passphraseHelpBox"> - <description> - &existingRecoveryKey.description; - <label class="text-link" - href="https://services.mozilla.com/sync/help/manual-setup"> - &addDevice.showMeHow.label; - </label> - <spacer id="passphraseHelpSpacer"/> - <label class="text-link" - onclick="gSyncSetup.resetPassphrase(); return false;"> - &resetSyncKey.label; - </label> - </description> - </vbox> - </wizardpage> - - <wizardpage id="syncOptionsPage" - label="&setup.optionsPage.title;" - onpageshow="gSyncSetup.onPageShow()"> - <groupbox id="syncOptions"> - <grid> - <columns> - <column/> - <column flex="1" style="margin-inline-end: 2px"/> - </columns> - <rows> - <row align="center"> - <label value="&syncDeviceName.label;" - accesskey="&syncDeviceName.accesskey;" - control="syncComputerName"/> - <textbox id="syncComputerName" flex="1" - onchange="gSyncUtils.changeName(this)"/> - </row> - <row> - <label value="&syncMy.label;" /> - <vbox> - <checkbox label="&engine.addons.label;" - accesskey="&engine.addons.accesskey;" - id="engine.addons" - checked="true"/> - <checkbox label="&engine.bookmarks.label;" - accesskey="&engine.bookmarks.accesskey;" - id="engine.bookmarks" - checked="true"/> - <checkbox label="&engine.passwords.label;" - accesskey="&engine.passwords.accesskey;" - id="engine.passwords" - checked="true"/> - <checkbox label="&engine.prefs.label;" - accesskey="&engine.prefs.accesskey;" - id="engine.prefs" - checked="true"/> - <checkbox label="&engine.history.label;" - accesskey="&engine.history.accesskey;" - id="engine.history" - checked="true"/> - <checkbox label="&engine.tabs.label;" - accesskey="&engine.tabs.accesskey;" - id="engine.tabs" - checked="true"/> - </vbox> - </row> - </rows> - </grid> - </groupbox> - - <groupbox id="mergeOptions"> - <radiogroup id="mergeChoiceRadio" pack="start"> - <grid> - <columns> - <column/> - <column flex="1"/> - </columns> - <rows flex="1"> - <row align="center"> - <radio id="resetClient" - class="mergeChoiceButton" - aria-labelledby="resetClientLabel"/> - <label id="resetClientLabel" control="resetClient"> - <html:strong>&choice2.merge.recommended.label;</html:strong> - &choice2a.merge.main.label; - </label> - </row> - <row align="center"> - <radio id="wipeClient" - class="mergeChoiceButton" - aria-labelledby="wipeClientLabel"/> - <label id="wipeClientLabel" - control="wipeClient"> - &choice2a.client.main.label; - </label> - </row> - <row align="center"> - <radio id="wipeRemote" - class="mergeChoiceButton" - aria-labelledby="wipeRemoteLabel"/> - <label id="wipeRemoteLabel" - control="wipeRemote"> - &choice2a.server.main.label; - </label> - </row> - </rows> - </grid> - </radiogroup> - </groupbox> - </wizardpage> - - <wizardpage id="syncOptionsConfirm" - label="&setup.optionsConfirmPage.title;" - onpageshow="gSyncSetup.onPageShow()"> - <deck id="chosenActionDeck"> - <vbox id="chosenActionMerge" class="confirm"> - <description class="normal"> - &confirm.merge2.label; - </description> - </vbox> - <vbox id="chosenActionWipeClient" class="confirm"> - <description class="normal"> - &confirm.client3.label; - </description> - <separator class="thin"/> - <vbox id="dataList"> - <label class="data indent" id="bookmarkCount"/> - <label class="data indent" id="historyCount"/> - <label class="data indent" id="passwordCount"/> - <label class="data indent" id="addonCount"/> - <label class="data indent" id="prefsWipe" - value="&engine.prefs.label;"/> - </vbox> - <separator class="thin"/> - <description class="normal"> - &confirm.client2.moreinfo.label; - </description> - </vbox> - <vbox id="chosenActionWipeServer" class="confirm"> - <description class="normal"> - &confirm.server2.label; - </description> - <separator class="thin"/> - <vbox id="clientList"> - </vbox> - </vbox> - </deck> - </wizardpage> - <!-- In terms of the wizard flow shown to the user, the 'syncOptionsConfirm' - page above is not the last wizard page. To prevent the wizard binding from - assuming that it is, we're inserting this dummy page here. This also means - that the wizard needs to always be closed manually via wizardFinish(). --> - <wizardpage> - </wizardpage> -</wizard> - diff --git a/application/basilisk/base/content/sync/utils.js b/application/basilisk/base/content/sync/utils.js deleted file mode 100644 index 92981f7b4..000000000 --- a/application/basilisk/base/content/sync/utils.js +++ /dev/null @@ -1,231 +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/. */ - -// Equivalent to 0o600 permissions; used for saved Sync Recovery Key. -// This constant can be replaced when the equivalent values are available to -// chrome JS; see Bug 433295 and Bug 757351. -const PERMISSIONS_RWUSR = 0x180; - -// Weave should always exist before before this file gets included. -var gSyncUtils = { - get bundle() { - delete this.bundle; - return this.bundle = Services.strings.createBundle("chrome://browser/locale/syncSetup.properties"); - }, - - get fxAccountsEnabled() { - let service = Components.classes["@mozilla.org/weave/service;1"] - .getService(Components.interfaces.nsISupports) - .wrappedJSObject; - return service.fxAccountsEnabled; - }, - - // opens in a new window if we're in a modal prefwindow world, in a new tab otherwise - _openLink: function (url) { - let thisDocEl = document.documentElement, - openerDocEl = window.opener && window.opener.document.documentElement; - if (thisDocEl.id == "accountSetup" && window.opener && - openerDocEl.id == "BrowserPreferences" && !openerDocEl.instantApply) - openUILinkIn(url, "window"); - else if (thisDocEl.id == "BrowserPreferences" && !thisDocEl.instantApply) - openUILinkIn(url, "window"); - else if (document.documentElement.id == "change-dialog") - Services.wm.getMostRecentWindow("navigator:browser") - .openUILinkIn(url, "tab"); - else - openUILinkIn(url, "tab"); - }, - - changeName: function changeName(input) { - // Make sure to update to a modified name, e.g., empty-string -> default - Weave.Service.clientsEngine.localName = input.value; - input.value = Weave.Service.clientsEngine.localName; - }, - - openChange: function openChange(type, duringSetup) { - // Just re-show the dialog if it's already open - let openedDialog = Services.wm.getMostRecentWindow("Sync:" + type); - if (openedDialog != null) { - openedDialog.focus(); - return; - } - - // Open up the change dialog - let changeXUL = "chrome://browser/content/sync/genericChange.xul"; - let changeOpt = "centerscreen,chrome,resizable=no"; - Services.ww.activeWindow.openDialog(changeXUL, "", changeOpt, - type, duringSetup); - }, - - changePassword: function () { - if (Weave.Utils.ensureMPUnlocked()) - this.openChange("ChangePassword"); - }, - - resetPassphrase: function (duringSetup) { - if (Weave.Utils.ensureMPUnlocked()) - this.openChange("ResetPassphrase", duringSetup); - }, - - updatePassphrase: function () { - if (Weave.Utils.ensureMPUnlocked()) - this.openChange("UpdatePassphrase"); - }, - - resetPassword: function () { - this._openLink(Weave.Service.pwResetURL); - }, - - get tosURL() { - let root = this.fxAccountsEnabled ? "fxa." : ""; - return Weave.Svc.Prefs.get(root + "termsURL"); - }, - - openToS: function () { - this._openLink(this.tosURL); - }, - - get privacyPolicyURL() { - let root = this.fxAccountsEnabled ? "fxa." : ""; - return Weave.Svc.Prefs.get(root + "privacyURL"); - }, - - openPrivacyPolicy: function () { - this._openLink(this.privacyPolicyURL); - }, - - /** - * Prepare an invisible iframe with the passphrase backup document. - * Used by both the print and saving methods. - * - * @param elid : ID of the form element containing the passphrase. - * @param callback : Function called once the iframe has loaded. - */ - _preparePPiframe: function(elid, callback) { - let pp = document.getElementById(elid).value; - - // Create an invisible iframe whose contents we can print. - let iframe = document.createElement("iframe"); - iframe.setAttribute("src", "chrome://browser/content/sync/key.xhtml"); - iframe.collapsed = true; - document.documentElement.appendChild(iframe); - iframe.contentWindow.addEventListener("load", function() { - iframe.contentWindow.removeEventListener("load", arguments.callee, false); - - // Insert the Sync Key into the page. - let el = iframe.contentDocument.getElementById("synckey"); - el.firstChild.nodeValue = pp; - - // Insert the TOS and Privacy Policy URLs into the page. - let termsURL = Weave.Svc.Prefs.get("termsURL"); - el = iframe.contentDocument.getElementById("tosLink"); - el.setAttribute("href", termsURL); - el.firstChild.nodeValue = termsURL; - - let privacyURL = Weave.Svc.Prefs.get("privacyURL"); - el = iframe.contentDocument.getElementById("ppLink"); - el.setAttribute("href", privacyURL); - el.firstChild.nodeValue = privacyURL; - - callback(iframe); - }, false); - }, - - /** - * Print passphrase backup document. - * - * @param elid : ID of the form element containing the passphrase. - */ - passphrasePrint: function(elid) { - this._preparePPiframe(elid, function(iframe) { - let webBrowserPrint = iframe.contentWindow - .QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIWebBrowserPrint); - let printSettings = PrintUtils.getPrintSettings(); - - // Display no header/footer decoration except for the date. - printSettings.headerStrLeft - = printSettings.headerStrCenter - = printSettings.headerStrRight - = printSettings.footerStrLeft - = printSettings.footerStrCenter = ""; - printSettings.footerStrRight = "&D"; - - try { - webBrowserPrint.print(printSettings, null); - } catch (ex) { - // print()'s return codes are expressed as exceptions. Ignore. - } - }); - }, - - /** - * Save passphrase backup document to disk as HTML file. - * - * @param elid : ID of the form element containing the passphrase. - */ - passphraseSave: function(elid) { - let dialogTitle = this.bundle.GetStringFromName("save.recoverykey.title"); - let defaultSaveName = this.bundle.GetStringFromName("save.recoverykey.defaultfilename"); - this._preparePPiframe(elid, function(iframe) { - let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); - let fpCallback = function fpCallback_done(aResult) { - if (aResult == Ci.nsIFilePicker.returnOK || - aResult == Ci.nsIFilePicker.returnReplace) { - let stream = Cc["@mozilla.org/network/file-output-stream;1"]. - createInstance(Ci.nsIFileOutputStream); - stream.init(fp.file, -1, PERMISSIONS_RWUSR, 0); - - let serializer = new XMLSerializer(); - let output = serializer.serializeToString(iframe.contentDocument); - output = output.replace(/<!DOCTYPE (.|\n)*?]>/, - '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" ' + - '"DTD/xhtml1-strict.dtd">'); - output = Weave.Utils.encodeUTF8(output); - stream.write(output, output.length); - } - }; - - fp.init(window, dialogTitle, Ci.nsIFilePicker.modeSave); - fp.appendFilters(Ci.nsIFilePicker.filterHTML); - fp.defaultString = defaultSaveName; - fp.open(fpCallback); - return false; - }); - }, - - /** - * validatePassword - * - * @param el1 : the first textbox element in the form - * @param el2 : the second textbox element, if omitted it's an update form - * - * returns [valid, errorString] - */ - validatePassword: function (el1, el2) { - let valid = false; - let val1 = el1.value; - let val2 = el2 ? el2.value : ""; - let error = ""; - - if (!el2) - valid = val1.length >= Weave.MIN_PASS_LENGTH; - else if (val1 && val1 == Weave.Service.identity.username) - error = "change.password.pwSameAsUsername"; - else if (val1 && val1 == Weave.Service.identity.account) - error = "change.password.pwSameAsEmail"; - else if (val1 && val1 == Weave.Service.identity.basicPassword) - error = "change.password.pwSameAsPassword"; - else if (val1 && val2) { - if (val1 == val2 && val1.length >= Weave.MIN_PASS_LENGTH) - valid = true; - else if (val1.length < Weave.MIN_PASS_LENGTH) - error = "change.password.tooShort"; - else if (val1 != val2) - error = "change.password.mismatch"; - } - let errorString = error ? Weave.Utils.getErrorString(error) : ""; - return [valid, errorString]; - } -}; diff --git a/application/basilisk/base/content/tab-content.js b/application/basilisk/base/content/tab-content.js index 7441b2140..fec13eba7 100644 --- a/application/basilisk/base/content/tab-content.js +++ b/application/basilisk/base/content/tab-content.js @@ -20,6 +20,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "AboutReader", "resource://gre/modules/AboutReader.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "ReaderMode", "resource://gre/modules/ReaderMode.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "Readerable", + "resource://gre/modules/Readerable.jsm"); XPCOMUtils.defineLazyGetter(this, "SimpleServiceDiscovery", function() { let ssdp = Cu.import("resource://gre/modules/SimpleServiceDiscovery.jsm", {}).SimpleServiceDiscovery; // Register targets @@ -336,7 +338,7 @@ var AboutReaderListener = { * painted is not going to work. */ updateReaderButton: function(forceNonArticle) { - if (!ReaderMode.isEnabledForParseOnLoad || this.isAboutReader || + if (!Readerable.isEnabledForParseOnLoad || this.isAboutReader || !content || !(content.document instanceof content.HTMLDocument) || content.document.mozSyntheticDocument) { return; @@ -375,7 +377,7 @@ var AboutReaderListener = { this.cancelPotentialPendingReadabilityCheck(); // Only send updates when there are articles; there's no point updating with // |false| all the time. - if (ReaderMode.isProbablyReaderable(content.document)) { + if (Readerable.isProbablyReaderable(content.document)) { sendAsyncMessage("Reader:UpdateReaderButton", { isArticle: true }); } else if (forceNonArticle) { sendAsyncMessage("Reader:UpdateReaderButton", { isArticle: false }); @@ -886,33 +888,6 @@ var RefreshBlocker = { RefreshBlocker.init(); -var UserContextIdNotifier = { - init() { - addEventListener("DOMWindowCreated", this); - }, - - uninit() { - removeEventListener("DOMWindowCreated", this); - }, - - handleEvent(aEvent) { - // When the window is created, we want to inform the tabbrowser about - // the userContextId in use in order to update the UI correctly. - // Just because we cannot change the userContextId from an active docShell, - // we don't need to check DOMContentLoaded again. - this.uninit(); - - // We use the docShell because content.document can have been loaded before - // setting the originAttributes. - let loadContext = docShell.QueryInterface(Ci.nsILoadContext); - let userContextId = loadContext.originAttributes.userContextId; - - sendAsyncMessage("Browser:WindowCreated", { userContextId }); - } -}; - -UserContextIdNotifier.init(); - addMessageListener("AllowScriptsToClose", () => { content.QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIDOMWindowUtils) diff --git a/application/basilisk/base/content/tabbrowser.xml b/application/basilisk/base/content/tabbrowser.xml index 52c51db69..0e819a3ed 100644 --- a/application/basilisk/base/content/tabbrowser.xml +++ b/application/basilisk/base/content/tabbrowser.xml @@ -814,10 +814,8 @@ } let unifiedComplete = this.mTabBrowser._unifiedComplete; - let userContextId = this.mBrowser.getAttribute("usercontextid") || 0; if (this.mBrowser.registeredOpenURI) { - unifiedComplete.unregisterOpenPage(this.mBrowser.registeredOpenURI, - userContextId); + unifiedComplete.unregisterOpenPage(this.mBrowser.registeredOpenURI); delete this.mBrowser.registeredOpenURI; } // Tabs in private windows aren't registered as "Open" so @@ -825,7 +823,7 @@ if (!isBlankPageURL(aLocation.spec) && (!PrivateBrowsingUtils.isWindowPrivate(window) || PrivateBrowsingUtils.permanentPrivateBrowsing)) { - unifiedComplete.registerOpenPage(aLocation, userContextId); + unifiedComplete.registerOpenPage(aLocation); this.mBrowser.registeredOpenURI = aLocation; } } @@ -1230,7 +1228,6 @@ this._adjustFocusAfterTabSwitch(this.mCurrentTab); } - updateUserContextUIIndicator(); gIdentityHandler.updateSharingIndicator(); this.tabContainer._setPositionalAttributes(); @@ -1486,7 +1483,6 @@ var aSkipAnimation; var aForceNotRemote; var aNoReferrer; - var aUserContextId; var aRelatedBrowser; var aOriginPrincipal; var aOpener; @@ -1507,7 +1503,6 @@ aSkipAnimation = params.skipAnimation; aForceNotRemote = params.forceNotRemote; aNoReferrer = params.noReferrer; - aUserContextId = params.userContextId; aRelatedBrowser = params.relatedBrowser; aOriginPrincipal = params.originPrincipal; aOpener = params.opener; @@ -1530,7 +1525,6 @@ allowMixedContent: aAllowMixedContent, forceNotRemote: aForceNotRemote, noReferrer: aNoReferrer, - userContextId: aUserContextId, originPrincipal: aOriginPrincipal, relatedBrowser: aRelatedBrowser, opener: aOpener }); @@ -1551,7 +1545,6 @@ let aTargetTab; let aNewIndex = -1; let aPostDatas = []; - let aUserContextId; if (arguments.length == 2 && typeof arguments[1] == "object") { let params = arguments[1]; @@ -1562,7 +1555,6 @@ aNewIndex = typeof params.newIndex === "number" ? params.newIndex : aNewIndex; aPostDatas = params.postDatas || aPostDatas; - aUserContextId = params.userContextId; } if (!aURIs.length) @@ -1611,8 +1603,7 @@ ownerTab: owner, skipAnimation: multiple, allowThirdPartyFixup: aAllowThirdPartyFixup, - postData: aPostDatas[0], - userContextId: aUserContextId + postData: aPostDatas[0] }); if (aNewIndex !== -1) { this.moveTabTo(firstTabAdded, aNewIndex); @@ -1625,8 +1616,7 @@ let tab = this.addTab(aURIs[i], { skipAnimation: true, allowThirdPartyFixup: aAllowThirdPartyFixup, - postData: aPostDatas[i], - userContextId: aUserContextId + postData: aPostDatas[i] }); if (targetTabIndex !== -1) this.moveTabTo(tab, ++tabNum); @@ -1899,7 +1889,7 @@ <body> <![CDATA[ // Supported parameters: - // userContextId, remote, isPreloadBrowser, uriIsAboutBlank, permanentKey + // remote, isPreloadBrowser, uriIsAboutBlank, permanentKey const NS_XUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; @@ -1911,10 +1901,6 @@ b.setAttribute("contextmenu", this.getAttribute("contentcontextmenu")); b.setAttribute("tooltip", this.getAttribute("contenttooltip")); - if (aParams.userContextId) { - b.setAttribute("usercontextid", aParams.userContextId); - } - if (aParams.remote) { b.setAttribute("remote", "true"); } @@ -1993,7 +1979,7 @@ "use strict"; // Supported parameters: - // forceNotRemote, userContextId + // forceNotRemote let uriIsAboutBlank = !aURI || aURI == "about:blank"; @@ -2011,7 +1997,6 @@ // Private windows are not included because both the label and the // icon for the tab would be set incorrectly (see bug 1195981). if (aURI == BROWSER_NEW_TAB_URL && - !aParams.userContextId && !PrivateBrowsingUtils.isWindowPrivate(window)) { browser = this._getPreloadedBrowser(); if (browser) { @@ -2025,7 +2010,6 @@ browser = this._createBrowser({permanentKey: aTab.permanentKey, remote: remote, uriIsAboutBlank: uriIsAboutBlank, - userContextId: aParams.userContextId, relatedBrowser: aParams.relatedBrowser, opener: aParams.opener}); } @@ -2100,7 +2084,6 @@ var aAllowMixedContent; var aForceNotRemote; var aNoReferrer; - var aUserContextId; var aEventDetail; var aRelatedBrowser; var aOriginPrincipal; @@ -2123,7 +2106,6 @@ aAllowMixedContent = params.allowMixedContent; aForceNotRemote = params.forceNotRemote; aNoReferrer = params.noReferrer; - aUserContextId = params.userContextId; aEventDetail = params.eventDetail; aRelatedBrowser = params.relatedBrowser; aOriginPrincipal = params.originPrincipal; @@ -2150,11 +2132,6 @@ t.setAttribute("label", aURI); } - if (aUserContextId) { - t.setAttribute("usercontextid", aUserContextId); - ContextualIdentityService.setTabStyle(t); - } - t.setAttribute("crop", "end"); t.setAttribute("onerror", "this.removeAttribute('image');"); @@ -2204,7 +2181,6 @@ // of tab.linkedBrowser. let browserParams = { forceNotRemote: aForceNotRemote, - userContextId: aUserContextId, relatedBrowser: aRelatedBrowser, opener: aOpener, }; @@ -2583,8 +2559,7 @@ listener.destroy(); if (browser.registeredOpenURI && !aAdoptedByTab) { - this._unifiedComplete.unregisterOpenPage(browser.registeredOpenURI, - browser.getAttribute("usercontextid") || 0); + this._unifiedComplete.unregisterOpenPage(browser.registeredOpenURI); delete browser.registeredOpenURI; } @@ -2783,11 +2758,6 @@ if (ourBrowser.isRemoteBrowser != otherBrowser.isRemoteBrowser) return; - // Keep the userContextId if set on other browser - if (otherBrowser.hasAttribute("usercontextid")) { - ourBrowser.setAttribute("usercontextid", otherBrowser.getAttribute("usercontextid")); - } - // That's gBrowser for the other window, not the tab's browser! var remoteBrowser = aOtherTab.ownerDocument.defaultView.gBrowser; var isPending = aOtherTab.hasAttribute("pending"); @@ -2820,10 +2790,6 @@ aOurTab.setAttribute("soundplaying", "true"); modifiedAttrs.push("soundplaying"); } - if (aOtherTab.hasAttribute("usercontextid")) { - aOurTab.setUserContextId(aOtherTab.getAttribute("usercontextid")); - modifiedAttrs.push("usercontextid"); - } if (aOtherTab.hasAttribute("sharing")) { aOurTab.setAttribute("sharing", aOtherTab.getAttribute("sharing")); modifiedAttrs.push("sharing"); @@ -2961,8 +2927,7 @@ <![CDATA[ // If the current URI is registered as open remove it from the list. if (aOurBrowser.registeredOpenURI) { - this._unifiedComplete.unregisterOpenPage(aOurBrowser.registeredOpenURI, - aOurBrowser.getAttribute("usercontextid") || 0); + this._unifiedComplete.unregisterOpenPage(aOurBrowser.registeredOpenURI); delete aOurBrowser.registeredOpenURI; } @@ -3302,10 +3267,6 @@ // it in the other window (making it seem to have moved between // windows). let params = { eventDetail: { adoptedTab: aTab } }; - if (aTab.hasAttribute("usercontextid")) { - // new tab must have the same usercontextid as the old one - params.userContextId = aTab.getAttribute("usercontextid"); - } let newTab = this.addTab("about:blank", params); let newBrowser = this.getBrowserForTab(newTab); let newURL = aTab.linkedBrowser.currentURI.spec; @@ -4174,11 +4135,7 @@ return true; if (this._logInit) return this._shouldLog; - let result = false; - try { - result = Services.prefs.getBoolPref("browser.tabs.remote.logSwitchTiming"); - } catch (ex) { - } + let result = Services.prefs.getBoolPref("browser.tabs.remote.logSwitchTiming", false); this._shouldLog = result; this._logInit = true; return this._shouldLog; @@ -4625,7 +4582,6 @@ disableSetDesktopBackground: data.disableSetDesktopBg, loginFillInfo: data.loginFillInfo, parentAllowsMixedContent: data.parentAllowsMixedContent, - userContextId: data.userContextId, }; let popup = browser.ownerDocument.getElementById("contentAreaContextMenu"); let event = gContextMenuContentData.event; @@ -4652,17 +4608,6 @@ } case "Browser:WindowCreated": { let tab = this.getTabForBrowser(browser); - if (tab && data.userContextId) { - ContextualIdentityService.telemetry(data.userContextId); - tab.setUserContextId(data.userContextId); - } - - // We don't want to update the container icon and identifier if - // this is not the selected browser. - if (browser == gBrowser.selectedBrowser) { - updateUserContextUIIndicator(); - } - break; } case "Findbar:Keypress": { @@ -4845,8 +4790,7 @@ for (let tab of this.tabs) { let browser = tab.linkedBrowser; if (browser.registeredOpenURI) { - this._unifiedComplete.unregisterOpenPage(browser.registeredOpenURI, - browser.getAttribute("usercontextid") || 0); + this._unifiedComplete.unregisterOpenPage(browser.registeredOpenURI); delete browser.registeredOpenURI; } let filter = this._tabFilters.get(tab); @@ -5247,7 +5191,7 @@ </xul:arrowscrollbox> </content> - <implementation implements="nsIDOMEventListener, nsIObserver"> + <implementation implements="nsIDOMEventListener"> <constructor> <![CDATA[ this.mTabClipWidth = Services.prefs.getIntPref("browser.tabs.tabClipWidth"); @@ -5260,23 +5204,11 @@ window.addEventListener("resize", this, false); window.addEventListener("load", this, false); - try { - this._tabAnimationLoggingEnabled = Services.prefs.getBoolPref("browser.tabs.animationLogging.enabled"); - } catch (ex) { - this._tabAnimationLoggingEnabled = false; - } + this._tabAnimationLoggingEnabled = Services.prefs.getBoolPref("browser.tabs.animationLogging.enabled", false); this._browserNewtabpageEnabled = Services.prefs.getBoolPref("browser.newtabpage.enabled"); - this.observe(null, "nsPref:changed", "privacy.userContext.enabled"); - Services.prefs.addObserver("privacy.userContext.enabled", this, false); ]]> </constructor> - <destructor> - <![CDATA[ - Services.prefs.removeObserver("privacy.userContext.enabled", this); - ]]> - </destructor> - <field name="tabbrowser" readonly="true"> document.getElementById(this.getAttribute("tabbrowser")); </field> @@ -5302,55 +5234,6 @@ <field name="_afterHoveredTab">null</field> <field name="_hoveredTab">null</field> - <method name="observe"> - <parameter name="aSubject"/> - <parameter name="aTopic"/> - <parameter name="aData"/> - <body><![CDATA[ - switch (aTopic) { - case "nsPref:changed": - // This is the only pref observed. - let containersEnabled = Services.prefs.getBoolPref("privacy.userContext.enabled"); - - const newTab = document.getElementById("new-tab-button"); - const newTab2 = document.getAnonymousElementByAttribute(this, "anonid", "tabs-newtab-button") - - if (containersEnabled) { - for (let parent of [newTab, newTab2]) { - if (!parent) - continue; - let popup = document.createElementNS( - "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", - "menupopup"); - if (parent.id) { - popup.id = "newtab-popup"; - } else { - popup.setAttribute("anonid", "newtab-popup"); - } - popup.className = "new-tab-popup"; - popup.setAttribute("position", "after_end"); - parent.appendChild(popup); - - gClickAndHoldListenersOnElement.add(parent); - parent.setAttribute("type", "menu"); - } - } else { - for (let parent of [newTab, newTab2]) { - if (!parent) - continue; - gClickAndHoldListenersOnElement.remove(parent); - parent.removeAttribute("type"); - if (!parent.firstChild) - continue; - parent.firstChild.remove(); - } - } - - break; - } - ]]></body> - </method> - <property name="_isCustomizing" readonly="true"> <getter> let root = document.documentElement; @@ -6451,7 +6334,6 @@ inBackground = !inBackground; let targetTab = this._getDragTargetTab(event, true); - let userContextId = this.selectedItem.getAttribute("usercontextid"); let replace = !!targetTab; let newIndex = this._getDropIndex(event, true); let urls = links.map(link => link.url); @@ -6461,7 +6343,6 @@ allowThirdPartyFixup: true, targetTab, newIndex, - userContextId, }); } @@ -6722,14 +6603,6 @@ --> <field name="muteReason">undefined</field> - <property name="userContextId" readonly="true"> - <getter> - return this.hasAttribute("usercontextid") - ? parseInt(this.getAttribute("usercontextid")) - : 0; - </getter> - </property> - <property name="soundPlaying" readonly="true"> <getter> return this.getAttribute("soundplaying") == "true"; @@ -6857,27 +6730,6 @@ ]]> </body> </method> - - <method name="setUserContextId"> - <parameter name="aUserContextId"/> - <body> - <![CDATA[ - if (aUserContextId) { - if (this.linkedBrowser) { - this.linkedBrowser.setAttribute("usercontextid", aUserContextId); - } - this.setAttribute("usercontextid", aUserContextId); - } else { - if (this.linkedBrowser) { - this.linkedBrowser.removeAttribute("usercontextid"); - } - this.removeAttribute("usercontextid"); - } - - ContextualIdentityService.setTabStyle(this); - ]]> - </body> - </method> </implementation> <handlers> @@ -7054,30 +6906,9 @@ <handlers> <handler event="popupshowing"> <![CDATA[ - if (event.target.getAttribute("id") == "alltabs_containersMenuTab") { - createUserContextMenu(event); - return; - } - - let containersEnabled = Services.prefs.getBoolPref("privacy.userContext.enabled"); - - if (event.target.getAttribute("anonid") == "newtab-popup" || - event.target.id == "newtab-popup") { - createUserContextMenu(event); - } else { - document.getElementById("alltabs-popup-separator-1").hidden = !containersEnabled; - let containersTab = document.getElementById("alltabs_containersTab"); - - containersTab.hidden = !containersEnabled; - if (PrivateBrowsingUtils.isWindowPrivate(window)) { - containersTab.setAttribute("disabled", "true"); - } - document.getElementById("alltabs_undoCloseTab").disabled = SessionStore.getClosedTabCount(window) == 0; - var tabcontainer = gBrowser.tabContainer; - // Listen for changes in the tab bar. tabcontainer.addEventListener("TabAttrModified", this, false); tabcontainer.addEventListener("TabClose", this, false); @@ -7094,9 +6925,6 @@ <handler event="popuphidden"> <![CDATA[ - if (event.target.getAttribute("id") == "alltabs_containersMenuTab") { - return; - } // clear out the menu popup and remove the listeners for (let i = this.childNodes.length - 1; i > 0; i--) { @@ -7105,9 +6933,6 @@ menuItem.tab.mCorrespondingMenuitem = null; this.removeChild(menuItem); } - if (menuItem.hasAttribute("usercontextid")) { - this.removeChild(menuItem); - } } var tabcontainer = gBrowser.tabContainer; tabcontainer.mTabstrip.removeEventListener("scroll", this, false); diff --git a/application/basilisk/base/content/utilityOverlay.js b/application/basilisk/base/content/utilityOverlay.js index 38ca82f55..3d27f7d27 100644 --- a/application/basilisk/base/content/utilityOverlay.js +++ b/application/basilisk/base/content/utilityOverlay.js @@ -5,7 +5,6 @@ // Services = object with smart getters for common XPCOM services Components.utils.import("resource://gre/modules/AppConstants.jsm"); -Components.utils.import("resource://gre/modules/ContextualIdentityService.jsm"); Components.utils.import("resource://gre/modules/Services.jsm"); Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm"); @@ -18,6 +17,9 @@ XPCOMUtils.defineLazyServiceGetter(this, "aboutNewTabService", "@mozilla.org/browser/aboutnewtab-service;1", "nsIAboutNewTabService"); +XPCOMUtils.defineLazyModuleGetter(this, "Deprecated", + "resource://gre/modules/Deprecated.jsm"); + this.__defineGetter__("BROWSER_NEW_TAB_URL", () => { if (PrivateBrowsingUtils.isWindowPrivate(window) && !PrivateBrowsingUtils.permanentPrivateBrowsing && @@ -35,7 +37,7 @@ var gBidiUI = false; * Determines whether the given url is considered a special URL for new tabs. */ function isBlankPageURL(aURL) { - return aURL == "about:blank" || aURL == "about:newtab" || aURL == "about:logopage"; + return aURL == "about:blank" || aURL == BROWSER_NEW_TAB_URL || aURL == "about:logopage"; } function getBrowserURL() @@ -43,6 +45,13 @@ function getBrowserURL() return "chrome://browser/content/browser.xul"; } +function getBoolPref(pref, defaultValue) { + Deprecated.warning("getBoolPref is deprecated and will be removed in a future release. " + + "You should use Services.pref.getBoolPref (Services.jsm).", + "https://github.com/MoonchildProductions/UXP/issues/989"); + return Services.prefs.getBoolPref(pref, defaultValue); +} + function getTopWin(skipPopups) { // If this is called in a browser window, use that window regardless of // whether it's the frontmost window, since commands can be executed in @@ -61,16 +70,6 @@ function openTopWin(url) { openUILinkIn(url, "current"); } -function getBoolPref(prefname, def) -{ - try { - return Services.prefs.getBoolPref(prefname); - } - catch (er) { - return def; - } -} - /* openUILink handles clicks on UI elements that cause URLs to load. * * As the third argument, you may pass an object with the same properties as @@ -137,7 +136,7 @@ function whereToOpenLink( e, ignoreButton, ignoreAlt ) // ignoreButton allows "middle-click paste" to use function without always opening in a new window. var middle = !ignoreButton && e.button == 1; - var middleUsesTabs = getBoolPref("browser.tabs.opentabfor.middleclick", true); + var middleUsesTabs = Services.prefs.getBoolPref("browser.tabs.opentabfor.middleclick", true); // Don't do anything special with right-mouse clicks. They're probably clicks on context menu items. @@ -145,7 +144,7 @@ function whereToOpenLink( e, ignoreButton, ignoreAlt ) if (metaKey || (middle && middleUsesTabs)) return shift ? "tabshifted" : "tab"; - if (alt && getBoolPref("browser.altClickSave", false)) + if (alt && Services.prefs.getBoolPref("browser.altClickSave", false)) return "save"; if (shift || (middle && !middleUsesTabs)) @@ -176,7 +175,6 @@ function whereToOpenLink( e, ignoreButton, ignoreAlt ) * skipTabAnimation (boolean) * allowPinnedTabHostChange (boolean) * allowPopups (boolean) - * userContextId (unsigned int) */ function openUILinkIn(url, where, aAllowThirdPartyFixup, aPostData, aReferrerURI) { var params; @@ -222,7 +220,6 @@ function openLinkIn(url, where, params) { var aAllowPinnedTabHostChange = !!params.allowPinnedTabHostChange; var aNoReferrer = params.noReferrer; var aAllowPopups = !!params.allowPopups; - var aUserContextId = params.userContextId; var aIndicateErrorPageLoad = params.indicateErrorPageLoad; var aPrincipal = params.originPrincipal; var aTriggeringPrincipal = params.triggeringPrincipal; @@ -268,7 +265,6 @@ function openLinkIn(url, where, params) { function useOAForPrincipal(principal) { if (principal && principal.isCodebasePrincipal) { let attrs = { - userContextId: aUserContextId, privateBrowsingId: aIsPrivate || (w && PrivateBrowsingUtils.isWindowPrivate(w)), }; return Services.scriptSecurityManager.createCodebasePrincipal(principal.URI, attrs); @@ -315,17 +311,12 @@ function openLinkIn(url, where, params) { createInstance(Ci.nsISupportsPRUint32); referrerPolicySupports.data = aReferrerPolicy; - var userContextIdSupports = Cc["@mozilla.org/supports-PRUint32;1"]. - createInstance(Ci.nsISupportsPRUint32); - userContextIdSupports.data = aUserContextId; - sa.appendElement(wuri, /* weak =*/ false); sa.appendElement(charset, /* weak =*/ false); sa.appendElement(referrerURISupports, /* weak =*/ false); sa.appendElement(aPostData, /* weak =*/ false); sa.appendElement(allowThirdPartyFixupSupports, /* weak =*/ false); sa.appendElement(referrerPolicySupports, /* weak =*/ false); - sa.appendElement(userContextIdSupports, /* weak =*/ false); sa.appendElement(aPrincipal, /* weak =*/ false); sa.appendElement(aTriggeringPrincipal, /* weak =*/ false); @@ -342,7 +333,7 @@ function openLinkIn(url, where, params) { if (loadInBackground == null) { loadInBackground = aFromChrome ? false : - getBoolPref("browser.tabs.loadInBackground"); + Services.prefs.getBoolPref("browser.tabs.loadInBackground"); } let uriObj; @@ -418,8 +409,7 @@ function openLinkIn(url, where, params) { flags: flags, referrerURI: aNoReferrer ? null : aReferrerURI, referrerPolicy: aReferrerPolicy, - postData: aPostData, - userContextId: aUserContextId + postData: aPostData }); browserUsedForLoad = aCurrentBrowser; break; @@ -438,7 +428,6 @@ function openLinkIn(url, where, params) { skipAnimation: aSkipTabAnimation, allowMixedContent: aAllowMixedContent, noReferrer: aNoReferrer, - userContextId: aUserContextId, originPrincipal: aPrincipal, triggeringPrincipal: aTriggeringPrincipal, }); @@ -482,74 +471,6 @@ function checkForMiddleClick(node, event) { } } -// Populate a menu with user-context menu items. This method should be called -// by onpopupshowing passing the event as first argument. -function createUserContextMenu(event, isContextMenu = false, excludeUserContextId = 0) { - while (event.target.hasChildNodes()) { - event.target.removeChild(event.target.firstChild); - } - - let bundle = document.getElementById("bundle_browser"); - let docfrag = document.createDocumentFragment(); - - // If we are excluding a userContextId, we want to add a 'no-container' item. - if (excludeUserContextId) { - let menuitem = document.createElement("menuitem"); - menuitem.setAttribute("data-usercontextid", "0"); - menuitem.setAttribute("label", bundle.getString("userContextNone.label")); - menuitem.setAttribute("accesskey", bundle.getString("userContextNone.accesskey")); - - // We don't set an oncommand/command attribute because if we have - // to exclude a userContextId we are generating the contextMenu and - // isContextMenu will be true. - - docfrag.appendChild(menuitem); - - let menuseparator = document.createElement("menuseparator"); - docfrag.appendChild(menuseparator); - } - - ContextualIdentityService.getIdentities().forEach(identity => { - if (identity.userContextId == excludeUserContextId) { - return; - } - - let menuitem = document.createElement("menuitem"); - menuitem.setAttribute("data-usercontextid", identity.userContextId); - menuitem.setAttribute("label", ContextualIdentityService.getUserContextLabel(identity.userContextId)); - - if (identity.accessKey) { - menuitem.setAttribute("accesskey", bundle.getString(identity.accessKey)); - } - - menuitem.classList.add("menuitem-iconic"); - menuitem.setAttribute("data-identity-color", identity.color); - - if (!isContextMenu) { - menuitem.setAttribute("command", "Browser:NewUserContextTab"); - } - - menuitem.setAttribute("data-identity-icon", identity.icon); - - docfrag.appendChild(menuitem); - }); - - if (!isContextMenu) { - docfrag.appendChild(document.createElement("menuseparator")); - - let menuitem = document.createElement("menuitem"); - menuitem.setAttribute("label", - bundle.getString("userContext.aboutPage.label")); - menuitem.setAttribute("accesskey", - bundle.getString("userContext.aboutPage.accesskey")); - menuitem.setAttribute("command", "Browser:OpenAboutContainers"); - docfrag.appendChild(menuitem); - } - - event.target.appendChild(docfrag); - return true; -} - // Closes all popups that are ancestors of the node. function closeMenus(node) { @@ -652,7 +573,7 @@ function getShellService() function isBidiEnabled() { // first check the pref. - if (getBoolPref("bidi.browser.ui", false)) + if (Services.prefs.getBoolPref("bidi.browser.ui", false)) return true; // then check intl.uidirection.<locale> @@ -914,7 +835,7 @@ function openHelpLink(aHelpTopic, aCalledFromModal, aWhere) { function openPrefsHelp() { // non-instant apply prefwindows are usually modal, so we can't open in the topmost window, // since its probably behind the window. - var instantApply = getBoolPref("browser.preferences.instantApply"); + var instantApply = Services.prefs.getBoolPref("browser.preferences.instantApply"); var helpTopic = document.getElementsByTagName("prefwindow")[0].currentPane.helpTopic; openHelpLink(helpTopic, !instantApply); diff --git a/application/basilisk/base/content/web-panels.xul b/application/basilisk/base/content/web-panels.xul index ed868c24a..78f8954c1 100644 --- a/application/basilisk/base/content/web-panels.xul +++ b/application/basilisk/base/content/web-panels.xul @@ -23,7 +23,6 @@ <script type="application/javascript" src="chrome://global/content/contentAreaUtils.js"/> <script type="application/javascript" src="chrome://browser/content/browser.js"/> <script type="application/javascript" src="chrome://browser/content/browser-places.js"/> - <script type="application/javascript" src="chrome://browser/content/browser-fxaccounts.js"/> <script type="application/javascript" src="chrome://browser/content/nsContextMenu.js"/> <script type="application/javascript" src="chrome://browser/content/web-panels.js"/> |