Bug 1384807 - Enable Pocket (en-US/en-CA), add hero element telemetry and bug fixes to Activity Stream. r?dmose draft
authorEd Lee <edilee@mozilla.com>
Wed, 26 Jul 2017 20:53:10 -0700
changeset 616501 7732a25195be1bf3c1260ab9847b880bf1848552
parent 616205 f1693d664f8e8ee4c79801630c181c28095cad56
child 639494 9fa541f84c0628088cd6fc7bc636a2ceee1210bc
push id70706
push userbmo:edilee@mozilla.com
push dateThu, 27 Jul 2017 03:58:27 +0000
reviewersdmose
bugs1384807
milestone56.0a1
Bug 1384807 - Enable Pocket (en-US/en-CA), add hero element telemetry and bug fixes to Activity Stream. r?dmose MozReview-Commit-ID: ATqGmgJf7l0
browser/extensions/activity-stream/common/Actions.jsm
browser/extensions/activity-stream/common/PerfService.jsm
browser/extensions/activity-stream/data/content/activity-stream.bundle.js
browser/extensions/activity-stream/data/content/activity-stream.css
browser/extensions/activity-stream/data/locales.json
browser/extensions/activity-stream/lib/ActivityStream.jsm
browser/extensions/activity-stream/lib/ActivityStreamMessageChannel.jsm
browser/extensions/activity-stream/lib/PlacesFeed.jsm
browser/extensions/activity-stream/lib/SnippetsFeed.jsm
browser/extensions/activity-stream/lib/TelemetryFeed.jsm
browser/extensions/activity-stream/lib/TopSitesFeed.jsm
browser/extensions/activity-stream/lib/TopStoriesFeed.jsm
browser/extensions/activity-stream/test/schemas/pings.js
browser/extensions/activity-stream/test/unit/common/PerfService.test.js
browser/extensions/activity-stream/test/unit/lib/ActivityStreamMessageChannel.test.js
browser/extensions/activity-stream/test/unit/lib/PlacesFeed.test.js
browser/extensions/activity-stream/test/unit/lib/SnippetsFeed.test.js
browser/extensions/activity-stream/test/unit/lib/TelemetryFeed.test.js
browser/extensions/activity-stream/test/unit/lib/TopSitesFeed.test.js
browser/extensions/activity-stream/test/unit/lib/TopStoriesFeed.test.js
browser/extensions/activity-stream/test/unit/unit-entry.js
browser/extensions/activity-stream/test/unit/utils.js
--- a/browser/extensions/activity-stream/common/Actions.jsm
+++ b/browser/extensions/activity-stream/common/Actions.jsm
@@ -31,31 +31,33 @@ for (const type of [
   "DELETE_HISTORY_URL_CONFIRM",
   "DIALOG_CANCEL",
   "DIALOG_OPEN",
   "FEED_INIT",
   "INIT",
   "LOCALE_UPDATED",
   "MIGRATION_CANCEL",
   "MIGRATION_START",
+  "NEW_TAB_INIT",
   "NEW_TAB_INITIAL_STATE",
   "NEW_TAB_LOAD",
   "NEW_TAB_UNLOAD",
-  "NEW_TAB_VISIBLE",
+  "OPEN_LINK",
   "OPEN_NEW_WINDOW",
   "OPEN_PRIVATE_WINDOW",
   "PINNED_SITES_UPDATED",
   "PLACES_BOOKMARK_ADDED",
   "PLACES_BOOKMARK_CHANGED",
   "PLACES_BOOKMARK_REMOVED",
   "PLACES_HISTORY_CLEARED",
   "PLACES_LINK_BLOCKED",
   "PLACES_LINK_DELETED",
   "PREFS_INITIAL_VALUES",
   "PREF_CHANGED",
+  "SAVE_SESSION_PERF_DATA",
   "SAVE_TO_POCKET",
   "SCREENSHOT_UPDATED",
   "SECTION_DEREGISTER",
   "SECTION_REGISTER",
   "SECTION_ROWS_UPDATE",
   "SET_PREF",
   "SNIPPETS_DATA",
   "SNIPPETS_RESET",
--- a/browser/extensions/activity-stream/common/PerfService.jsm
+++ b/browser/extensions/activity-stream/common/PerfService.jsm
@@ -65,24 +65,42 @@ this._PerfService = function _PerfServic
    *
    * @return {Number} A double of milliseconds with a precision of 0.5us.
    */
   get timeOrigin() {
     return this._perf.timeOrigin;
   },
 
   /**
-   * This returns the startTime from the most recen!t performance.mark()
+   * Returns the "absolute" version of performance.now(), i.e. one that
+   * based on the timeOrigin of the XUL hiddenwindow.
+   *
+   * @return {Number}
+   */
+  absNow: function absNow() {
+    return this.timeOrigin + this._perf.now();
+  },
+
+  /**
+   * This returns the absolute startTime from the most recent performance.mark()
    * with the given name.
    *
    * @param  {String} name  the name to lookup the start time for
    *
    * @return {Number}       the returned start time, as a DOMHighResTimeStamp
    *
    * @throws {Error}        "No Marks with the name ..." if none are available
+   *
+   * @note Always surround calls to this by try/catch.  Otherwise your code
+   * may fail when the `privacy.resistFingerprinting` pref is true.  When
+   * this pref is set, all attempts to get marks will likely fail, which will
+   * cause this method to throw.
+   *
+   * See [bug 1369303](https://bugzilla.mozilla.org/show_bug.cgi?id=1369303)
+   * for more info.
    */
   getMostRecentAbsMarkStartByName(name) {
     let entries = this.getEntriesByName(name, "mark");
 
     if (!entries.length) {
       throw new Error(`No marks with the name ${name}`);
     }
 
--- a/browser/extensions/activity-stream/data/content/activity-stream.bundle.js
+++ b/browser/extensions/activity-stream/data/content/activity-stream.bundle.js
@@ -98,17 +98,17 @@ const globalImportContext = typeof Windo
 
 
 // Create an object that avoids accidental differing key/value pairs:
 // {
 //   INIT: "INIT",
 //   UNINIT: "UNINIT"
 // }
 const actionTypes = {};
-for (const type of ["BLOCK_URL", "BOOKMARK_URL", "DELETE_BOOKMARK_BY_ID", "DELETE_HISTORY_URL", "DELETE_HISTORY_URL_CONFIRM", "DIALOG_CANCEL", "DIALOG_OPEN", "FEED_INIT", "INIT", "LOCALE_UPDATED", "MIGRATION_CANCEL", "MIGRATION_START", "NEW_TAB_INITIAL_STATE", "NEW_TAB_LOAD", "NEW_TAB_UNLOAD", "NEW_TAB_VISIBLE", "OPEN_NEW_WINDOW", "OPEN_PRIVATE_WINDOW", "PINNED_SITES_UPDATED", "PLACES_BOOKMARK_ADDED", "PLACES_BOOKMARK_CHANGED", "PLACES_BOOKMARK_REMOVED", "PLACES_HISTORY_CLEARED", "PLACES_LINK_BLOCKED", "PLACES_LINK_DELETED", "PREFS_INITIAL_VALUES", "PREF_CHANGED", "SAVE_TO_POCKET", "SCREENSHOT_UPDATED", "SECTION_DEREGISTER", "SECTION_REGISTER", "SECTION_ROWS_UPDATE", "SET_PREF", "SNIPPETS_DATA", "SNIPPETS_RESET", "SYSTEM_TICK", "TELEMETRY_PERFORMANCE_EVENT", "TELEMETRY_UNDESIRED_EVENT", "TELEMETRY_USER_EVENT", "TOP_SITES_PIN", "TOP_SITES_UNPIN", "TOP_SITES_UPDATED", "UNINIT"]) {
+for (const type of ["BLOCK_URL", "BOOKMARK_URL", "DELETE_BOOKMARK_BY_ID", "DELETE_HISTORY_URL", "DELETE_HISTORY_URL_CONFIRM", "DIALOG_CANCEL", "DIALOG_OPEN", "FEED_INIT", "INIT", "LOCALE_UPDATED", "MIGRATION_CANCEL", "MIGRATION_START", "NEW_TAB_INIT", "NEW_TAB_INITIAL_STATE", "NEW_TAB_LOAD", "NEW_TAB_UNLOAD", "OPEN_LINK", "OPEN_NEW_WINDOW", "OPEN_PRIVATE_WINDOW", "PINNED_SITES_UPDATED", "PLACES_BOOKMARK_ADDED", "PLACES_BOOKMARK_CHANGED", "PLACES_BOOKMARK_REMOVED", "PLACES_HISTORY_CLEARED", "PLACES_LINK_BLOCKED", "PLACES_LINK_DELETED", "PREFS_INITIAL_VALUES", "PREF_CHANGED", "SAVE_SESSION_PERF_DATA", "SAVE_TO_POCKET", "SCREENSHOT_UPDATED", "SECTION_DEREGISTER", "SECTION_REGISTER", "SECTION_ROWS_UPDATE", "SET_PREF", "SNIPPETS_DATA", "SNIPPETS_RESET", "SYSTEM_TICK", "TELEMETRY_PERFORMANCE_EVENT", "TELEMETRY_UNDESIRED_EVENT", "TELEMETRY_USER_EVENT", "TOP_SITES_PIN", "TOP_SITES_UNPIN", "TOP_SITES_UPDATED", "UNINIT"]) {
   actionTypes[type] = type;
 }
 
 // Helper function for creating routed actions between content and main
 // Not intended to be used by consumers
 function _RouteMessage(action, options) {
   const meta = action.meta ? Object.assign({}, action.meta) : {};
   if (!options || !options.from || !options.to) {
@@ -338,23 +338,23 @@ module.exports = function shortURL(link)
 
 
 const React = __webpack_require__(0);
 
 var _require = __webpack_require__(2);
 
 const injectIntl = _require.injectIntl;
 
-const ContextMenu = __webpack_require__(15);
+const ContextMenu = __webpack_require__(16);
 
 var _require2 = __webpack_require__(1);
 
 const ac = _require2.actionCreators;
 
-const linkMenuOptions = __webpack_require__(22);
+const linkMenuOptions = __webpack_require__(23);
 const DEFAULT_SITE_MENU_OPTIONS = ["CheckPinTopSite", "Separator", "OpenInNewWindow", "OpenInPrivateWindow"];
 
 class LinkMenu extends React.Component {
   getOptions() {
     const props = this.props;
     const site = props.site,
           index = props.index,
           source = props.source;
@@ -403,35 +403,158 @@ class LinkMenu extends React.Component {
 module.exports = injectIntl(LinkMenu);
 module.exports._unconnected = LinkMenu;
 
 /***/ }),
 /* 6 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
+/* globals Services */
+
+
+let usablePerfObj;
+
+let Cu;
+const isRunningInChrome = typeof Window === "undefined";
+
+/* istanbul ignore if */
+if (isRunningInChrome) {
+  Cu = Components.utils;
+} else {
+  Cu = { import() {} };
+}
+
+Cu.import("resource://gre/modules/Services.jsm");
+
+/* istanbul ignore if */
+if (isRunningInChrome) {
+  // Borrow the high-resolution timer from the hidden window....
+  usablePerfObj = Services.appShell.hiddenDOMWindow.performance;
+} else {
+  // we must be running in content space
+  usablePerfObj = performance;
+}
+
+var _PerfService = function _PerfService(options) {
+  // For testing, so that we can use a fake Window.performance object with
+  // known state.
+  if (options && options.performanceObj) {
+    this._perf = options.performanceObj;
+  } else {
+    this._perf = usablePerfObj;
+  }
+};
+
+_PerfService.prototype = {
+  /**
+   * Calls the underlying mark() method on the appropriate Window.performance
+   * object to add a mark with the given name to the appropriate performance
+   * timeline.
+   *
+   * @param  {String} name  the name to give the current mark
+   * @return {void}
+   */
+  mark: function mark(str) {
+    this._perf.mark(str);
+  },
+
+  /**
+   * Calls the underlying getEntriesByName on the appropriate Window.performance
+   * object.
+   *
+   * @param  {String} name
+   * @param  {String} type eg "mark"
+   * @return {Array}       Performance* objects
+   */
+  getEntriesByName: function getEntriesByName(name, type) {
+    return this._perf.getEntriesByName(name, type);
+  },
+
+  /**
+   * The timeOrigin property from the appropriate performance object.
+   * Used to ensure that timestamps from the add-on code and the content code
+   * are comparable.
+   *
+   * @return {Number} A double of milliseconds with a precision of 0.5us.
+   */
+  get timeOrigin() {
+    return this._perf.timeOrigin;
+  },
+
+  /**
+   * Returns the "absolute" version of performance.now(), i.e. one that
+   * based on the timeOrigin of the XUL hiddenwindow.
+   *
+   * @return {Number}
+   */
+  absNow: function absNow() {
+    return this.timeOrigin + this._perf.now();
+  },
+
+  /**
+   * This returns the absolute startTime from the most recent performance.mark()
+   * with the given name.
+   *
+   * @param  {String} name  the name to lookup the start time for
+   *
+   * @return {Number}       the returned start time, as a DOMHighResTimeStamp
+   *
+   * @throws {Error}        "No Marks with the name ..." if none are available
+   *
+   * @note Always surround calls to this by try/catch.  Otherwise your code
+   * may fail when the `privacy.resistFingerprinting` pref is true.  When
+   * this pref is set, all attempts to get marks will likely fail, which will
+   * cause this method to throw.
+   *
+   * See [bug 1369303](https://bugzilla.mozilla.org/show_bug.cgi?id=1369303)
+   * for more info.
+   */
+  getMostRecentAbsMarkStartByName(name) {
+    let entries = this.getEntriesByName(name, "mark");
+
+    if (!entries.length) {
+      throw new Error(`No marks with the name ${name}`);
+    }
+
+    let mostRecentEntry = entries[entries.length - 1];
+    return this._perf.timeOrigin + mostRecentEntry.startTime;
+  }
+};
+
+var perfService = new _PerfService();
+module.exports = {
+  _PerfService,
+  perfService
+};
+
+/***/ }),
+/* 7 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
 
 
 const React = __webpack_require__(0);
 
 var _require = __webpack_require__(3);
 
 const connect = _require.connect;
 
 var _require2 = __webpack_require__(2);
 
 const addLocaleData = _require2.addLocaleData,
       IntlProvider = _require2.IntlProvider;
 
-const TopSites = __webpack_require__(20);
-const Search = __webpack_require__(18);
-const ConfirmDialog = __webpack_require__(14);
-const ManualMigration = __webpack_require__(16);
-const PreferencesPane = __webpack_require__(17);
-const Sections = __webpack_require__(19);
+const TopSites = __webpack_require__(21);
+const Search = __webpack_require__(19);
+const ConfirmDialog = __webpack_require__(15);
+const ManualMigration = __webpack_require__(17);
+const PreferencesPane = __webpack_require__(18);
+const Sections = __webpack_require__(20);
 
 // Locales that should be displayed RTL
 const RTL_LIST = ["ar", "he", "fa", "ur"];
 
 // Add the locale data for pluralization and relative-time formatting for now,
 // this just uses english locale data. We can make this more sophisticated if
 // more features are needed.
 function addLocaleDataForReactIntl(_ref) {
@@ -493,27 +616,27 @@ class Base extends React.Component {
       )
     );
   }
 }
 
 module.exports = connect(state => ({ App: state.App, Prefs: state.Prefs }))(Base);
 
 /***/ }),
-/* 7 */
+/* 8 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 var _require = __webpack_require__(1);
 
 const at = _require.actionTypes;
 
-var _require2 = __webpack_require__(23);
+var _require2 = __webpack_require__(6);
 
 const perfSvc = _require2.perfService;
 
 
 const VISIBLE = "visible";
 const VISIBILITY_CHANGE_EVENT = "visibilitychange";
 
 module.exports = class DetectUserSessionStart {
@@ -542,43 +665,48 @@ module.exports = class DetectUserSession
       // If the document is not visible, listen for when it does become visible.
       this.document.addEventListener(VISIBILITY_CHANGE_EVENT, this._onVisibilityChange);
     }
   }
 
   /**
    * _sendEvent - Sends a message to the main process to indicate the current
    *              tab is now visible to the user, includes the
-   *              visibility-change-event time in ms from the UNIX epoch.
+   *              visibility_event_rcvd_ts time in ms from the UNIX epoch.
    */
   _sendEvent() {
-    this._perfService.mark("visibility-change-event");
+    this._perfService.mark("visibility_event_rcvd_ts");
 
-    let absVisChangeTime = this._perfService.getMostRecentAbsMarkStartByName("visibility-change-event");
+    try {
+      let visibility_event_rcvd_ts = this._perfService.getMostRecentAbsMarkStartByName("visibility_event_rcvd_ts");
 
-    this.sendAsyncMessage("ActivityStream:ContentToMain", {
-      type: at.NEW_TAB_VISIBLE,
-      data: { absVisibilityChangeTime: absVisChangeTime }
-    });
+      this.sendAsyncMessage("ActivityStream:ContentToMain", {
+        type: at.SAVE_SESSION_PERF_DATA,
+        data: { visibility_event_rcvd_ts }
+      });
+    } catch (ex) {
+      // If this failed, it's likely because the `privacy.resistFingerprinting`
+      // pref is true.  We should at least not blow up.
+    }
   }
 
   /**
    * _onVisibilityChange - If the visibility has changed to visible, sends a notification
    *                      and removes the event listener. This should only be called once per tab.
    */
   _onVisibilityChange() {
     if (this.document.visibilityState === VISIBLE) {
       this._sendEvent();
       this.document.removeEventListener(VISIBILITY_CHANGE_EVENT, this._onVisibilityChange);
     }
   }
 };
 
 /***/ }),
-/* 8 */
+/* 9 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 /* eslint-env mozilla/frame-script */
 
 var _require = __webpack_require__(25);
@@ -653,17 +781,17 @@ module.exports = function initStore(redu
   return store;
 };
 
 module.exports.MERGE_STORE_ACTION = MERGE_STORE_ACTION;
 module.exports.OUTGOING_MESSAGE_NAME = OUTGOING_MESSAGE_NAME;
 module.exports.INCOMING_MESSAGE_NAME = INCOMING_MESSAGE_NAME;
 
 /***/ }),
-/* 9 */
+/* 10 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 /* WEBPACK VAR INJECTION */(function(global) {
 
 const DATABASE_NAME = "snippets_db";
 const DATABASE_VERSION = 1;
 const SNIPPETS_OBJECTSTORE_NAME = "snippets";
@@ -815,34 +943,35 @@ class SnippetsProvider {
   get snippetsMap() {
     return global.gSnippetsMap;
   }
 
   async _refreshSnippets() {
     // Check if the cached version of of the snippets in snippetsMap. If it's too
     // old, blow away the entire snippetsMap.
     const cachedVersion = this.snippetsMap.get("snippets-cached-version");
-    if (cachedVersion !== this.version) {
+
+    if (cachedVersion !== this.appData.version) {
       this.snippetsMap.clear();
     }
 
     // Has enough time passed for us to require an update?
     const lastUpdate = this.snippetsMap.get("snippets-last-update");
     const needsUpdate = !(lastUpdate >= 0) || Date.now() - lastUpdate > SNIPPETS_UPDATE_INTERVAL_MS;
 
-    if (needsUpdate && this.snippetsURL) {
+    if (needsUpdate && this.appData.snippetsURL) {
       this.snippetsMap.set("snippets-last-update", Date.now());
       try {
         // TODO: timeout?
-        const response = await fetch(this.snippetsURL);
+        const response = await fetch(this.appData.snippetsURL);
         if (response.status === 200) {
           const payload = await response.text();
 
           this.snippetsMap.set("snippets", payload);
-          this.snippetsMap.set("snippets-cached-version", this.version);
+          this.snippetsMap.set("snippets-cached-version", this.appData.version);
         }
       } catch (e) {
         console.error(e); // eslint-disable-line no-console
       }
     }
   }
 
   _showDefaultSnippets() {
@@ -879,39 +1008,45 @@ class SnippetsProvider {
       containerEl.style.display = "block";
     }
   }
 
   /**
    * init - Fetch the snippet payload and show snippets
    *
    * @param  {obj} options
-   * @param  {str} options.snippetsURL  The URL from which we fetch snippets
-   * @param  {int} options.version  The current snippets version
-   * @param  {str} options.elementId  The id of the element of the snippets container
+   * @param  {str} options.appData.snippetsURL  The URL from which we fetch snippets
+   * @param  {int} options.appData.version  The current snippets version
+   * @param  {str} options.elementId  The id of the element in which to inject snippets
+   * @param  {str} options.containerElementId  The id of the element of element containing the snippets element
+   * @param  {bool} options.connect  Should gSnippetsMap connect to indexedDB?
    */
   async init(options) {
     Object.assign(this, {
-      snippetsURL: "",
-      version: 0,
+      appData: {},
       elementId: "snippets",
       containerElementId: "snippets-container",
       connect: true
     }, options);
 
     // TODO: Requires enabling indexedDB on newtab
     // Restore the snippets map from indexedDB
     if (this.connect) {
       try {
         await this.snippetsMap.connect();
       } catch (e) {
         console.error(e); // eslint-disable-line no-console
       }
     }
 
+    // Cache app data values so they can be accessible from gSnippetsMap
+    for (const key of Object.keys(this.appData)) {
+      this.snippetsMap.set(`appData.${key}`, this.appData[key]);
+    }
+
     // Refresh snippets, if enough time has passed.
     await this._refreshSnippets();
 
     // Try showing remote snippets, falling back to defaults if necessary.
     try {
       this._showRemoteSnippets();
     } catch (e) {
       this._showDefaultSnippets(e);
@@ -920,17 +1055,17 @@ class SnippetsProvider {
 }
 
 module.exports.SnippetsMap = SnippetsMap;
 module.exports.SnippetsProvider = SnippetsProvider;
 module.exports.SNIPPETS_UPDATE_INTERVAL_MS = SNIPPETS_UPDATE_INTERVAL_MS;
 /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(24)))
 
 /***/ }),
-/* 10 */
+/* 11 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 /* 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/. */
 
 
@@ -1221,61 +1356,77 @@ function Snippets() {
 var reducers = { TopSites, App, Snippets, Prefs, Dialog, Sections };
 module.exports = {
   reducers,
   INITIAL_STATE,
   insertPinned
 };
 
 /***/ }),
-/* 11 */
+/* 12 */
 /***/ (function(module, exports) {
 
 module.exports = ReactDOM;
 
 /***/ }),
-/* 12 */
+/* 13 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 const React = __webpack_require__(0);
 const LinkMenu = __webpack_require__(5);
 const shortURL = __webpack_require__(4);
 
 var _require = __webpack_require__(2);
 
 const FormattedMessage = _require.FormattedMessage;
 
-const cardContextTypes = __webpack_require__(13);
+const cardContextTypes = __webpack_require__(14);
+
+var _require2 = __webpack_require__(1);
+
+const ac = _require2.actionCreators,
+      at = _require2.actionTypes;
 
 /**
  * Card component.
  * Cards are found within a Section component and contain information about a link such
  * as preview image, page title, page description, and some context about if the page
  * was visited, bookmarked, trending etc...
  * Each Section can make an unordered list of Cards which will create one instane of
  * this class. Each card will then get a context menu which reflects the actions that
  * can be done on this Card.
  */
+
 class Card extends React.Component {
   constructor(props) {
     super(props);
     this.state = { showContextMenu: false, activeCard: null };
     this.onMenuButtonClick = this.onMenuButtonClick.bind(this);
     this.onMenuUpdate = this.onMenuUpdate.bind(this);
+    this.onLinkClick = this.onLinkClick.bind(this);
   }
   onMenuButtonClick(event) {
     event.preventDefault();
     this.setState({
       activeCard: this.props.index,
       showContextMenu: true
     });
   }
+  onLinkClick(event) {
+    event.preventDefault();
+    this.props.dispatch(ac.SendToMain({ type: at.OPEN_LINK, data: this.props.link }));
+    this.props.dispatch(ac.UserEvent({
+      event: "CLICK",
+      source: this.props.eventSource,
+      action_position: this.props.index
+    }));
+  }
   onMenuUpdate(showContextMenu) {
     this.setState({ showContextMenu });
   }
   render() {
     var _props = this.props;
     const index = _props.index,
           link = _props.link,
           dispatch = _props.dispatch,
@@ -1288,17 +1439,17 @@ class Card extends React.Component {
           intlID = _cardContextTypes$lin.intlID;
 
 
     return React.createElement(
       "li",
       { className: `card-outer${isContextMenuOpen ? " active" : ""}` },
       React.createElement(
         "a",
-        { href: link.url },
+        { href: link.url, onClick: this.onLinkClick },
         React.createElement(
           "div",
           { className: "card" },
           link.image && React.createElement("div", { className: "card-preview-image", style: { backgroundImage: `url(${link.image})` } }),
           React.createElement(
             "div",
             { className: "card-details" },
             React.createElement(
@@ -1357,17 +1508,17 @@ class Card extends React.Component {
         site: link,
         visible: isContextMenuOpen })
     );
   }
 }
 module.exports = Card;
 
 /***/ }),
-/* 13 */
+/* 14 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 module.exports = {
   history: {
     intlID: "type_label_visited",
@@ -1383,17 +1534,17 @@ module.exports = {
   },
   now: {
     intlID: "type_label_now",
     icon: "now"
   }
 };
 
 /***/ }),
-/* 14 */
+/* 15 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 const React = __webpack_require__(0);
 
 var _require = __webpack_require__(3);
@@ -1502,17 +1653,17 @@ const ConfirmDialog = React.createClass(
   }
 });
 
 module.exports = connect(state => state.Dialog)(ConfirmDialog);
 module.exports._unconnected = ConfirmDialog;
 module.exports.Dialog = ConfirmDialog;
 
 /***/ }),
-/* 15 */
+/* 16 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 const React = __webpack_require__(0);
 
 class ContextMenu extends React.Component {
@@ -1596,17 +1747,17 @@ class ContextMenuItem extends React.Comp
   }
 }
 
 module.exports = ContextMenu;
 module.exports.ContextMenu = ContextMenu;
 module.exports.ContextMenuItem = ContextMenuItem;
 
 /***/ }),
-/* 16 */
+/* 17 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 const React = __webpack_require__(0);
 
 var _require = __webpack_require__(3);
@@ -1674,17 +1825,17 @@ class ManualMigration extends React.Comp
     );
   }
 }
 
 module.exports = connect()(ManualMigration);
 module.exports._unconnected = ManualMigration;
 
 /***/ }),
-/* 17 */
+/* 18 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 const React = __webpack_require__(0);
 
 var _require = __webpack_require__(3);
@@ -1703,32 +1854,39 @@ const ac = _require3.actionCreators;
 
 const PreferencesInput = props => React.createElement(
   "section",
   null,
   React.createElement("input", { type: "checkbox", id: props.prefName, name: props.prefName, checked: props.value, onChange: props.onChange, className: props.className }),
   React.createElement(
     "label",
     { htmlFor: props.prefName },
-    React.createElement(FormattedMessage, { id: props.titleStringId })
+    React.createElement(FormattedMessage, { id: props.titleStringId, values: props.titleStringValues })
   ),
   props.descStringId && React.createElement(
     "p",
     { className: "prefs-input-description" },
     React.createElement(FormattedMessage, { id: props.descStringId })
   )
 );
 
 class PreferencesPane extends React.Component {
   constructor(props) {
     super(props);
     this.state = { visible: false };
     this.handleClickOutside = this.handleClickOutside.bind(this);
     this.handleChange = this.handleChange.bind(this);
     this.togglePane = this.togglePane.bind(this);
+
+    // TODO This is temporary until sections register their PreferenceInput component automatically
+    try {
+      this.topStoriesOptions = JSON.parse(props.Prefs.values["feeds.section.topstories.options"]);
+    } catch (e) {
+      console.error("Problem parsing feeds.section.topstories.options", e); // eslint-disable-line no-console
+    }
   }
   componentDidMount() {
     document.addEventListener("click", this.handleClickOutside);
   }
   componentWillUnmount() {
     document.removeEventListener("click", this.handleClickOutside);
   }
   handleClickOutside(event) {
@@ -1779,18 +1937,20 @@ class PreferencesPane extends React.Comp
               "p",
               null,
               React.createElement(FormattedMessage, { id: "settings_pane_body" })
             ),
             React.createElement(PreferencesInput, { className: "showSearch", prefName: "showSearch", value: prefs.showSearch, onChange: this.handleChange,
               titleStringId: "settings_pane_search_header", descStringId: "settings_pane_search_body" }),
             React.createElement(PreferencesInput, { className: "showTopSites", prefName: "showTopSites", value: prefs.showTopSites, onChange: this.handleChange,
               titleStringId: "settings_pane_topsites_header", descStringId: "settings_pane_topsites_body" }),
-            React.createElement(PreferencesInput, { className: "showTopStories", prefName: "feeds.section.topstories", value: prefs["feeds.section.topstories"], onChange: this.handleChange,
-              titleStringId: "settings_pane_pocketstories_header", descStringId: "settings_pane_pocketstories_body" })
+            this.topStoriesOptions && React.createElement(PreferencesInput, { className: "showTopStories", prefName: "feeds.section.topstories",
+              value: prefs["feeds.section.topstories"], onChange: this.handleChange,
+              titleStringId: "header_recommended_by", titleStringValues: { provider: this.topStoriesOptions.provider_name },
+              descStringId: this.topStoriesOptions.provider_description })
           ),
           React.createElement(
             "section",
             { className: "actions" },
             React.createElement(
               "button",
               { className: "done", onClick: this.togglePane },
               React.createElement(FormattedMessage, { id: "settings_pane_done_button" })
@@ -1802,17 +1962,17 @@ class PreferencesPane extends React.Comp
   }
 }
 
 module.exports = connect(state => ({ Prefs: state.Prefs }))(injectIntl(PreferencesPane));
 module.exports.PreferencesPane = PreferencesPane;
 module.exports.PreferencesInput = PreferencesInput;
 
 /***/ }),
-/* 18 */
+/* 19 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 /* globals ContentSearchUIController */
 
 
 const React = __webpack_require__(0);
 
@@ -1901,17 +2061,17 @@ class Search extends React.Component {
     );
   }
 }
 
 module.exports = connect()(injectIntl(Search));
 module.exports._unconnected = Search;
 
 /***/ }),
-/* 19 */
+/* 20 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
 
 const React = __webpack_require__(0);
@@ -1919,23 +2079,24 @@ const React = __webpack_require__(0);
 var _require = __webpack_require__(3);
 
 const connect = _require.connect;
 
 var _require2 = __webpack_require__(2);
 
 const FormattedMessage = _require2.FormattedMessage;
 
-const Card = __webpack_require__(12);
-const Topics = __webpack_require__(21);
+const Card = __webpack_require__(13);
+const Topics = __webpack_require__(22);
 
 class Section extends React.Component {
   render() {
     var _props = this.props;
     const id = _props.id,
+          eventSource = _props.eventSource,
           title = _props.title,
           icon = _props.icon,
           rows = _props.rows,
           infoOption = _props.infoOption,
           emptyState = _props.emptyState,
           dispatch = _props.dispatch,
           maxCards = _props.maxCards,
           contextMenuOptions = _props.contextMenuOptions;
@@ -1984,17 +2145,17 @@ class Section extends React.Component {
               React.createElement(FormattedMessage, infoOption.link)
             )
           )
         )
       ),
       React.createElement(
         "ul",
         { className: "section-list", style: { padding: 0 } },
-        rows.slice(0, maxCards).map((link, index) => link && React.createElement(Card, { index: index, dispatch: dispatch, link: link, contextMenuOptions: contextMenuOptions }))
+        rows.slice(0, maxCards).map((link, index) => link && React.createElement(Card, { index: index, dispatch: dispatch, link: link, contextMenuOptions: contextMenuOptions, eventSource: eventSource }))
       ),
       !initialized && React.createElement(
         "div",
         { className: "section-empty-state" },
         React.createElement(
           "div",
           { className: "empty-state" },
           React.createElement("img", { className: `empty-state-icon icon icon-${emptyState.icon}` }),
@@ -2021,17 +2182,17 @@ class Sections extends React.Component {
   }
 }
 
 module.exports = connect(state => ({ Sections: state.Sections }))(Sections);
 module.exports._unconnected = Sections;
 module.exports.Section = Section;
 
 /***/ }),
-/* 20 */
+/* 21 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 const React = __webpack_require__(0);
 
 var _require = __webpack_require__(3);
@@ -2042,17 +2203,22 @@ var _require2 = __webpack_require__(2);
 
 const FormattedMessage = _require2.FormattedMessage;
 
 const shortURL = __webpack_require__(4);
 const LinkMenu = __webpack_require__(5);
 
 var _require3 = __webpack_require__(1);
 
-const ac = _require3.actionCreators;
+const ac = _require3.actionCreators,
+      at = _require3.actionTypes;
+
+var _require4 = __webpack_require__(6);
+
+const perfSvc = _require4.perfService;
 
 const TOP_SITES_SOURCE = "TOP_SITES";
 const TOP_SITES_CONTEXT_MENU_OPTIONS = ["CheckPinTopSite", "Separator", "OpenInNewWindow", "OpenInPrivateWindow", "Separator", "BlockUrl", "DeleteUrl"];
 
 class TopSite extends React.Component {
   constructor(props) {
     super(props);
     this.state = { showContextMenu: false, activeTile: null };
@@ -2134,16 +2300,107 @@ class TopSite extends React.Component {
         options: TOP_SITES_CONTEXT_MENU_OPTIONS,
         site: link,
         source: TOP_SITES_SOURCE,
         visible: isContextMenuOpen })
     );
   }
 }
 
+/**
+ * A proxy class that uses double requestAnimationFrame from
+ * componentDidMount to dispatch a SAVE_SESSION_PERF_DATA to the main procsess
+ * after the paint.
+ *
+ * This uses two callbacks because, after one callback, this part of the tree
+ * may have rendered but not yet reflowed.  This strategy is modeled after
+ * https://stackoverflow.com/a/34999925 but uses a double rFA because
+ * we want to get to the closest reliable paint for measuring, and
+ * setTimeout is often throttled or queued by browsers in ways that could
+ * make it lag too long.
+ *
+ * XXX Should be made more generic by using this.props.children, or potentially
+ * even split out into a higher-order component to wrap whatever.
+ *
+ * @class TopSitesPerfTimer
+ * @extends {React.Component}
+ */
+class TopSitesPerfTimer extends React.Component {
+  constructor(props) {
+    super(props);
+    // Just for test dependency injection:
+    this.perfSvc = this.props.perfSvc || perfSvc;
+
+    this._sendPaintedEvent = this._sendPaintedEvent.bind(this);
+    this._timestampSent = false;
+  }
+
+  componentDidMount() {
+    this._maybeSendPaintedEvent();
+  }
+
+  componentDidUpdate() {
+    this._maybeSendPaintedEvent();
+  }
+
+  /**
+   * Call the given callback when the subsequent animation frame
+   * (not the upcoming one) paints.
+   *
+   * @param {Function} callback
+   *
+   * @returns void
+   */
+  _onNextFrame(callback) {
+    requestAnimationFrame(() => {
+      requestAnimationFrame(callback);
+    });
+  }
+
+  _maybeSendPaintedEvent() {
+    // If we've already saved a timestamp for this session, don't do so again.
+    if (this._timestampSent) {
+      return;
+    }
+
+    // We don't want this to ever happen, but sometimes it does.  And when it
+    // does (typically on the first newtab at startup time calling
+    // componentDidMount), the paint(s) we care about will be later (eg
+    // in a subsequent componentDidUpdate).
+    if (!this.props.TopSites.initialized) {
+      // XXX should send bad event
+      return;
+    }
+
+    this._onNextFrame(this._sendPaintedEvent);
+  }
+
+  _sendPaintedEvent() {
+    this.perfSvc.mark("topsites_first_painted_ts");
+
+    try {
+      let topsites_first_painted_ts = this.perfSvc.getMostRecentAbsMarkStartByName("topsites_first_painted_ts");
+
+      this.props.dispatch(ac.SendToMain({
+        type: at.SAVE_SESSION_PERF_DATA,
+        data: { topsites_first_painted_ts }
+      }));
+    } catch (ex) {
+      // If this failed, it's likely because the `privacy.resistFingerprinting`
+      // pref is true.  We should at least not blow up, and should continue
+      // to set this._timestampSent to avoid going through this again.
+    }
+
+    this._timestampSent = true;
+  }
+  render() {
+    return React.createElement(TopSites, this.props);
+  }
+}
+
 const TopSites = props => React.createElement(
   "section",
   null,
   React.createElement(
     "h3",
     { className: "section-title" },
     React.createElement("span", { className: `icon icon-small-spacer icon-topsites` }),
     React.createElement(FormattedMessage, { id: "header_top_sites" })
@@ -2154,22 +2411,23 @@ const TopSites = props => React.createEl
     props.TopSites.rows.map((link, index) => link && React.createElement(TopSite, {
       key: link.guid || link.url,
       dispatch: props.dispatch,
       link: link,
       index: index }))
   )
 );
 
-module.exports = connect(state => ({ TopSites: state.TopSites }))(TopSites);
-module.exports._unconnected = TopSites;
+module.exports = connect(state => ({ TopSites: state.TopSites }))(TopSitesPerfTimer);
+module.exports._unconnected = TopSitesPerfTimer;
 module.exports.TopSite = TopSite;
+module.exports.TopSites = TopSites;
 
 /***/ }),
-/* 21 */
+/* 22 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 const React = __webpack_require__(0);
 
 var _require = __webpack_require__(2);
@@ -2224,17 +2482,17 @@ class Topics extends React.Component {
   }
 }
 
 module.exports = Topics;
 module.exports._unconnected = Topics;
 module.exports.Topic = Topic;
 
 /***/ }),
-/* 22 */
+/* 23 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 var _require = __webpack_require__(1);
 
 const at = _require.actionTypes,
@@ -2267,26 +2525,26 @@ module.exports = {
     }),
     userEvent: "BOOKMARK_ADD"
   }),
   OpenInNewWindow: site => ({
     id: "menu_action_open_new_window",
     icon: "new-window",
     action: ac.SendToMain({
       type: at.OPEN_NEW_WINDOW,
-      data: { url: site.url }
+      data: { url: site.url, referrer: site.referrer }
     }),
     userEvent: "OPEN_NEW_WINDOW"
   }),
   OpenInPrivateWindow: site => ({
     id: "menu_action_open_private_window",
     icon: "new-window-private",
     action: ac.SendToMain({
       type: at.OPEN_PRIVATE_WINDOW,
-      data: { url: site.url }
+      data: { url: site.url, referrer: site.referrer }
     }),
     userEvent: "OPEN_PRIVATE_WINDOW"
   }),
   BlockUrl: site => ({
     id: "menu_action_dismiss",
     icon: "dismiss",
     action: ac.SendToMain({
       type: at.BLOCK_URL,
@@ -2335,121 +2593,16 @@ module.exports = {
     userEvent: "SAVE_TO_POCKET"
   })
 };
 
 module.exports.CheckBookmark = site => site.bookmarkGuid ? module.exports.RemoveBookmark(site) : module.exports.AddBookmark(site);
 module.exports.CheckPinTopSite = (site, index) => site.isPinned ? module.exports.UnpinTopSite(site) : module.exports.PinTopSite(site, index);
 
 /***/ }),
-/* 23 */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-/* globals Services */
-
-
-let usablePerfObj;
-
-let Cu;
-const isRunningInChrome = typeof Window === "undefined";
-
-/* istanbul ignore if */
-if (isRunningInChrome) {
-  Cu = Components.utils;
-} else {
-  Cu = { import() {} };
-}
-
-Cu.import("resource://gre/modules/Services.jsm");
-
-/* istanbul ignore if */
-if (isRunningInChrome) {
-  // Borrow the high-resolution timer from the hidden window....
-  usablePerfObj = Services.appShell.hiddenDOMWindow.performance;
-} else {
-  // we must be running in content space
-  usablePerfObj = performance;
-}
-
-var _PerfService = function _PerfService(options) {
-  // For testing, so that we can use a fake Window.performance object with
-  // known state.
-  if (options && options.performanceObj) {
-    this._perf = options.performanceObj;
-  } else {
-    this._perf = usablePerfObj;
-  }
-};
-
-_PerfService.prototype = {
-  /**
-   * Calls the underlying mark() method on the appropriate Window.performance
-   * object to add a mark with the given name to the appropriate performance
-   * timeline.
-   *
-   * @param  {String} name  the name to give the current mark
-   * @return {void}
-   */
-  mark: function mark(str) {
-    this._perf.mark(str);
-  },
-
-  /**
-   * Calls the underlying getEntriesByName on the appropriate Window.performance
-   * object.
-   *
-   * @param  {String} name
-   * @param  {String} type eg "mark"
-   * @return {Array}       Performance* objects
-   */
-  getEntriesByName: function getEntriesByName(name, type) {
-    return this._perf.getEntriesByName(name, type);
-  },
-
-  /**
-   * The timeOrigin property from the appropriate performance object.
-   * Used to ensure that timestamps from the add-on code and the content code
-   * are comparable.
-   *
-   * @return {Number} A double of milliseconds with a precision of 0.5us.
-   */
-  get timeOrigin() {
-    return this._perf.timeOrigin;
-  },
-
-  /**
-   * This returns the startTime from the most recen!t performance.mark()
-   * with the given name.
-   *
-   * @param  {String} name  the name to lookup the start time for
-   *
-   * @return {Number}       the returned start time, as a DOMHighResTimeStamp
-   *
-   * @throws {Error}        "No Marks with the name ..." if none are available
-   */
-  getMostRecentAbsMarkStartByName(name) {
-    let entries = this.getEntriesByName(name, "mark");
-
-    if (!entries.length) {
-      throw new Error(`No marks with the name ${name}`);
-    }
-
-    let mostRecentEntry = entries[entries.length - 1];
-    return this._perf.timeOrigin + mostRecentEntry.startTime;
-  }
-};
-
-var perfService = new _PerfService();
-module.exports = {
-  _PerfService,
-  perfService
-};
-
-/***/ }),
 /* 24 */
 /***/ (function(module, exports) {
 
 var g;
 
 // This works in non-strict mode
 g = (function() {
 	return this;
@@ -2480,32 +2633,32 @@ module.exports = Redux;
 /***/ }),
 /* 26 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 const React = __webpack_require__(0);
-const ReactDOM = __webpack_require__(11);
-const Base = __webpack_require__(6);
+const ReactDOM = __webpack_require__(12);
+const Base = __webpack_require__(7);
 
 var _require = __webpack_require__(3);
 
 const Provider = _require.Provider;
 
-const initStore = __webpack_require__(8);
+const initStore = __webpack_require__(9);
 
-var _require2 = __webpack_require__(10);
+var _require2 = __webpack_require__(11);
 
 const reducers = _require2.reducers;
 
-const DetectUserSessionStart = __webpack_require__(7);
+const DetectUserSessionStart = __webpack_require__(8);
 
-var _require3 = __webpack_require__(9);
+var _require3 = __webpack_require__(10);
 
 const SnippetsProvider = _require3.SnippetsProvider;
 
 
 new DetectUserSessionStart().sendEventOrAddListener();
 
 const store = initStore(reducers);
 
@@ -2515,18 +2668,15 @@ ReactDOM.render(React.createElement(
   React.createElement(Base, null)
 ), document.getElementById("root"));
 
 // Trigger snippets when snippets data has been received.
 const snippets = new SnippetsProvider();
 const unsubscribe = store.subscribe(() => {
   const state = store.getState();
   if (state.Snippets.initialized) {
-    snippets.init({
-      snippetsURL: state.Snippets.snippetsURL,
-      version: state.Snippets.version
-    });
+    snippets.init({ appData: state.Snippets });
     unsubscribe();
   }
 });
 
 /***/ })
 /******/ ]);
\ No newline at end of file
--- a/browser/extensions/activity-stream/data/content/activity-stream.css
+++ b/browser/extensions/activity-stream/data/content/activity-stream.css
@@ -73,17 +73,17 @@ input {
 
 html,
 body,
 #root {
   height: 100%; }
 
 body {
   background: #F6F6F8;
-  color: #383E49;
+  color: #0C0C0D;
   font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Ubuntu', 'Helvetica Neue', sans-serif;
   font-size: 16px; }
 
 h1,
 h2 {
   font-weight: normal; }
 
 a {
@@ -132,17 +132,17 @@ a {
   flex-direction: row;
   margin: 0;
   padding: 15px 25px;
   justify-content: flex-start; }
   .actions button {
     background: #FBFBFB;
     border: solid 1px #BFBFBF;
     border-radius: 5px;
-    color: #858585;
+    color: #0C0C0D;
     cursor: pointer;
     padding: 10px 30px; }
     .actions button:hover {
       box-shadow: 0 0 0 5px rgba(0, 0, 0, 0.1);
       transition: box-shadow 150ms; }
     .actions button.done {
       background: #0695F9;
       border: solid 1px #1677CF;
@@ -180,16 +180,18 @@ main {
     margin-bottom: 40px; }
 
 .section-title {
   color: #6E707E;
   font-size: 13px;
   font-weight: bold;
   text-transform: uppercase;
   margin: 0 0 18px; }
+  .section-title span {
+    vertical-align: middle; }
 
 .top-sites-list {
   list-style: none;
   margin: 0;
   padding: 0;
   margin-inline-end: -32px; }
   @media (min-width: 672px) {
     .top-sites-list {
@@ -368,17 +370,18 @@ main {
       font-size: 13px;
       font-weight: 300;
       color: #A0A0A0;
       text-align: center; }
 
 .topic {
   font-size: 13px;
   color: #BFC0C7;
-  min-width: 780px; }
+  min-width: 780px;
+  line-height: 16px; }
   .topic ul {
     display: inline;
     padding-left: 12px; }
   .topic ul li {
     display: inline; }
   .topic ul li::after {
     content: '•';
     padding-left: 8px;
@@ -391,17 +394,17 @@ main {
     float: right;
     margin-right: 40px;
     color: #008EA4; }
   .topic .topic-read-more-logo {
     padding-right: 10px;
     margin-left: 5px;
     background-image: url("assets/topic-show-more-12.svg");
     background-repeat: no-repeat;
-    background-position-y: 2px; }
+    vertical-align: middle; }
 
 .search-wrapper {
   cursor: default;
   display: flex;
   position: relative;
   margin: 0 0 40px;
   width: 100%;
   height: 36px; }
@@ -494,17 +497,17 @@ main {
         padding: 3px 12px;
         line-height: 16px;
         display: flex;
         align-items: center; }
         .context-menu > ul > li > a:hover, .context-menu > ul > li > a:focus {
           background: #2B99FF;
           color: #FFF; }
           .context-menu > ul > li > a:hover a, .context-menu > ul > li > a:focus a {
-            color: #383E49; }
+            color: #0C0C0D; }
           .context-menu > ul > li > a:hover:hover, .context-menu > ul > li > a:hover:focus, .context-menu > ul > li > a:focus:hover, .context-menu > ul > li > a:focus:focus {
             color: #FFF; }
 
 .prefs-pane {
   font-size: 13px; }
   .prefs-pane .sidebar {
     background: #FFF;
     border-left: solid 1px rgba(0, 0, 0, 0.1);
@@ -729,24 +732,24 @@ main {
   .card-outer .card-host-name {
     color: #858585;
     font-size: 10px;
     padding-bottom: 4px;
     text-transform: uppercase; }
   .card-outer .card-title {
     margin: 0 0 2px;
     font-size: inherit;
-    word-wrap: break-word; }
+    word-wrap: break-word;
+    line-height: 19px; }
   .card-outer .card-description {
     font-size: 12px;
     margin: 0;
     word-wrap: break-word;
     overflow: hidden;
-    line-height: 18px;
-    max-height: 34px; }
+    line-height: 19px; }
   .card-outer .card-context {
     padding: 16px 16px 14px 14px;
     position: absolute;
     bottom: 0;
     left: 0;
     right: 0;
     color: #A0A0A0;
     font-size: 11px;
--- a/browser/extensions/activity-stream/data/locales.json
+++ b/browser/extensions/activity-stream/data/locales.json
@@ -149,24 +149,26 @@
   },
   "az": {
     "newtab_page_title": "Yeni Vərəq",
     "default_label_loading": "Yüklənir…",
     "header_top_sites": "Qabaqcıl Saytlar",
     "header_stories": "Qabaqcıl Hekayələr",
     "header_visit_again": "Təkrar ziyarət et",
     "header_bookmarks": "Son Əlfəcinlər",
+    "header_recommended_by": "{provider} məsləhət görür",
     "header_bookmarks_placeholder": "Hələlik heç əlfəcininiz yoxdur.",
     "header_stories_from": "qaynaq:",
     "type_label_visited": "Ziyarət edilib",
     "type_label_bookmarked": "Əlfəcinlənib",
     "type_label_synced": "Digər cihazdan sync edilib",
     "type_label_recommended": "Populyar",
     "type_label_open": "Açıq",
     "type_label_topic": "Mövzu",
+    "type_label_now": "İndi",
     "menu_action_bookmark": "Əlfəcinlə",
     "menu_action_remove_bookmark": "Əlfəcini sil",
     "menu_action_copy_address": "Ünvanı köçür",
     "menu_action_email_link": "Keçidi e-poçt ilə göndər…",
     "menu_action_open_new_window": "Yeni Pəncərədə Aç",
     "menu_action_open_private_window": "Yeni Məxfi Pəncərədə Aç",
     "menu_action_dismiss": "Rədd et",
     "menu_action_delete": "Tarixçədən Sil",
@@ -175,16 +177,17 @@
     "confirm_history_delete_p1": "Bu səhifənin bütün parçalarını tarixçənizdən silmək istədiyinizə əminsiniz?",
     "confirm_history_delete_notice_p2": "Bu əməliyyat geri alına bilməz.",
     "menu_action_save_to_pocket": "Pocket-ə Saxla",
     "search_for_something_with": "{search_term} üçün bununla axtar:",
     "search_button": "Axtar",
     "search_header": "{search_engine_name} Axtarış",
     "search_web_placeholder": "İnternetdə Axtar",
     "search_settings": "Axtarış Tənzimləmələrini Dəyiş",
+    "section_info_option": "Məlumat",
     "welcome_title": "Yeni vərəqə xoş gəldiniz",
     "welcome_body": "Firefox bu səhifədə ən uyğun əlfəcin, məqalə, video və son ziyarət etdiyiniz səhifələri göstərərək onları rahat tapmağınıza kömək edəcək.",
     "welcome_label": "Seçilmişləriniz təyin edilir",
     "time_label_less_than_minute": "<1d",
     "time_label_minute": "{number}d",
     "time_label_hour": "{number}s",
     "time_label_day": "{number}g",
     "settings_pane_button_label": "Yeni Vərəq səhifənizi özəlləşdirin",
@@ -543,24 +546,26 @@
   "cak": {},
   "cs": {
     "newtab_page_title": "Nový panel",
     "default_label_loading": "Načítání…",
     "header_top_sites": "Top stránky",
     "header_stories": "Nejlepší příběhy",
     "header_visit_again": "Znovu navštívit",
     "header_bookmarks": "Nedávno přidané záložky",
+    "header_recommended_by": "Doporučení ze služby {provider}",
     "header_bookmarks_placeholder": "Zatím nemáte uložené žádné záložky.",
     "header_stories_from": "ze šlužby",
     "type_label_visited": "Navštívené",
     "type_label_bookmarked": "V záložkách",
     "type_label_synced": "Synchronizované z jiného zařízení",
     "type_label_recommended": "Populární",
     "type_label_open": "Otevřené",
     "type_label_topic": "Téma",
+    "type_label_now": "Teď",
     "menu_action_bookmark": "Přidat do záložek",
     "menu_action_remove_bookmark": "Odebrat záložku",
     "menu_action_copy_address": "Zkopírovat adresu",
     "menu_action_email_link": "Poslat odkaz…",
     "menu_action_open_new_window": "Otevřít v novém okně",
     "menu_action_open_private_window": "Otevřít v novém anonymním okně",
     "menu_action_dismiss": "Skrýt",
     "menu_action_delete": "Smazat z historie",
@@ -569,16 +574,17 @@
     "confirm_history_delete_p1": "Opravdu chcete smazat všechny výskyty této stránky z vaší historie?",
     "confirm_history_delete_notice_p2": "Tuto akci nelze vzít zpět.",
     "menu_action_save_to_pocket": "Uložit do služby Pocket",
     "search_for_something_with": "Vyhledat {search_term} s:",
     "search_button": "Hledat",
     "search_header": "Vyhledat pomocí {search_engine_name}",
     "search_web_placeholder": "Hledat na webu",
     "search_settings": "Změnit nastavení vyhledávání",
+    "section_info_option": "Informace",
     "welcome_title": "Vítejte na stránce nového panelu",
     "welcome_body": "Tady Firefox zobrazí nejrelevantnější záložky, články, videa a stránky, které jste nedávno navštívili. Návrat k nim je tak velmi jednoduchý.",
     "welcome_label": "Rozpoznávání Vybraných stránek",
     "time_label_less_than_minute": "< 1 min",
     "time_label_minute": "{number} min",
     "time_label_hour": "{number} h",
     "time_label_day": "{number} d",
     "settings_pane_button_label": "Přizpůsobení stránky nového panelu",
@@ -613,33 +619,39 @@
     "topsites_form_add_button": "Přidat",
     "topsites_form_save_button": "Uložit",
     "topsites_form_cancel_button": "Zrušit",
     "topsites_form_url_validation": "Je vyžadována platná URL",
     "pocket_read_more": "Populární témata:",
     "pocket_read_even_more": "Zobrazit více příběhů",
     "pocket_feedback_header": "To nejlepší na webu podle hodnocení více než 25 milionů lidí.",
     "pocket_feedback_body": "Pocket, služba od Mozilly, vám pomůže najít vysoce kvalitní obsah, který byste jinak neobjevili.",
-    "pocket_send_feedback": "Odeslat zpětnou vazbu"
+    "pocket_send_feedback": "Odeslat zpětnou vazbu",
+    "topstories_empty_state": "Už jste všechno přečetli. Další příběhy ze služby {provider} tu najdete zase později. Ale pokud se nemůžete dočkat, vyberte své oblíbené téma a podívejte se na další velké příběhy z celého webu.",
+    "manual_migration_explanation": "Vyzkoušejte Firefox se svými oblíbenými stránkami a záložkami z jiného prohlížeče.",
+    "manual_migration_cancel_button": "Ne, děkuji",
+    "manual_migration_import_button": "Importovat nyní"
   },
   "cy": {
     "newtab_page_title": "Tab Newydd",
     "default_label_loading": "Llwytho…",
     "header_top_sites": "Hoff Wefannau",
     "header_stories": "Hoff Straeon",
     "header_visit_again": "Ymweld Eto",
     "header_bookmarks": "Nodau Tudalen Diweddar",
+    "header_recommended_by": "Argymhellwyd gan {provider}",
     "header_bookmarks_placeholder": "Nid oes gennych unrhyw nodau tudalen eto.",
     "header_stories_from": "oddi wrth",
     "type_label_visited": "Ymwelwyd",
     "type_label_bookmarked": "Nod Tudalen",
     "type_label_synced": "Cydweddwyd o ddyfais arall",
     "type_label_recommended": "Trendio",
     "type_label_open": "Ar Agor",
     "type_label_topic": "Pwnc",
+    "type_label_now": "Nawr",
     "menu_action_bookmark": "Nod Tudalen",
     "menu_action_remove_bookmark": "Tynnu Nod Tudalen",
     "menu_action_copy_address": "Copïo'r Cyfeiriad",
     "menu_action_email_link": "Dolen E-bost…",
     "menu_action_open_new_window": "Agor Ffenestr Newydd",
     "menu_action_open_private_window": "Agor mewn Ffenestr Preifat Newydd",
     "menu_action_dismiss": "Cau",
     "menu_action_delete": "Dileu o'r Hanes",
@@ -648,16 +660,17 @@
     "confirm_history_delete_p1": "Ydych chi'n siŵr eich bod chi am ddileu pob enghraifft o'r dudalen hon o'ch hanes?",
     "confirm_history_delete_notice_p2": "Nid oes modd dadwneud hyn.",
     "menu_action_save_to_pocket": "Cadw i Pocket",
     "search_for_something_with": "Chwilio am {search_term} gyda:",
     "search_button": "Chwilio",
     "search_header": "{search_engine_name} Chwilio",
     "search_web_placeholder": "Chwilio'r We",
     "search_settings": "Newid y Gosodiadau Chwilio",
+    "section_info_option": "Gwybodaeth",
     "welcome_title": "Croeso i dab newydd",
     "welcome_body": "Bydd Firefox yn defnyddio'r gofod hwn i ddangos y nodau tudalen, erthyglau, fideos a thudalennau mwyaf perthnasol i chi, a thudalennau fuoch yn ymweld â nhw'n ddiweddar, fel bod modd i chi ddychwelydd atyn nhw'n hawdd.",
     "welcome_label": "Adnabod eich Goreuon",
     "time_label_less_than_minute": "<1m",
     "time_label_minute": "{number}m",
     "time_label_hour": "{number}a",
     "time_label_day": "{number}d",
     "settings_pane_button_label": "Cyfaddasu eich tudalen Tab Newydd",
@@ -692,33 +705,39 @@
     "topsites_form_add_button": "Ychwanegu",
     "topsites_form_save_button": "Cadw",
     "topsites_form_cancel_button": "Diddymu",
     "topsites_form_url_validation": "Mae angen URL Ddilys",
     "pocket_read_more": "Pynciau Poblogaidd:",
     "pocket_read_even_more": "Gweld Rhagor o Straeon",
     "pocket_feedback_header": "Y gorau o'r we, wedi ei gasglu gan dros 25 miliwn o bobl.",
     "pocket_feedback_body": "Gall Pocket, sy'n rhan o deulu Mozilla, eich helpu i ganfod cynnwys o ansawdd uchel na fyddech wedi eu canfod fel arall.",
-    "pocket_send_feedback": "Anfon Adborth"
+    "pocket_send_feedback": "Anfon Adborth",
+    "topstories_empty_state": "Rydych wedi dal i fynDewch nôl rhywbryd eto am fwy o'r straeon pwysicaf gan {provider}. Methu aros? Dewiswch bwnc poblogaidd i ganfod straeon da o ar draws y we. ",
+    "manual_migration_explanation": "Profwch Firefox gyda'ch hoff wefannau a nodau tudalen o borwr arall.",
+    "manual_migration_cancel_button": "Dim Diolch",
+    "manual_migration_import_button": "Mewnforio Nawr"
   },
   "da": {
     "newtab_page_title": "Nyt faneblad",
     "default_label_loading": "Indlæser…",
     "header_top_sites": "Mest besøgte websider",
     "header_stories": "Tophistorier",
     "header_visit_again": "Besøg igen",
     "header_bookmarks": "Seneste bogmærker",
+    "header_recommended_by": "Anbefalet af {provider}",
     "header_bookmarks_placeholder": "Du har ingen bogmærker endnu.",
     "header_stories_from": "fra",
     "type_label_visited": "Besøgt",
     "type_label_bookmarked": "Bogmærket",
     "type_label_synced": "Synkroniseret fra en anden enhed",
     "type_label_recommended": "Populært",
     "type_label_open": "Åben",
     "type_label_topic": "Emne",
+    "type_label_now": "Nu",
     "menu_action_bookmark": "Bogmærk",
     "menu_action_remove_bookmark": "Fjern bogmærke",
     "menu_action_copy_address": "Kopier adresse",
     "menu_action_email_link": "Send link…",
     "menu_action_open_new_window": "Åbn i et nyt vindue",
     "menu_action_open_private_window": "Åbn i et nyt privat vindue",
     "menu_action_dismiss": "Afvis",
     "menu_action_delete": "Slet fra historik",
@@ -727,16 +746,17 @@
     "confirm_history_delete_p1": "Er du sikker på, at du vil slette alle forekomster af denne side fra din historik?",
     "confirm_history_delete_notice_p2": "Denne handling kan ikke fortrydes.",
     "menu_action_save_to_pocket": "Gem til Pocket",
     "search_for_something_with": "Søg efter {search_term} med:",
     "search_button": "Søg",
     "search_header": "{search_engine_name}-søgning",
     "search_web_placeholder": "Søg på internettet",
     "search_settings": "Skift søgeindstillinger",
+    "section_info_option": "Info",
     "welcome_title": "Velkommen til nyt faneblad",
     "welcome_body": "Firefox vil bruge denne plads til at vise dine mest relevante bogmærker, artikler, videoer og sider, du har besøgt for nylig - så kan du nemmere finde dem.",
     "welcome_label": "Finder dine højdepunkter",
     "time_label_less_than_minute": "<1 m.",
     "time_label_minute": "{number} m.",
     "time_label_hour": "{number} t.",
     "time_label_day": "{number} d.",
     "settings_pane_button_label": "Tilpas siden Nyt faneblad",
@@ -771,33 +791,39 @@
     "topsites_form_add_button": "Tilføj",
     "topsites_form_save_button": "Gem",
     "topsites_form_cancel_button": "Annuller",
     "topsites_form_url_validation": "Gyldig URL påkrævet",
     "pocket_read_more": "Populære emner:",
     "pocket_read_even_more": "Se flere historier",
     "pocket_feedback_header": "Det bedste fra nettet, udvalgt af mere end 25 millioner mennesker.",
     "pocket_feedback_body": "Pocket, en del af Mozilla-familien, hjælper dig med at opdage indhold af høj kvalitet, som du måske ellers ikke ville have fundet.",
-    "pocket_send_feedback": "Send feedback"
+    "pocket_send_feedback": "Send feedback",
+    "topstories_empty_state": "Der er ikke flere nye historier. Kom tilbage senere for at se flere tophistorier fra {provider}. Kan du ikke vente? Vælg et populært emne og find flere spændende historier fra hele verden.",
+    "manual_migration_explanation": "Prøv Firefox med dine favorit-websteder og bogmærker fra en anden browser.",
+    "manual_migration_cancel_button": "Nej tak",
+    "manual_migration_import_button": "Importer nu"
   },
   "de": {
     "newtab_page_title": "Neuer Tab",
     "default_label_loading": "Wird geladen…",
     "header_top_sites": "Meistbesuchte Seiten",
     "header_stories": "Meistgelesene Meldungen",
     "header_visit_again": "Erneut besuchen",
     "header_bookmarks": "Neue Lesezeichen",
+    "header_recommended_by": "Empfohlen von {provider}",
     "header_bookmarks_placeholder": "Sie haben noch keine Lesezeichen.",
     "header_stories_from": "von",
     "type_label_visited": "Besucht",
     "type_label_bookmarked": "Lesezeichen",
     "type_label_synced": "Von anderem Gerät synchronisiert",
     "type_label_recommended": "Populär",
     "type_label_open": "Geöffnet",
     "type_label_topic": "Thema",
+    "type_label_now": "Jetzt",
     "menu_action_bookmark": "Lesezeichen",
     "menu_action_remove_bookmark": "Lesezeichen entfernen",
     "menu_action_copy_address": "Adresse kopieren",
     "menu_action_email_link": "Link per E-Mail versenden…",
     "menu_action_open_new_window": "In neuem Fenster öffnen",
     "menu_action_open_private_window": "In neuem privaten Fenster öffnen",
     "menu_action_dismiss": "Schließen",
     "menu_action_delete": "Aus Chronik löschen",
@@ -806,16 +832,17 @@
     "confirm_history_delete_p1": "Soll wirklich jede Instanz dieser Seite aus Ihrer Chronik gelöscht werden?",
     "confirm_history_delete_notice_p2": "Diese Aktion kann nicht rückgängig gemacht werden.",
     "menu_action_save_to_pocket": "Bei Pocket speichern",
     "search_for_something_with": "Nach {search_term} suchen mit:",
     "search_button": "Suchen",
     "search_header": "{search_engine_name}-Suche",
     "search_web_placeholder": "Das Web durchsuchen",
     "search_settings": "Sucheinstellungen ändern",
+    "section_info_option": "Info",
     "welcome_title": "Willkommen im neuen Tab",
     "welcome_body": "Firefox nutzt diesen Bereich, um Ihnen Ihre wichtigsten Lesezeichen, Artikel, Videos und kürzlich besuchten Seiten anzuzeigen, damit Sie diese einfach wiederfinden.",
     "welcome_label": "Auswahl Ihrer wichtigsten Seiten",
     "time_label_less_than_minute": "< 1 min",
     "time_label_minute": "{number} m",
     "time_label_hour": "{number} h",
     "time_label_day": "{number} t",
     "settings_pane_button_label": "Neuer-Tab-Seite anpassen",
@@ -850,33 +877,39 @@
     "topsites_form_add_button": "Hinzufügen",
     "topsites_form_save_button": "Speichern",
     "topsites_form_cancel_button": "Abbrechen",
     "topsites_form_url_validation": "Gültige URL erforderlich",
     "pocket_read_more": "Beliebte Themen:",
     "pocket_read_even_more": "Weitere Nachrichten ansehen",
     "pocket_feedback_header": "Das Beste aus dem Web, zusammengetragen von 25 Millionen Menschen.",
     "pocket_feedback_body": "Pocket, ein Teil der Mozilla-Familie, hilft Ihnen beim Finden von qualitativ hochwertigen Inhalten, die Sie ansonsten vielleicht nicht gefunden hätten.",
-    "pocket_send_feedback": "Feedback senden"
+    "pocket_send_feedback": "Feedback senden",
+    "topstories_empty_state": "Jetzt kennen Sie die Neuigkeiten. Schauen Sie später wieder vorbei, um neue Informationen von {provider} zu erhalten. Können sie nicht warten? Wählen Sie ein beliebtes Thema und lesen Sie weitere interessante Geschichten aus dem Internet.",
+    "manual_migration_explanation": "Nutzen Sie Firefox mit Ihren Lieblings-Websites und Lesezeichen aus einem anderen Browser.",
+    "manual_migration_cancel_button": "Nein, danke",
+    "manual_migration_import_button": "Jetzt importieren"
   },
   "dsb": {
     "newtab_page_title": "Nowy rejtark",
     "default_label_loading": "Zacytujo se…",
     "header_top_sites": "Nejcesćej woglědane sedła",
     "header_stories": "Nejcesćej pśecytane powěźenki",
     "header_visit_again": "Hyšći raz se woglědaś",
     "header_bookmarks": "Nejnowše cytańske znamjenja",
+    "header_recommended_by": "Wót {provider} dopórucony",
     "header_bookmarks_placeholder": "Hyšći cytańske znamjenja njamaśo.",
     "header_stories_from": "wót",
     "type_label_visited": "Woglědany",
     "type_label_bookmarked": "Ako cytańske znamje skłaźony",
     "type_label_synced": "Z drugego rěda synchronizěrowany",
     "type_label_recommended": "Popularny",
     "type_label_open": "Wócynjony",
     "type_label_topic": "Tema",
+    "type_label_now": "Něnto",
     "menu_action_bookmark": "Ako cytańske znamje składowaś",
     "menu_action_remove_bookmark": "Cytańske znamje wótpóraś",
     "menu_action_copy_address": "Adresu kopěrowaś",
     "menu_action_email_link": "Wótkaz e-mailowaś…",
     "menu_action_open_new_window": "W nowem woknje wócyniś",
     "menu_action_open_private_window": "W nowem priwatnem woknje wócyniś",
     "menu_action_dismiss": "Zachyśiś",
     "menu_action_delete": "Z historije lašowaś",
@@ -885,16 +918,17 @@
     "confirm_history_delete_p1": "Cośo napšawdu kuždu instancu toś togo boka ze swójeje historije lašowaś?",
     "confirm_history_delete_notice_p2": "Toś ta akcija njedajo se anulěrowaś.",
     "menu_action_save_to_pocket": "Pla Pocket składowaś",
     "search_for_something_with": "Za {search_term} pytaś z:",
     "search_button": "Pytaś",
     "search_header": "Z {search_engine_name} pytaś",
     "search_web_placeholder": "Web pśepytaś",
     "search_settings": "Pytańske nastajenja změniś",
+    "section_info_option": "Info",
     "welcome_title": "Witajśo k nowemu rejtarkoju",
     "welcome_body": "Firefox buźo toś ten rum wužywaś, aby waše nejwažnjejše cytańske znamjenja, nastawki, wideo a rowno woglědane boki pokazał, aby mógł se lažko k nim wrośiś.",
     "welcome_label": "Wuběranje wašych nejwažnjejšych bokow",
     "time_label_less_than_minute": "<1m",
     "time_label_minute": "{number} m",
     "time_label_hour": "{number} h",
     "time_label_day": "",
     "settings_pane_button_label": "Bok wašogo nowego rejtarka pśiměriś",
@@ -929,33 +963,39 @@
     "topsites_form_add_button": "Pśidaś",
     "topsites_form_save_button": "Składowaś",
     "topsites_form_cancel_button": "Pśetergnuś",
     "topsites_form_url_validation": "Płaśiwy URL trěbny",
     "pocket_read_more": "Woblubowane temy:",
     "pocket_read_even_more": "Dalšne powěźeńki se woglědaś",
     "pocket_feedback_header": "Nejlěpše z weba, zezběrane wót wěcej ako 25 milionow luźi.",
     "pocket_feedback_body": "Pocket, źěl familije Mozilla, buźo pomagaś, was z wopśimjeśim wusokeje kwality zwězowaś, kótaryž njeby wy snaź howac namakał.",
-    "pocket_send_feedback": "Komentar pósłaś"
+    "pocket_send_feedback": "Komentar pósłaś",
+    "topstories_empty_state": "To jo nachylu wšykno. Wrośćo se pózdźej wjelicnych tšojeńkow dla wót {provider}. Njamóžośo cakaś? Wubjeŕśo woblubowanu temu, aby dalšne wjelicne tšojeńka we webje namakał.",
+    "manual_migration_explanation": "Wopytajśo Firefox ze swójimi nejlubšymi websedłami a cytańskimi znamjenjami z drugego wobglědowaka.",
+    "manual_migration_cancel_button": "Ně, źěkujom se",
+    "manual_migration_import_button": "Něnto importěrowaś"
   },
   "el": {
     "newtab_page_title": "Νέα καρτέλα",
     "default_label_loading": "Φόρτωση…",
     "header_top_sites": "Κορυφαίες ιστοσελίδες",
     "header_stories": "Κορυφαίες ιστορίες",
     "header_visit_again": "Επίσκεψη ξανά",
     "header_bookmarks": "Πρόσφατοι σελιδοδείκτες",
+    "header_recommended_by": "Προτεινόμενο από τον πάροχο {provider}",
     "header_bookmarks_placeholder": "Δεν έχετε κανένα σελιδοδείκτη ακόμα.",
     "header_stories_from": "από",
     "type_label_visited": "Από ιστορικό",
     "type_label_bookmarked": "Από σελιδοδείκτες",
     "type_label_synced": "Συγχρονισμένα από άλλη συσκευή",
     "type_label_recommended": "Τάσεις",
     "type_label_open": "Ανοικτό",
     "type_label_topic": "Θέμα",
+    "type_label_now": "Τώρα",
     "menu_action_bookmark": "Προσθήκη σελιδοδείκτη",
     "menu_action_remove_bookmark": "Αφαίρεση σελιδοδείκτη",
     "menu_action_copy_address": "Αντιγραφή διεύθυνσης",
     "menu_action_email_link": "Αποστολή συνδέσμου…",
     "menu_action_open_new_window": "Άνοιγμα σε νέο παράθυρο",
     "menu_action_open_private_window": "Άνοιγμα σε νέο ιδιωτικό παράθυρο",
     "menu_action_dismiss": "Απόρριψη",
     "menu_action_delete": "Διαγραφή από ιστορικό",
@@ -964,16 +1004,17 @@
     "confirm_history_delete_p1": "Θέλετε σίγουρα να διαγράψετε κάθε παρουσία της σελίδας αυτής από το ιστορικό σας;",
     "confirm_history_delete_notice_p2": "Αυτή η ενέργεια δεν μπορεί να αναιρεθεί.",
     "menu_action_save_to_pocket": "Αποθήκευση στο Pocket",
     "search_for_something_with": "Αναζήτηση για {search_term} με:",
     "search_button": "Αναζήτηση",
     "search_header": "Αναζήτηση {search_engine_name}",
     "search_web_placeholder": "Αναζήτηση στον ιστό",
     "search_settings": "Αλλαγή ρυθμίσεων αναζήτησης",
+    "section_info_option": "Πληροφορίες",
     "welcome_title": "Καλώς ορίσατε στη νέα καρτέλα",
     "welcome_body": "Το Firefox θα χρησιμοποιήσει αυτό το χώρο για να εμφανίσει τους πιο σχετικούς σελιδοδείκτες, άρθρα, βίντεο και σελίδες που επισκεφθήκατε πρόσφατα, ώστε να έχετε εύκολη πρόσβαση.",
     "welcome_label": "Αναγνώριση κορυφαίων στιγμών",
     "time_label_less_than_minute": "<1λ",
     "time_label_minute": "{number}λ",
     "time_label_hour": "{number}ώ",
     "time_label_day": "{number}η",
     "settings_pane_button_label": "Προσαρμογή της σελίδας Νέας Καρτέλας",
@@ -1008,17 +1049,21 @@
     "topsites_form_add_button": "Προσθήκη",
     "topsites_form_save_button": "Αποθήκευση",
     "topsites_form_cancel_button": "Ακύρωση",
     "topsites_form_url_validation": "Απαιτείται έγκυρο URL",
     "pocket_read_more": "Δημοφιλή θέματα:",
     "pocket_read_even_more": "Προβολή περισσότερων ιστοριών",
     "pocket_feedback_header": "Τα καλύτερα του διαδικτύου, παρέχονται από πάνω από 25 εκατομμύρια άτομα.",
     "pocket_feedback_body": "Το Pocket, ένα μέλος της οικογένειας Mozilla, θα σάς βοηθήσει να ανακαλύψετε περιεχόμενο υψηλής ποιότητας που ίσως να μην βρίσκατε διαφορετικά.",
-    "pocket_send_feedback": "Αποστολή σχολίων"
+    "pocket_send_feedback": "Αποστολή σχολίων",
+    "topstories_empty_state": "Δεν υπάρχει κάτι νεότερο. Ελέγξτε αργότερα για περισσότερες ιστορίες από τον πάροχο {provider}. Δεν μπορείτε να περιμένετε; Διαλέξτε κάποιο από τα δημοφιλή θέματα και ανακαλύψτε ενδιαφέρουσες ιστορίες από όλο τον Ιστό.",
+    "manual_migration_explanation": "Δοκιμάστε τον Firefox για τις αγαπημένες σας σελίδες και σελιδοδείκτες από άλλους περιηγητές.",
+    "manual_migration_cancel_button": "Όχι ευχαριστώ",
+    "manual_migration_import_button": "Εισαγωγή τώρα"
   },
   "en-GB": {
     "newtab_page_title": "New Tab",
     "default_label_loading": "Loading…",
     "header_top_sites": "Top Sites",
     "header_stories": "Top Stories",
     "header_visit_again": "Visit Again",
     "header_bookmarks": "Recent Bookmarks",
@@ -1262,24 +1307,26 @@
   },
   "es-AR": {
     "newtab_page_title": "Nueva pestaña",
     "default_label_loading": "Cargando…",
     "header_top_sites": "Más visitados",
     "header_stories": "Historias principales",
     "header_visit_again": "Visitar de nuevo",
     "header_bookmarks": "Marcadores recientes",
+    "header_recommended_by": "Recomendado por {provider}",
     "header_bookmarks_placeholder": "Todavía no hay ningún marcador.",
     "header_stories_from": "de",
     "type_label_visited": "Visitados",
     "type_label_bookmarked": "Marcados",
     "type_label_synced": "Sincronizados de otro dispositivo",
     "type_label_recommended": "Tendencias",
     "type_label_open": "Abrir",
     "type_label_topic": "Tópico",
+    "type_label_now": "Ahora",
     "menu_action_bookmark": "Marcador",
     "menu_action_remove_bookmark": "Eliminar marcador",
     "menu_action_copy_address": "Copiar dirección",
     "menu_action_email_link": "Enlace por correo electrónico…",
     "menu_action_open_new_window": "Abrir en nueva ventana",
     "menu_action_open_private_window": "Abrir en nueva ventana privada",
     "menu_action_dismiss": "Descartar",
     "menu_action_delete": "Borrar del historial",
@@ -1288,16 +1335,17 @@
     "confirm_history_delete_p1": "¿Está seguro de querer borrar cualquier instancia de esta página del historial?",
     "confirm_history_delete_notice_p2": "Esta acción no puede deshacerse.",
     "menu_action_save_to_pocket": "Guardar en Pocket",
     "search_for_something_with": "Buscar {search_term} con:",
     "search_button": "Buscar",
     "search_header": "Buscar con {search_engine_name}",
     "search_web_placeholder": "Buscar en la web",
     "search_settings": "Cambiar opciones de búsqueda",
+    "section_info_option": "Información",
     "welcome_title": "Bienvenido a una nueva pestaña",
     "welcome_body": "Firefox usará este espacio para mostrar sus marcadores, artículos, videos y páginas más relevantes que se hayan visitado para poder volver más fácilmente.",
     "welcome_label": "Identificar los destacados",
     "time_label_less_than_minute": "<1m",
     "time_label_minute": "{number}m",
     "time_label_hour": "{number}h",
     "time_label_day": "{number}d",
     "settings_pane_button_label": "Personalizar la página nueva pestaña",
@@ -1332,17 +1380,20 @@
     "topsites_form_add_button": "Agregar",
     "topsites_form_save_button": "Guardar",
     "topsites_form_cancel_button": "Cancelar",
     "topsites_form_url_validation": "Se requiere URL válida",
     "pocket_read_more": "Tópicos populares:",
     "pocket_read_even_more": "Ver más historias",
     "pocket_feedback_header": "Lo mejor de la web, seleccionado por más de 25 millones de personas.",
     "pocket_feedback_body": "Pocket, parte de la familia Mozilla, ayudará a conectarte con contenido de alta calidad que no podrías haber encontrado de otra forma.",
-    "pocket_send_feedback": "Enviar opinión"
+    "pocket_send_feedback": "Enviar opinión",
+    "manual_migration_explanation": "Probá Firefox con tus sitios favoritos y marcadores de otro navegador.",
+    "manual_migration_cancel_button": "No gracias",
+    "manual_migration_import_button": "Importar ahora"
   },
   "es-CL": {
     "newtab_page_title": "Nueva pestaña",
     "default_label_loading": "Cargando…",
     "header_top_sites": "Sitios frecuentes",
     "header_stories": "Historias populares",
     "header_visit_again": "Volver a visitar",
     "header_bookmarks": "Marcadores recientes",
@@ -1420,24 +1471,26 @@
   },
   "es-ES": {
     "newtab_page_title": "Nueva pestaña",
     "default_label_loading": "Cargando…",
     "header_top_sites": "Sitios favoritos",
     "header_stories": "Historias populares",
     "header_visit_again": "Visitar de nuevo",
     "header_bookmarks": "Marcadores recientes",
+    "header_recommended_by": "Recomendado por {provider}",
     "header_bookmarks_placeholder": "Todavía no tienes ningún marcador.",
     "header_stories_from": "desde",
     "type_label_visited": "Visitados",
     "type_label_bookmarked": "En marcadores",
     "type_label_synced": "Sincronizado desde otro dispositivo",
     "type_label_recommended": "Tendencias",
     "type_label_open": "Abrir",
     "type_label_topic": "Tema",
+    "type_label_now": "Ahora",
     "menu_action_bookmark": "Marcador",
     "menu_action_remove_bookmark": "Eliminar marcador",
     "menu_action_copy_address": "Copiar dirección",
     "menu_action_email_link": "Enviar enlace…",
     "menu_action_open_new_window": "Abrir en una nueva ventana",
     "menu_action_open_private_window": "Abrir en una nueva ventana privada",
     "menu_action_dismiss": "Ignorar",
     "menu_action_delete": "Eliminar del historial",
@@ -1446,16 +1499,17 @@
     "confirm_history_delete_p1": "¿Estás seguro de que quieres eliminar de tu historial todas las instancias de esta página?",
     "confirm_history_delete_notice_p2": "Esta acción no se puede deshacer.",
     "menu_action_save_to_pocket": "Guardar en Pocket",
     "search_for_something_with": "Buscar {search_term} con:",
     "search_button": "Buscar",
     "search_header": "Búsqueda de {search_engine_name}",
     "search_web_placeholder": "Buscar en la Web",
     "search_settings": "Cambiar ajustes de búsqueda",
+    "section_info_option": "Info",
     "welcome_title": "Bienvenido a la nueva pestaña",
     "welcome_body": "Firefox utilizará este espacio para mostrarte los marcadores, artículos y vídeos más relevantes y las páginas que has visitado recientemente, para que puedas acceder más rápido.",
     "welcome_label": "Identificar lo más destacado para ti",
     "time_label_less_than_minute": "<1m",
     "time_label_minute": "{number}m",
     "time_label_hour": "{number}h",
     "time_label_day": "{number}d",
     "settings_pane_button_label": "Personalizar la página Nueva pestaña",
@@ -1490,17 +1544,21 @@
     "topsites_form_add_button": "Agregar",
     "topsites_form_save_button": "Guardar",
     "topsites_form_cancel_button": "Cancelar",
     "topsites_form_url_validation": "Se requiere una URL válida",
     "pocket_read_more": "Temas populares:",
     "pocket_read_even_more": "Ver más historias",
     "pocket_feedback_header": "Lo mejor de la web, confirmado por más de 25 millones de personas.",
     "pocket_feedback_body": "Pocket, que forma parte de la familia de Mozilla, te ayudará a encontrar contenido de alta calidad que puede que no encuentres de otra forma.",
-    "pocket_send_feedback": "Enviar comentario"
+    "pocket_send_feedback": "Enviar comentario",
+    "topstories_empty_state": "Ya estás al día. Vuelve luego y busca más historias de {provider}. ¿No puedes esperar? Selecciona un tema popular y encontrás más historias alucinantes por toda la web.",
+    "manual_migration_explanation": "Prueba Firefox con tusmarcadores y sitios favoritos importados desde otro navegador.",
+    "manual_migration_cancel_button": "No, gracias",
+    "manual_migration_import_button": "Importar ahora"
   },
   "es-MX": {
     "newtab_page_title": "Nueva pestaña",
     "default_label_loading": "Cargando…",
     "header_top_sites": "Sitios favoritos",
     "header_stories": "Historias populares",
     "header_visit_again": "Visitar de nuevo",
     "header_bookmarks": "Marcadores recientes",
@@ -1804,24 +1862,26 @@
   },
   "fr": {
     "newtab_page_title": "Nouvel onglet",
     "default_label_loading": "Chargement…",
     "header_top_sites": "Sites les plus visités",
     "header_stories": "Articles populaires",
     "header_visit_again": "Visiter à nouveau",
     "header_bookmarks": "Marque-pages récents",
+    "header_recommended_by": "Recommandé par {provider}",
     "header_bookmarks_placeholder": "Vous ne possédez aucun marque-page pour l’instant.",
     "header_stories_from": "par",
     "type_label_visited": "Visité",
     "type_label_bookmarked": "Ajouté aux marque-pages",
     "type_label_synced": "Synchronisé depuis un autre appareil",
     "type_label_recommended": "Tendance",
     "type_label_open": "Ouvert",
     "type_label_topic": "Thème",
+    "type_label_now": "Maintenant",
     "menu_action_bookmark": "Marquer cette page",
     "menu_action_remove_bookmark": "Supprimer le marque-page",
     "menu_action_copy_address": "Copier l’adresse",
     "menu_action_email_link": "Envoyer un lien par courriel…",
     "menu_action_open_new_window": "Ouvrir dans une nouvelle fenêtre",
     "menu_action_open_private_window": "Ouvrir dans une nouvelle fenêtre privée",
     "menu_action_dismiss": "Retirer",
     "menu_action_delete": "Supprimer de l’historique",
@@ -1830,28 +1890,29 @@
     "confirm_history_delete_p1": "Voulez-vous vraiment supprimer de l’historique toutes les occurrences de cette page ?",
     "confirm_history_delete_notice_p2": "Cette action est irréversible.",
     "menu_action_save_to_pocket": "Enregistrer dans Pocket",
     "search_for_something_with": "Recherche pour {search_term} avec :",
     "search_button": "Rechercher",
     "search_header": "Recherche {search_engine_name}",
     "search_web_placeholder": "Rechercher sur le Web",
     "search_settings": "Paramètres de recherche",
+    "section_info_option": "Informations",
     "welcome_title": "Bienvenue sur la page Nouvel onglet",
     "welcome_body": "Firefox utilisera cet espace pour afficher des éléments pertinents, comme des marque-pages, des articles, des vidéos, et des pages que vous avez visitées, afin que vous les retrouviez facilement.",
     "welcome_label": "Identification des éléments-clés",
     "time_label_less_than_minute": "<1 min",
     "time_label_minute": "{number} min",
     "time_label_hour": "{number} h",
     "time_label_day": "{number} j",
     "settings_pane_button_label": "Personnaliser la page Nouvel onglet",
     "settings_pane_header": "Préférences Nouvel onglet",
     "settings_pane_body": "Choisissez ce qui s’affiche à l’ouverture d’un nouvel onglet.",
     "settings_pane_search_header": "Recherche",
-    "settings_pane_search_body": "Effectuez une recherche sur le Web à partir du nouvel onglet.",
+    "settings_pane_search_body": "Effectuez une recherche sur le Web depuis le nouvel onglet.",
     "settings_pane_topsites_header": "Sites les plus visités",
     "settings_pane_topsites_body": "Accédez aux sites que vous consultez le plus.",
     "settings_pane_topsites_options_showmore": "Afficher deux lignes",
     "settings_pane_bookmarks_header": "Marque-pages récents",
     "settings_pane_bookmarks_body": "Vos nouveaux marque-pages, facilement accessibles.",
     "settings_pane_visit_again_header": "Visiter à nouveau",
     "settings_pane_visit_again_body": "Firefox affichera des extraits de votre historique de navigation dont vous pourriez vouloir vous souvenir ou que vous pourriez vouloir revisiter.",
     "settings_pane_pocketstories_header": "Articles populaires",
@@ -1874,33 +1935,39 @@
     "topsites_form_add_button": "Ajouter",
     "topsites_form_save_button": "Enregistrer",
     "topsites_form_cancel_button": "Annuler",
     "topsites_form_url_validation": "Adresse web valide requise",
     "pocket_read_more": "Sujets populaires :",
     "pocket_read_even_more": "Afficher plus d’articles",
     "pocket_feedback_header": "Le meilleur du Web, sélectionné par plus de 25 millions de personnes.",
     "pocket_feedback_body": "Pocket, un membre de la famille Mozilla, vous aide à découvrir du contenu de grande qualité que vous auriez pu manquer dans le cas contraire.",
-    "pocket_send_feedback": "Donner mon avis"
+    "pocket_send_feedback": "Donner mon avis",
+    "topstories_empty_state": "Il n’y en a pas d’autres. Revenez plus tard pour plus d’articles de {provider}. Vous ne voulez pas attendre ? Choisissez un sujet parmi les plus populaires pour découvrir d’autres articles intéressants sur le Web.",
+    "manual_migration_explanation": "Essayez Firefox avec vos sites et marque-pages préférés, importés depuis un autre navigateur.",
+    "manual_migration_cancel_button": "Non merci",
+    "manual_migration_import_button": "Importer maintenant"
   },
   "fy-NL": {
     "newtab_page_title": "Nij ljepblêd",
     "default_label_loading": "Lade…",
     "header_top_sites": "Topwebsites",
     "header_stories": "Topferhalen",
     "header_visit_again": "Nochris besykje",
     "header_bookmarks": "Resinte blêdwizers",
+    "header_recommended_by": "Oanrekommandearre troch {provider}",
     "header_bookmarks_placeholder": "Jo hawwe noch gjin inkelde blêdwizer.",
     "header_stories_from": "fan",
     "type_label_visited": "Besocht",
     "type_label_bookmarked": "Blêdwizer makke",
     "type_label_synced": "Syngronisearre fan oar apparaat ôf",
     "type_label_recommended": "Trending",
     "type_label_open": "Iepene",
     "type_label_topic": "Underwerp",
+    "type_label_now": "No",
     "menu_action_bookmark": "Blêdwizer",
     "menu_action_remove_bookmark": "Blêdwizer fuortsmite",
     "menu_action_copy_address": "Adres kopiearje",
     "menu_action_email_link": "Keppeling e-maile…",
     "menu_action_open_new_window": "Iepenje yn in nij finster",
     "menu_action_open_private_window": "Iepenje yn in nij priveefinster",
     "menu_action_dismiss": "Fuortsmite",
     "menu_action_delete": "Fuortsmite út skiednis",
@@ -1909,16 +1976,17 @@
     "confirm_history_delete_p1": "Binne jo wis dat jo elke ferwizing fan dizze side út jo skiednis fuortsmite wolle?",
     "confirm_history_delete_notice_p2": "Dizze aksje kin net ûngedien makke wurde.",
     "menu_action_save_to_pocket": "Bewarje nei Pocket",
     "search_for_something_with": "Sykje nei {search_term} mei:",
     "search_button": "Sykje",
     "search_header": "{search_engine_name} trochsykje",
     "search_web_placeholder": "Sykje op it web",
     "search_settings": "Sykynstellingen wizigje",
+    "section_info_option": "Ynfo",
     "welcome_title": "Wolkom by it nije ljepblêd",
     "welcome_body": "Firefox brûkt dizze romte om jo meast relevante blêdwizers, artikelen, fideo’s en siden dy't jo koartlyn besocht hawwe wer te jaan, sadat jo dizze ienfâldichwei weromfine kinne.",
     "welcome_label": "Jo hichtepunten oantsjutte",
     "time_label_less_than_minute": "< 1 m",
     "time_label_minute": "{number} m",
     "time_label_hour": "{number} o",
     "time_label_day": "{number} d",
     "settings_pane_button_label": "Jo side foar nije ljepblêden oanpasse",
@@ -1953,17 +2021,21 @@
     "topsites_form_add_button": "Tafoegje",
     "topsites_form_save_button": "Bewarje",
     "topsites_form_cancel_button": "Annulearje",
     "topsites_form_url_validation": "Jildige URL fereaske",
     "pocket_read_more": "Populêre ûnderwerpen:",
     "pocket_read_even_more": "Mear ferhalen besjen",
     "pocket_feedback_header": "It bêste fan it web, sammele troch mear as 25 miljoen minsken.",
     "pocket_feedback_body": "Pocket, part fan de Mozilla-famylje, sil jo helpe te ferbinen mei hege kwaliteit ynhâld dy't jo oars miskien net fûn hienen.",
-    "pocket_send_feedback": "Kommentaar ferstjoere"
+    "pocket_send_feedback": "Kommentaar ferstjoere",
+    "topstories_empty_state": "Jo binne by. Kom letter werom foar mear ferhalen fan {provider}. Kin jo net wachtsje? Selektearje in populêr ûnderwerp om mear ferhalen fan it ynternet te finen.",
+    "manual_migration_explanation": "Probearje Firefox mei jo favorite websites en blêdwizers fan in oare browser.",
+    "manual_migration_cancel_button": "Nee tankewol",
+    "manual_migration_import_button": "No ymportearje"
   },
   "ga-IE": {
     "newtab_page_title": "Cluaisín Nua",
     "default_label_loading": "Á Lódáil…",
     "header_top_sites": "Barrshuímh",
     "header_stories": "Barrscéalta",
     "header_visit_again": "Cuairt Arís",
     "header_bookmarks": "Leabharmharcanna Le Déanaí",
@@ -2334,24 +2406,26 @@
   },
   "hsb": {
     "newtab_page_title": "Nowy rajtark",
     "default_label_loading": "Začituje so…",
     "header_top_sites": "Najhusćišo wopytane sydła",
     "header_stories": "Najhusćišo přečitane zdźělenki",
     "header_visit_again": "Hišće raz wopytać",
     "header_bookmarks": "Najnowše zapołožki",
+    "header_recommended_by": "Wot {provider} doporučeny",
     "header_bookmarks_placeholder": "Hišće zapołožki nimaće.",
     "header_stories_from": "wot",
     "type_label_visited": "Wopytany",
     "type_label_bookmarked": "Jako zapołožka składowany",
     "type_label_synced": "Z druheho grata synchronizowany",
     "type_label_recommended": "Popularny",
     "type_label_open": "Wočinjeny",
     "type_label_topic": "Tema",
+    "type_label_now": "Nětko",
     "menu_action_bookmark": "Zapołožki składować",
     "menu_action_remove_bookmark": "Zapołožku wotstronić",
     "menu_action_copy_address": "Adresu kopěrować",
     "menu_action_email_link": "Wotkaz e-mejlować…",
     "menu_action_open_new_window": "W nowym woknje wočinić",
     "menu_action_open_private_window": "W nowym priwatnym woknje wočinić",
     "menu_action_dismiss": "Zaćisnyć",
     "menu_action_delete": "Z historije zhašeć",
@@ -2360,16 +2434,17 @@
     "confirm_history_delete_p1": "Chceće woprawdźe kóždu instancu tuteje strony ze swojeje historije zhašeć?",
     "confirm_history_delete_notice_p2": "Tuta akcija njeda so cofnyć.",
     "menu_action_save_to_pocket": "Pola Pocket składować",
     "search_for_something_with": "Za {search_term} pytać z:",
     "search_button": "Pytać",
     "search_header": "Z {search_engine_name} pytać",
     "search_web_placeholder": "Web přepytać",
     "search_settings": "Pytanske nastajenja změnić",
+    "section_info_option": "Info",
     "welcome_title": "Witajće k nowemu rajtarkej",
     "welcome_body": "Firefox budźe tutón rum wužiwać, zo by waše najwažniše zapołožki, nastawki, wideja a runje wopytane strony pokazał, zo byšće móhł so lochko k nim wróćić.",
     "welcome_label": "Wuběranje wašich najwažnišich stronow",
     "time_label_less_than_minute": "< 1 min",
     "time_label_minute": "{number} m",
     "time_label_hour": "{number} h",
     "time_label_day": "",
     "settings_pane_button_label": "Stronu wašeho noweho rajtarka přiměrić",
@@ -2404,33 +2479,39 @@
     "topsites_form_add_button": "Přidać",
     "topsites_form_save_button": "Składować",
     "topsites_form_cancel_button": "Přetorhnyć",
     "topsites_form_url_validation": "Płaćiwy URL trěbny",
     "pocket_read_more": "Woblubowane temy:",
     "pocket_read_even_more": "Dalše zdźělenki sej wobhladać",
     "pocket_feedback_header": "Najlěpše z weba, zhromadźene wot wjace hač 25 milionow ludźi.",
     "pocket_feedback_body": "Pocket, dźěl swójby Mozilla, budźe pomhać, was z wobsahom wysokeje kwality zwjazować, kotryž njebyšće snano hewak namakał.",
-    "pocket_send_feedback": "Komentar pósłać"
+    "pocket_send_feedback": "Komentar pósłać",
+    "topstories_empty_state": "To je nachwilu wšitko. Wróćće so pozdźišo dalšich wulkotnych stawiznow dla wot {provider}. Njemóžeće čakać? Wubjerće woblubowanu temu, zo byšće dalše wulkotne stawizny z weba namakał.",
+    "manual_migration_explanation": "Wupruwujće Firefox ze swojimi najlubšimi websydłami a zapołožkami z druheho wobhladowaka.",
+    "manual_migration_cancel_button": "Ně, dźakuju so",
+    "manual_migration_import_button": "Nětko importować"
   },
   "hu": {
     "newtab_page_title": "Új lap",
     "default_label_loading": "Betöltés…",
     "header_top_sites": "Népszerű oldalak",
     "header_stories": "Népszerű történetek",
     "header_visit_again": "Látogasson el ismét",
     "header_bookmarks": "Friss könyvjelzők",
+    "header_recommended_by": "A(z) {provider} ajánlásával",
     "header_bookmarks_placeholder": "Még nincs könyvjelzője.",
     "header_stories_from": "innen:",
     "type_label_visited": "Látogatott",
     "type_label_bookmarked": "Könyvjelzőzött",
     "type_label_synced": "Másik eszközről szinkronizálva",
     "type_label_recommended": "Népszerű",
     "type_label_open": "Megnyitás",
     "type_label_topic": "Téma",
+    "type_label_now": "Most",
     "menu_action_bookmark": "Könyvjelzőzés",
     "menu_action_remove_bookmark": "Könyvjelző eltávolítása",
     "menu_action_copy_address": "Cím másolása",
     "menu_action_email_link": "Hivatkozás küldése e-mailben…",
     "menu_action_open_new_window": "Megnyitás új ablakban",
     "menu_action_open_private_window": "Megnyitás új privát ablakban",
     "menu_action_dismiss": "Elutasítás",
     "menu_action_delete": "Törlés az előzményekből",
@@ -2439,16 +2520,17 @@
     "confirm_history_delete_p1": "Biztosan törli ezen oldal minden példányát az előzményekből?",
     "confirm_history_delete_notice_p2": "Ez a művelet nem vonható vissza.",
     "menu_action_save_to_pocket": "Mentés a Pocketbe",
     "search_for_something_with": "„{search_term}” keresése ezzel:",
     "search_button": "Keresés",
     "search_header": "{search_engine_name} keresés",
     "search_web_placeholder": "Keresés a weben",
     "search_settings": "Keresési beállítások módosítása",
+    "section_info_option": "Információ",
     "welcome_title": "Üdvözöljük az új lapon",
     "welcome_body": "A Firefox ezt a területet a leginkább releváns könyvjelzők, cikkek, videók és nemrég látogatott oldalak megjelenítésére fogja használni, így könnyedén visszatalálhat hozzájuk.",
     "welcome_label": "A kiemeléseinek azonosítása",
     "time_label_less_than_minute": "<1 p",
     "time_label_minute": "{number} p",
     "time_label_hour": "{number} ó",
     "time_label_day": "{number} n",
     "settings_pane_button_label": "Az Új lap oldal személyre szabása",
@@ -2483,17 +2565,21 @@
     "topsites_form_add_button": "Hozzáadás",
     "topsites_form_save_button": "Mentés",
     "topsites_form_cancel_button": "Mégse",
     "topsites_form_url_validation": "Érvényes URL szükséges",
     "pocket_read_more": "Népszerű témák:",
     "pocket_read_even_more": "További történetek",
     "pocket_feedback_header": "A web legjava, több mint 25 millió ember válogatásában.",
     "pocket_feedback_body": "A Pocket a Mozilla család tagja, segít az olyan jó minőségű tartalmak fellelésében, melyekkel egyébként nem is találkozott volna.",
-    "pocket_send_feedback": "Visszajelzés küldése"
+    "pocket_send_feedback": "Visszajelzés küldése",
+    "topstories_empty_state": "Már felzárkózott. Nézzen vissza később a legújabb {provider} hírekért. Nem tud várni? Válasszon egy népszerű témát, hogy még több sztorit találjon a weben.",
+    "manual_migration_explanation": "Próbálja ki a Firefoxot egy másik böngészőben lévő kedvenc oldalaival és könyvjelzőivel.",
+    "manual_migration_cancel_button": "Köszönöm, nem",
+    "manual_migration_import_button": "Importálás most"
   },
   "hy-AM": {
     "newtab_page_title": "Նոր ներդիր",
     "default_label_loading": "Բեռնվում է...",
     "header_top_sites": "Լավագույն կայքեր",
     "header_highlights": "Գունանշում",
     "type_label_visited": "Այցելած",
     "type_label_bookmarked": "Էջանշված",
@@ -2594,24 +2680,26 @@
   "is": {},
   "it": {
     "newtab_page_title": "Nuova scheda",
     "default_label_loading": "Caricamento…",
     "header_top_sites": "Siti principali",
     "header_stories": "Storie principali",
     "header_visit_again": "Visita di nuovo",
     "header_bookmarks": "Segnalibri recenti",
+    "header_recommended_by": "Consigliato da {provider}",
     "header_bookmarks_placeholder": "Non è ancora disponibile alcun segnalibro.",
     "header_stories_from": "da",
     "type_label_visited": "Visitato",
     "type_label_bookmarked": "Nei segnalibri",
     "type_label_synced": "Sincronizzato da un altro dispositivo",
     "type_label_recommended": "Di tendenza",
     "type_label_open": "Apri",
     "type_label_topic": "Argomento",
+    "type_label_now": "Adesso",
     "menu_action_bookmark": "Aggiungi ai segnalibri",
     "menu_action_remove_bookmark": "Elimina segnalibro",
     "menu_action_copy_address": "Copia indirizzo",
     "menu_action_email_link": "Invia link per email…",
     "menu_action_open_new_window": "Apri in una nuova finestra",
     "menu_action_open_private_window": "Apri in una nuova finestra anonima",
     "menu_action_dismiss": "Rimuovi",
     "menu_action_delete": "Elimina dalla cronologia",
@@ -2620,16 +2708,17 @@
     "confirm_history_delete_p1": "Eliminare tutte le occorrenze di questa pagina dalla cronologia?",
     "confirm_history_delete_notice_p2": "Questa operazione non può essere annullata.",
     "menu_action_save_to_pocket": "Salva in Pocket",
     "search_for_something_with": "Cerca {search_term} con:",
     "search_button": "Cerca",
     "search_header": "Ricerca {search_engine_name}",
     "search_web_placeholder": "Cerca sul Web",
     "search_settings": "Cambia impostazioni di ricerca",
+    "section_info_option": "Info",
     "welcome_title": "Benvenuto nella nuova scheda",
     "welcome_body": "Firefox utilizzerà questo spazio per visualizzare gli elementi più significativi, come segnalibri, articoli, video e pagine visitate di recente, in modo che siano sempre facili da raggiungere.",
     "welcome_label": "Identificazione elementi in evidenza…",
     "time_label_less_than_minute": "<1m",
     "time_label_minute": "{number}m",
     "time_label_hour": "{number}h",
     "time_label_day": "{number}g",
     "settings_pane_button_label": "Personalizza la pagina Nuova scheda",
@@ -2664,33 +2753,39 @@
     "topsites_form_add_button": "Aggiungi",
     "topsites_form_save_button": "Salva",
     "topsites_form_cancel_button": "Annulla",
     "topsites_form_url_validation": "È necessario fornire un URL valido",
     "pocket_read_more": "Argomenti popolari:",
     "pocket_read_even_more": "Visualizza altre storie",
     "pocket_feedback_header": "Il meglio del web, selezionato da 25 milioni di persone.",
     "pocket_feedback_body": "Grazie a Pocket, un componente della famiglia Mozilla, puoi raggiungere contenuti di alta qualità che altrimenti potrebbero sfuggirti.",
-    "pocket_send_feedback": "Invia feedback"
+    "pocket_send_feedback": "Invia feedback",
+    "topstories_empty_state": "Non c'è altro. Controlla più tardi per altre storie da {provider}. Non vuoi aspettare? Seleziona un argomento tra quelli più popolari per scoprire altre notizie interessanti dal Web.",
+    "manual_migration_explanation": "Prova Firefox con i siti preferiti e i segnalibri importati da un altro browser.",
+    "manual_migration_cancel_button": "No grazie",
+    "manual_migration_import_button": "Importa adesso"
   },
   "ja": {
     "newtab_page_title": "新しいタブ",
     "default_label_loading": "読み込み中...",
     "header_top_sites": "トップサイト",
     "header_stories": "トップ記事",
     "header_visit_again": "再度訪れる",
     "header_bookmarks": "最近のブックマーク",
+    "header_recommended_by": "{provider} のおすすめ",
     "header_bookmarks_placeholder": "まだブックマークがありません。",
     "header_stories_from": "配信元",
     "type_label_visited": "訪問済み",
-    "type_label_bookmarked": "ブックマーク",
+    "type_label_bookmarked": "ブックマーク済み",
     "type_label_synced": "他の端末から同期",
     "type_label_recommended": "話題の記事",
     "type_label_open": "開く",
     "type_label_topic": "トピック",
+    "type_label_now": "今",
     "menu_action_bookmark": "ブックマーク",
     "menu_action_remove_bookmark": "ブックマークを削除",
     "menu_action_copy_address": "URL をコピー",
     "menu_action_email_link": "URL をメールで送信...",
     "menu_action_open_new_window": "新しいウィンドウで開く",
     "menu_action_open_private_window": "新しいプライベートウィンドウで開く",
     "menu_action_dismiss": "閉じる",
     "menu_action_delete": "履歴から削除",
@@ -2699,16 +2794,17 @@
     "confirm_history_delete_p1": "本当にこのページに関して保存されているあらゆる情報を履歴から削除しますか?",
     "confirm_history_delete_notice_p2": "この操作は取り消せません。",
     "menu_action_save_to_pocket": "Pocket へ保存",
     "search_for_something_with": "{search_term} を検索:",
     "search_button": "検索",
     "search_header": "{search_engine_name} 検索",
     "search_web_placeholder": "ウェブを検索",
     "search_settings": "検索設定を変更",
+    "section_info_option": "情報",
     "welcome_title": "新しいタブへようこそ",
     "welcome_body": "Firefox はこのスペースを使って、関連性の高いブックマーク、記事、動画、最近訪れたページを表示し、それらのコンテンツへ簡単に戻れるようにします。",
     "welcome_label": "あなたのハイライトを確認しています",
     "time_label_less_than_minute": "1 分以内",
     "time_label_minute": "{number} 分",
     "time_label_hour": "{number} 時間",
     "time_label_day": "{number} 日",
     "settings_pane_button_label": "新しいタブページをカスタマイズ",
@@ -2743,33 +2839,39 @@
     "topsites_form_add_button": "追加",
     "topsites_form_save_button": "保存",
     "topsites_form_cancel_button": "キャンセル",
     "topsites_form_url_validation": "正しい URL を入力してください",
     "pocket_read_more": "人気のトピック:",
     "pocket_read_even_more": "他の記事を見る",
     "pocket_feedback_header": "2,500 万人以上の人々によって収集されている、ウェブ上で最も優れたコンテンツ。",
     "pocket_feedback_body": "Mozilla ファミリーの一員となった Pocket は、他では見つからなかったかもしれない高品質なコンテンツとあなたを結び付ける手助けをします。",
-    "pocket_send_feedback": "フィードバックを送る"
+    "pocket_send_feedback": "フィードバックを送る",
+    "topstories_empty_state": "すべて既読です。また後で戻って {provider} からのおすすめ記事をチェックしてください。もし待ちきれないなら、人気のトピックを選択すれば、他にもウェブ上の優れた記事を見つけられます。",
+    "manual_migration_explanation": "他のブラウザーから Firefox へあなたのお気に入りのサイトやブックマークを取り込んでみましょう。",
+    "manual_migration_cancel_button": "今はしない",
+    "manual_migration_import_button": "今すぐインポート"
   },
   "ka": {
     "newtab_page_title": "ახალი ჩანართი",
     "default_label_loading": "იტვირთება…",
     "header_top_sites": "მთავარი საიტები",
     "header_stories": "მთავარი სიახლეები",
     "header_visit_again": "ხელახლა ნახვა",
     "header_bookmarks": "ბოლოს ჩანიშნულები",
+    "header_recommended_by": "რეკომენდებულია {provider}-ის მიერ",
     "header_bookmarks_placeholder": "სანიშნეები ჯერ არაა დამატებული.",
     "header_stories_from": "-იდან",
     "type_label_visited": "მონახულებული",
     "type_label_bookmarked": "ჩანიშნული",
     "type_label_synced": "სხვა მოწყობილობიდან დასინქრონებული",
     "type_label_recommended": "პოპულარული",
     "type_label_open": "გახსნა",
     "type_label_topic": "თემა",
+    "type_label_now": "ახლა",
     "menu_action_bookmark": "ჩანიშვნა",
     "menu_action_remove_bookmark": "სანიშნეებიდან ამოღება",
     "menu_action_copy_address": "მისამართის დაკოპირება",
     "menu_action_email_link": "ბმულის გაგზავნა…",
     "menu_action_open_new_window": "ახალ ფანჯარაში გახსნა",
     "menu_action_open_private_window": "ახალ პირად ფანჯარაში გახსნა",
     "menu_action_dismiss": "დახურვა",
     "menu_action_delete": "ისტორიიდან ამოშლა",
@@ -2778,16 +2880,17 @@
     "confirm_history_delete_p1": "ნამდვილად გსურთ, ამ გვერდის ყველა ჩანაწერის ისტორიიდან ამოშლა?",
     "confirm_history_delete_notice_p2": "ეს ქმედება შეუქცევადია.",
     "menu_action_save_to_pocket": "Pocket-ში შენახვა",
     "search_for_something_with": "{search_term} -ის ძიება:",
     "search_button": "ძიება",
     "search_header": "{search_engine_name} -ში ძიება",
     "search_web_placeholder": "ინტერნეტში ძიება",
     "search_settings": "ძიების პარამეტრების შეცვლა",
+    "section_info_option": "ინფორმაცია",
     "welcome_title": "მოგესალმებით ახალ ჩანართზე",
     "welcome_body": "Firefox ამ სივრცეს გამოიყენებს თქვენთვის ყველაზე საჭირო სანიშნეების, სტატიების, ვიდეოებისა და ბოლოს მონახულებული გვერდებისთვის, რომ ადვილად შეძლოთ მათზე დაბრუნება.",
     "welcome_label": "რჩეული ვებ-გვერდების დადგენა",
     "time_label_less_than_minute": "<1წთ",
     "time_label_minute": "{number}წთ",
     "time_label_hour": "{number}სთ",
     "time_label_day": "{number}დღე",
     "settings_pane_button_label": "მოირგეთ ახალი ჩანართის გვერდი",
@@ -2822,33 +2925,39 @@
     "topsites_form_add_button": "დამატება",
     "topsites_form_save_button": "შენახვა",
     "topsites_form_cancel_button": "გაუქმება",
     "topsites_form_url_validation": "საჭიროა მართებული URL",
     "pocket_read_more": "პოპულარული თემები:",
     "pocket_read_even_more": "მეტი სიახლის ნახვა",
     "pocket_feedback_header": "საუკეთესოები ინტერნეტიდან, 25 მილიონზე მეტი ადამიანის მიერ არჩეული.",
     "pocket_feedback_body": "Pocket არის Mozilla-ს ოჯახის ნაწილი, რომელიც დაგეხმარებათ ისეთი მაღალი ხარისხის კონტენტის მოძიებაში, რომელიც სხვა გზებით, შეიძლება ვერ მოგენახათ.",
-    "pocket_send_feedback": "უკუკავშირი"
+    "pocket_send_feedback": "უკუკავშირი",
+    "topstories_empty_state": "უკვე ყველაფერი წაკითხული გაქვთ. {provider}-იდან ახალი რჩეული სტატიების მისაღებად, მოგვიანებით შემოიარეთ. თუ ვერ ითმენთ, აირჩიეთ რომელიმე მოთხოვნადი თემა, ახალი საინტერესო სტატიების მოსაძიებლად.",
+    "manual_migration_explanation": "სცადეთ Firefox, გადმოიტანეთ თქვენი რჩეული საიტები და სანიშნეები სხვა ბრაუზერიდან.",
+    "manual_migration_cancel_button": "არა, გმადლობთ",
+    "manual_migration_import_button": "ახლავე გადმოტანა"
   },
   "kab": {
     "newtab_page_title": "Iccer amaynut",
     "default_label_loading": "Asali…",
     "header_top_sites": "Ismal ifazen",
     "header_stories": "Tiqsiɣin ifazen",
     "header_visit_again": "Rzu tikelt-nniḍen",
     "header_bookmarks": "Ticraḍ n melmi kan",
+    "header_recommended_by": "Iwelleh-it-id {provider}",
     "header_bookmarks_placeholder": "Ur ɣur-k ara ticraḍ yakan.",
     "header_stories_from": "seg",
     "type_label_visited": "Yettwarza",
     "type_label_bookmarked": "Yettwacreḍ",
     "type_label_synced": "Yemtawi seg ibenk-nniḍen",
     "type_label_recommended": "Tiddin",
     "type_label_open": "Yeldi",
     "type_label_topic": "Asentel",
+    "type_label_now": "Tura",
     "menu_action_bookmark": "Creḍ asebter-agi",
     "menu_action_remove_bookmark": "Kkes tacreṭ-agi",
     "menu_action_copy_address": "Nγel tansa",
     "menu_action_email_link": "Azen aseγwen s yimayl…",
     "menu_action_open_new_window": "Ldei deg usfaylu amaynut",
     "menu_action_open_private_window": "Ldi deg usfaylu uslig amaynut",
     "menu_action_dismiss": "Kkes",
     "menu_action_delete": "Kkes seg umazray",
@@ -2857,16 +2966,17 @@
     "confirm_history_delete_p1": "Tebɣiḍ ad tekksed yal tummant n usebter-agi seg umazray-ik?",
     "confirm_history_delete_notice_p2": "Tigawt-agi ur tettuɣal ara ar deffir.",
     "menu_action_save_to_pocket": "Sekles ɣer Pocket",
     "search_for_something_with": "Nadi γef {search_term} s:",
     "search_button": "Nadi",
     "search_header": "Anadi {search_engine_name}",
     "search_web_placeholder": "Nadi di Web",
     "search_settings": "Snifel iγewwaṛen n unadi",
+    "section_info_option": "Talɣut",
     "welcome_title": "Ansuf ar yiccer amaynut",
     "welcome_body": "Firefox ad iseqdec tallunt akken ad d-yesken akk ticraḍ n isebtar iwulmen, imagraden, tividyutin, akked isebtar aniɣer terziḍ melmi kan, ihi tzemreḍ ad d-uɣaleḍ ɣer-sen s wudem fessusen.",
     "welcome_label": "Asulu n iferdisen tisura",
     "time_label_less_than_minute": "<1 n tesdat",
     "time_label_minute": "{number} n tesdatin",
     "time_label_hour": "{number} n isragen",
     "time_label_day": "{number}n wussan",
     "settings_pane_button_label": "Sagen asebter n yiccer-ik amaynut",
@@ -2901,17 +3011,21 @@
     "topsites_form_add_button": "Rnu",
     "topsites_form_save_button": "Sekles",
     "topsites_form_cancel_button": "Sefsex",
     "topsites_form_url_validation": "Tansa URL tameɣtut tettwasra",
     "pocket_read_more": "Isental ittwasnen aṭas:",
     "pocket_read_even_more": "Wali ugar n teqsiḍin",
     "pocket_feedback_header": "D amezwaru n Web, ittwafren sγur ugar 25 imelyan n imdanen.",
     "pocket_feedback_body": "Pocket, aɛeggal n twaxult n Mozilla, ak-d-yefk afus ad twaliḍ agbur n tɣara meqqren i tzemred ad tzegleḍ.",
-    "pocket_send_feedback": "Azen tikti"
+    "pocket_send_feedback": "Azen tikti",
+    "topstories_empty_state": "Ulac wiyaḍ. Uɣal-d ticki s wugar n imagraden seg {provider}. Ur tebɣiḍ ara ad terǧuḍ? Fren asentel seg wid yettwasnen akken ad twaliḍ imagraden yelhan di Web.",
+    "manual_migration_explanation": "Ɛreḍ Firefox s ismal-ik inurifen akked ticraḍ seg iminig-nniḍen.",
+    "manual_migration_cancel_button": "Ala, tanemmirt",
+    "manual_migration_import_button": "Kter tura"
   },
   "kk": {
     "newtab_page_title": "Жаңа бет",
     "default_label_loading": "Жүктелуде…",
     "header_top_sites": "Топ сайттар",
     "header_stories": "Топ хикаялар",
     "header_visit_again": "Қайтадан шолу",
     "header_bookmarks": "Соңғы бетбелгілер",
@@ -3386,24 +3500,26 @@
   },
   "ms": {
     "newtab_page_title": "Tab Baru",
     "default_label_loading": "Memuatkan…",
     "header_top_sites": "Laman Teratas",
     "header_stories": "Berita Hangat",
     "header_visit_again": "Lawat Semula",
     "header_bookmarks": "Tandabuku Terkini",
+    "header_recommended_by": "Disyorkan oleh {provider}",
     "header_bookmarks_placeholder": "Anda masih belum ada tandabuku lagi.",
     "header_stories_from": "dari",
     "type_label_visited": "Dilawati",
     "type_label_bookmarked": "Ditandabuku",
     "type_label_synced": "Sync dari peranti lain",
     "type_label_recommended": "Trending",
     "type_label_open": "Buka",
     "type_label_topic": "Topik",
+    "type_label_now": "Sekarang",
     "menu_action_bookmark": "Tandabuku",
     "menu_action_remove_bookmark": "Alihkeluar Tandabuku",
     "menu_action_copy_address": "Salin Alamat",
     "menu_action_email_link": "Pautan E-mel…",
     "menu_action_open_new_window": "Buka dalam Tetingkap Baru",
     "menu_action_open_private_window": "Buka dalam Tetingkap Peribadi Baru",
     "menu_action_dismiss": "Abai",
     "menu_action_delete": "Hapuskan sejarah",
@@ -3412,16 +3528,17 @@
     "confirm_history_delete_p1": "Anda pasti mahu menghapuskan setiap contoh halaman ini daripada sejarah anda?",
     "confirm_history_delete_notice_p2": "Tindakan ini tidak boleh dibatalkan.",
     "menu_action_save_to_pocket": "Simpan ke Pocket",
     "search_for_something_with": "Cari {search_term} dengan:",
     "search_button": "Cari",
     "search_header": "{search_engine_name} Cari",
     "search_web_placeholder": "Cari dalam Web",
     "search_settings": "Ubah Tetapan Carian",
+    "section_info_option": "Info",
     "welcome_title": "Selamat Datang ke tab baru",
     "welcome_body": "Firefox akan menggunakan ruang ini untuk mempamerkan tandabuku, artikel, video dan halaman yang paling berkaitan dan terkini anda lawati supaya anda boleh mendapatkannya semula dengan mudah.",
     "welcome_label": "Mengenalpasti Serlahan anda",
     "time_label_less_than_minute": "<1m",
     "time_label_minute": "{number}m",
     "time_label_hour": "{number}h",
     "time_label_day": "{number}d",
     "settings_pane_button_label": "Sesuaikan halaman Tab Baru anda",
@@ -3456,17 +3573,21 @@
     "topsites_form_add_button": "Tambah",
     "topsites_form_save_button": "Simpan",
     "topsites_form_cancel_button": "Batal",
     "topsites_form_url_validation": "Perlukan URL yang sah",
     "pocket_read_more": "Topik Popular:",
     "pocket_read_even_more": "Papar Kisah Selanjutnya",
     "pocket_feedback_header": "Terbaik daripada web, disokong oleh lebih 25 juta pengguna.",
     "pocket_feedback_body": "Pocket, sebahagian daripada ciri Mozilla, akan membantu anda sentiasa berhubung dengan kandungan berkualiti tinggi yang mungkin tidak akan anda jumpa tanpanya.",
-    "pocket_send_feedback": "Hantar Maklum balas"
+    "pocket_send_feedback": "Hantar Maklum balas",
+    "topstories_empty_state": "Anda sudah di sini. Tapi sila datang lagi untuk mendapatkan lebih banyak berita hangat daripada {provider}. Tidak boleh tunggu? Pilih topik untuk mendapatkannya dari serata dunia.",
+    "manual_migration_explanation": "Cuba Firefox dengan laman kegemaran dan tandabuku anda daripada pelayar lain.",
+    "manual_migration_cancel_button": "Tidak, Terima kasih",
+    "manual_migration_import_button": "Import Sekarang"
   },
   "my": {
     "newtab_page_title": "တပ်ဗ်အသစ်ဖွင့်",
     "default_label_loading": "ရယူနေသှ်…",
     "header_top_sites": "အများဆုံးသုံးဆိုက်များ",
     "header_highlights": "အသားပေးဖော်ပြချက်များ",
     "type_label_visited": "သွားလည်ခဲ့သော",
     "type_label_bookmarked": "စာအမှတ်မှတ်ထားသော",
@@ -3515,24 +3636,26 @@
   },
   "nb-NO": {
     "newtab_page_title": "Ny fane",
     "default_label_loading": "Laster …",
     "header_top_sites": "Mest besøkte nettsider",
     "header_stories": "Hovedsakene",
     "header_visit_again": "Besøk igjen",
     "header_bookmarks": "Nylige bokmerker",
+    "header_recommended_by": "Anbefalt av {provider}",
     "header_bookmarks_placeholder": "Du har ingen bokmerker enda.",
     "header_stories_from": "fra",
     "type_label_visited": "Besøkt",
     "type_label_bookmarked": "Bokmerket",
     "type_label_synced": "Synkronisert fra annen enhet",
     "type_label_recommended": "Trender",
     "type_label_open": "Åpne",
     "type_label_topic": "Emne",
+    "type_label_now": "Nå",
     "menu_action_bookmark": "Bokmerke",
     "menu_action_remove_bookmark": "Fjern bokmerke",
     "menu_action_copy_address": "Kopier adresse",
     "menu_action_email_link": "Send lenke på e-post …",
     "menu_action_open_new_window": "Åpne i nytt vindu",
     "menu_action_open_private_window": "Åpne i nytt privat vindu",
     "menu_action_dismiss": "Avslå",
     "menu_action_delete": "Slett fra historikk",
@@ -3541,16 +3664,17 @@
     "confirm_history_delete_p1": "Er du sikker på at du vil slette alle forekomster av denne siden fra historikken?",
     "confirm_history_delete_notice_p2": "Denne handlingen kan ikke angres.",
     "menu_action_save_to_pocket": "Lagre til Pocket",
     "search_for_something_with": "Søk etter {search_term} med:",
     "search_button": "Søk",
     "search_header": "{search_engine_name}-søk",
     "search_web_placeholder": "Søk på nettet",
     "search_settings": "Endre søkeinnstillinger",
+    "section_info_option": "Informasjon",
     "welcome_title": "Velkommen til ny fane",
     "welcome_body": "Firefox vil bruke denne plassen til å vise deg de mest relevante bokmerkene, artiklene, videoene og sidene du nettopp har besøkt, slik at du enkelt kan finne tilbake til de.",
     "welcome_label": "Identifiserer dine høydepunkter",
     "time_label_less_than_minute": "<1 m",
     "time_label_minute": "{number} m",
     "time_label_hour": "{number} t",
     "time_label_day": "{number} d",
     "settings_pane_button_label": "Tilpass siden for Ny fane",
@@ -3585,17 +3709,21 @@
     "topsites_form_add_button": "Legg til",
     "topsites_form_save_button": "Lagre",
     "topsites_form_cancel_button": "Avbryt",
     "topsites_form_url_validation": "Gyldig URL er nødvendig",
     "pocket_read_more": "Populære emner:",
     "pocket_read_even_more": "Vis flere saker",
     "pocket_feedback_header": "Det beste av nettet, kurert av over 25 millioner mennesker.",
     "pocket_feedback_body": "Pocket, en del av Mozilla-familien, vil hjelpe deg med å finne innhold av høy kvalitet, som du kanskje ikke ville ha funnet ellers.",
-    "pocket_send_feedback": "Send tilbakemelding"
+    "pocket_send_feedback": "Send tilbakemelding",
+    "topstories_empty_state": "Du har tatt igjen. Kom tilbake senere for flere topphistorier fra {provider}. Kan du ikke vente? Velg et populært emne for å finne flere gode artikler fra hele Internett.",
+    "manual_migration_explanation": "Prøv Firefox med dine favorittnettsteder og bokmerker fra en annen nettleser.",
+    "manual_migration_cancel_button": "Nei takk",
+    "manual_migration_import_button": "Importer nå"
   },
   "ne-NP": {
     "newtab_page_title": "नयाँ ट्याब",
     "default_label_loading": "लोड हुदैँछ...",
     "header_top_sites": "शीर्ष साइटहरु",
     "header_highlights": "विशेषताहरू",
     "type_label_visited": "भ्रमण गरिएको",
     "type_label_bookmarked": "पुस्तकचिनो लागाइएको",
@@ -3623,24 +3751,26 @@
   },
   "nl": {
     "newtab_page_title": "Nieuw tabblad",
     "default_label_loading": "Laden…",
     "header_top_sites": "Topwebsites",
     "header_stories": "Topverhalen",
     "header_visit_again": "Nogmaals bezoeken",
     "header_bookmarks": "Recente bladwijzers",
+    "header_recommended_by": "Aanbevolen door {provider}",
     "header_bookmarks_placeholder": "U hebt nog geen bladwijzers.",
     "header_stories_from": "van",
     "type_label_visited": "Bezocht",
     "type_label_bookmarked": "Bladwijzer gemaakt",
     "type_label_synced": "Gesynchroniseerd vanaf ander apparaat",
     "type_label_recommended": "Trending",
     "type_label_open": "Open",
     "type_label_topic": "Onderwerp",
+    "type_label_now": "Nu",
     "menu_action_bookmark": "Bladwijzer maken",
     "menu_action_remove_bookmark": "Bladwijzer verwijderen",
     "menu_action_copy_address": "Adres kopiëren",
     "menu_action_email_link": "Koppeling e-mailen…",
     "menu_action_open_new_window": "Openen in een nieuw venster",
     "menu_action_open_private_window": "Openen in een nieuw privévenster",
     "menu_action_dismiss": "Verwijderen",
     "menu_action_delete": "Verwijderen uit geschiedenis",
@@ -3649,26 +3779,27 @@
     "confirm_history_delete_p1": "Weet u zeker dat u alle exemplaren van deze pagina uit uw geschiedenis wilt verwijderen?",
     "confirm_history_delete_notice_p2": "Deze actie kan niet ongedaan worden gemaakt.",
     "menu_action_save_to_pocket": "Opslaan naar Pocket",
     "search_for_something_with": "Zoeken naar {search_term} met:",
     "search_button": "Zoeken",
     "search_header": "{search_engine_name} doorzoeken",
     "search_web_placeholder": "Zoeken op het web",
     "search_settings": "Zoekinstellingen wijzigen",
+    "section_info_option": "Info",
     "welcome_title": "Welkom bij het nieuwe tabblad",
     "welcome_body": "Firefox gebruikt deze ruimte om uw meest relevante bladwijzers, artikelen, video’s en pagina’s die u onlangs hebt bezocht weer te geven, zodat u deze eenvoudig kunt terugvinden.",
     "welcome_label": "Uw highlights aanduiden",
     "time_label_less_than_minute": "< 1 m",
     "time_label_minute": "{number} m",
     "time_label_hour": "{number} u",
     "time_label_day": "{number} d",
     "settings_pane_button_label": "Uw Nieuw-tabbladpagina aanpassen",
     "settings_pane_header": "Nieuw-tabbladvoorkeuren",
-    "settings_pane_body": "Kiezen wat u ziet bij het openen van een nieuw tabblad.",
+    "settings_pane_body": "Kies wat u ziet bij het openen van een nieuw tabblad.",
     "settings_pane_search_header": "Zoeken",
     "settings_pane_search_body": "Het web doorzoeken vanaf uw nieuwe tabblad.",
     "settings_pane_topsites_header": "Topwebsites",
     "settings_pane_topsites_body": "De websites benaderen die u het vaakst bezoekt.",
     "settings_pane_topsites_options_showmore": "Twee rijen tonen",
     "settings_pane_bookmarks_header": "Recente bladwijzers",
     "settings_pane_bookmarks_body": "Uw nieuw aangemaakte bladwijzers op één handige plek.",
     "settings_pane_visit_again_header": "Nogmaals bezoeken",
@@ -3693,17 +3824,21 @@
     "topsites_form_add_button": "Toevoegen",
     "topsites_form_save_button": "Opslaan",
     "topsites_form_cancel_button": "Annuleren",
     "topsites_form_url_validation": "Geldige URL vereist",
     "pocket_read_more": "Populaire onderwerpen:",
     "pocket_read_even_more": "Meer verhalen bekijken",
     "pocket_feedback_header": "Het beste van het web, geselecteerd door meer dan 25 miljoen mensen.",
     "pocket_feedback_body": "Pocket, een onderdeel van de Mozilla-familie, helpt u bij het vinden van inhoud met hoge kwaliteit die u anders misschien niet had kunnen vinden.",
-    "pocket_send_feedback": "Feedback verzenden"
+    "pocket_send_feedback": "Feedback verzenden",
+    "topstories_empty_state": "U bent weer bij. Kijk later nog eens voor meer topverhalen van {provider}. Kunt u niet wachten? Selecteer een populair onderwerp voor meer geweldige verhalen van het hele web.",
+    "manual_migration_explanation": "Probeer Firefox met uw favoriete websites en bladwijzers uit een andere browser.",
+    "manual_migration_cancel_button": "Nee bedankt",
+    "manual_migration_import_button": "Nu importeren"
   },
   "nn-NO": {
     "newtab_page_title": "Ny flik",
     "default_label_loading": "Lastar…",
     "header_top_sites": "Mest vitja",
     "header_stories": "Hovudsakene",
     "header_visit_again": "Bes;kigjen",
     "header_bookmarks": "Nylege bokmerke",
@@ -3832,24 +3967,26 @@
   },
   "pl": {
     "newtab_page_title": "Nowa karta",
     "default_label_loading": "Wczytywanie…",
     "header_top_sites": "Popularne",
     "header_stories": "Popularne artykuły",
     "header_visit_again": "Odwiedź ponownie",
     "header_bookmarks": "Najnowsze zakładki",
+    "header_recommended_by": "Poleca: {provider}",
     "header_bookmarks_placeholder": "Nie ma jeszcze żadnych zakładek.",
     "header_stories_from": "od:",
     "type_label_visited": "Odwiedzone",
     "type_label_bookmarked": "Zakładka",
     "type_label_synced": "Z innego urządzenia",
     "type_label_recommended": "Polecane",
     "type_label_open": "Otwarte",
     "type_label_topic": "Temat",
+    "type_label_now": "Teraz",
     "menu_action_bookmark": "Dodaj zakładkę",
     "menu_action_remove_bookmark": "Usuń zakładkę",
     "menu_action_copy_address": "Kopiuj adres",
     "menu_action_email_link": "Wyślij odnośnik…",
     "menu_action_open_new_window": "Otwórz w nowym oknie",
     "menu_action_open_private_window": "Otwórz w nowym oknie prywatnym",
     "menu_action_dismiss": "Odrzuć",
     "menu_action_delete": "Usuń z historii",
@@ -3858,16 +3995,17 @@
     "confirm_history_delete_p1": "Czy na pewno usunąć każde wystąpienie tej strony z historii?",
     "confirm_history_delete_notice_p2": "Nie można tego cofnąć.",
     "menu_action_save_to_pocket": "Zapisz w Pocket",
     "search_for_something_with": "Szukaj „{search_term}” w:",
     "search_button": "Szukaj",
     "search_header": "Wyszukiwanie w {search_engine_name}",
     "search_web_placeholder": "Szukaj",
     "search_settings": "Zmień ustawienia wyszukiwania",
+    "section_info_option": "Informacja",
     "welcome_title": "Witamy w nowej karcie",
     "welcome_body": "W tym miejscu Firefox będzie wyświetlał najciekawsze zakładki, artykuły, filmy i niedawno odwiedzone strony, aby można było do nich łatwo wrócić.",
     "welcome_label": "Wykrywanie ulubionych treści użytkownika",
     "time_label_less_than_minute": "<1 min",
     "time_label_minute": "{number} min",
     "time_label_hour": "{number} godz.",
     "time_label_day": "{number} d.",
     "settings_pane_button_label": "Dostosuj stronę nowej karty",
@@ -3902,33 +4040,39 @@
     "topsites_form_add_button": "Dodaj",
     "topsites_form_save_button": "Zapisz",
     "topsites_form_cancel_button": "Anuluj",
     "topsites_form_url_validation": "Wymagany jest prawidłowy adres",
     "pocket_read_more": "Popularne tematy:",
     "pocket_read_even_more": "Więcej artykułów",
     "pocket_feedback_header": "Najlepsze, co oferuje Internet, wybrane przez ponad 25 milionów osób.",
     "pocket_feedback_body": "Pocket, będący częścią Mozilli, pomoże w szukaniu artykułów wysokiej jakości, aby nic Cię nie ominęło.",
-    "pocket_send_feedback": "Wyślij opinię"
+    "pocket_send_feedback": "Wyślij opinię",
+    "topstories_empty_state": "To na razie wszystko. {provider} później będzie mieć więcej popularnych artykułów. Nie możesz się doczekać? Wybierz popularny temat, aby znaleźć więcej artykułów z całego Internetu.",
+    "manual_migration_explanation": "Wypróbuj Firefoksa ze swoimi ulubionymi stronami i zakładkami z innej przeglądarki.",
+    "manual_migration_cancel_button": "Nie, dziękuję",
+    "manual_migration_import_button": "Importuj teraz"
   },
   "pt-BR": {
     "newtab_page_title": "Nova aba",
     "default_label_loading": "Carregando…",
     "header_top_sites": "Sites preferidos",
     "header_stories": "Histórias populares",
     "header_visit_again": "Visitar novamente",
     "header_bookmarks": "Favoritos recentes",
+    "header_recommended_by": "Recomendado por {provider}",
     "header_bookmarks_placeholder": "Você ainda não tem nenhum favorito.",
     "header_stories_from": "de",
     "type_label_visited": "Visitado",
     "type_label_bookmarked": "Adicionado aos favoritos",
     "type_label_synced": "Sincronizado a partir de outro dispositivo",
     "type_label_recommended": "Tendência",
     "type_label_open": "Abertas",
     "type_label_topic": "Tópico",
+    "type_label_now": "Agora",
     "menu_action_bookmark": "Adicionar aos favoritos",
     "menu_action_remove_bookmark": "Remover favorito",
     "menu_action_copy_address": "Copiar endereço",
     "menu_action_email_link": "Enviar link por e-mail…",
     "menu_action_open_new_window": "Abrir em uma nova janela",
     "menu_action_open_private_window": "Abrir em uma nova janela privativa",
     "menu_action_dismiss": "Dispensar",
     "menu_action_delete": "Excluir do histórico",
@@ -3937,16 +4081,17 @@
     "confirm_history_delete_p1": "Você tem certeza que deseja deletar todas as ocorrências dessa página do seu histórico?",
     "confirm_history_delete_notice_p2": "Essa ação não pode ser desfeita.",
     "menu_action_save_to_pocket": "Salvar no Pocket",
     "search_for_something_with": "Pesquisar por {search_term} com:",
     "search_button": "Pesquisar",
     "search_header": "Pesquisa {search_engine_name}",
     "search_web_placeholder": "Pesquisar na Web",
     "search_settings": "Alterar configurações de pesquisa",
+    "section_info_option": "Info",
     "welcome_title": "Bem-vindo a nova aba",
     "welcome_body": "O Firefox usará este espaço para mostrar seus favoritos, artigos, vídeos e páginas mais relevantes visitados recentemente, assim você pode voltar mais facilmente.",
     "welcome_label": "Identificando seus destaques",
     "time_label_less_than_minute": "<1m",
     "time_label_minute": "{number}m",
     "time_label_hour": "{number}h",
     "time_label_day": "{number}d",
     "settings_pane_button_label": "Personalizar sua página de nova aba",
@@ -3981,33 +4126,39 @@
     "topsites_form_add_button": "Adicionar",
     "topsites_form_save_button": "Salvar",
     "topsites_form_cancel_button": "Cancelar",
     "topsites_form_url_validation": "É necessário uma URL válida",
     "pocket_read_more": "Tópicos populares:",
     "pocket_read_even_more": "Ver mais histórias",
     "pocket_feedback_header": "O melhor da web, com curadoria de mais de 25 milhões de pessoas.",
     "pocket_feedback_body": "O Pocket, parte da família Mozilla, irá ajudar a conecta-se a conteúdo de alta qualidade que talvez não tenha encontrado de outra forma.",
-    "pocket_send_feedback": "Enviar feedback"
+    "pocket_send_feedback": "Enviar feedback",
+    "topstories_empty_state": "Você já viu tudo. Volte mais tarde para mais histórias do {provider}. Não consegue esperar? Escolha um assunto popular para encontrar mais grandes histórias através da web.",
+    "manual_migration_explanation": "Use o Firefox com seus sites favoritos de outro navegador.",
+    "manual_migration_cancel_button": "Não, obrigado",
+    "manual_migration_import_button": "Importar agora"
   },
   "pt-PT": {
     "newtab_page_title": "Novo separador",
     "default_label_loading": "A carregar…",
     "header_top_sites": "Sites mais visitados",
     "header_stories": "Histórias principais",
     "header_visit_again": "Visitar novamente",
     "header_bookmarks": "Marcadores recentes",
+    "header_recommended_by": "Recomendado por {provider}",
     "header_bookmarks_placeholder": "Ainda não tem quaisquer marcadores.",
     "header_stories_from": "de",
     "type_label_visited": "Visitados",
     "type_label_bookmarked": "Guardados nos marcadores",
     "type_label_synced": "Sincronizado a partir de outro dispositivo",
     "type_label_recommended": "Tendência",
     "type_label_open": "Abertos",
     "type_label_topic": "Tópico",
+    "type_label_now": "Agora",
     "menu_action_bookmark": "Adicionar aos marcadores",
     "menu_action_remove_bookmark": "Remover marcador",
     "menu_action_copy_address": "Copiar endereço",
     "menu_action_email_link": "Enviar ligação por email…",
     "menu_action_open_new_window": "Abrir em nova janela",
     "menu_action_open_private_window": "Abrir em nova janela privada",
     "menu_action_dismiss": "Dispensar",
     "menu_action_delete": "Apagar do histórico",
@@ -4016,16 +4167,17 @@
     "confirm_history_delete_p1": "Tem a certeza de que deseja apagar todas as instâncias desta página do seu histórico?",
     "confirm_history_delete_notice_p2": "Esta ação não pode ser desfeita.",
     "menu_action_save_to_pocket": "Guardar no Pocket",
     "search_for_something_with": "Pesquisar por {search_term} com:",
     "search_button": "Pesquisar",
     "search_header": "Pesquisa {search_engine_name}",
     "search_web_placeholder": "Pesquisar na Web",
     "search_settings": "Alterar definições de pesquisa",
+    "section_info_option": "Informação",
     "welcome_title": "Bem-vindo ao novo separador",
     "welcome_body": "O Firefox irá utilizar este espaço para lhe mostrar os seus marcadores, artigos, vídeos, e páginas mais relevantes que visitou recentemente, para que possa regressar a estes mais facilmente.",
     "welcome_label": "A identificar os seus destaques",
     "time_label_less_than_minute": "<1m",
     "time_label_minute": "{number}m",
     "time_label_hour": "{number}h",
     "time_label_day": "{number}d",
     "settings_pane_button_label": "Personalizar a sua página de novo separador",
@@ -4060,17 +4212,21 @@
     "topsites_form_add_button": "Adicionar",
     "topsites_form_save_button": "Guardar",
     "topsites_form_cancel_button": "Cancelar",
     "topsites_form_url_validation": "URL válido requerido",
     "pocket_read_more": "Tópicos populares:",
     "pocket_read_even_more": "Ver mais histórias",
     "pocket_feedback_header": "O melhor da web, com curadoria de mais de 25 milhões de pessoas.",
     "pocket_feedback_body": "O Pocket, parte da família Mozilla, irá ajudar a ligar-se a conteúdo de alta qualidade que você poderia não ter encontrado de outra forma.",
-    "pocket_send_feedback": "Enviar feedback"
+    "pocket_send_feedback": "Enviar feedback",
+    "topstories_empty_state": "Já apanhou tudo. Verifique mais tarde para mais histórias principais de {provider}. Não pode esperar? Selecione um tópico popular para encontrar mais boas histórias de toda a web.",
+    "manual_migration_explanation": "Experimente o Firefox com os seus sites favoritos e marcadores de outro navegador.",
+    "manual_migration_cancel_button": "Não obrigado",
+    "manual_migration_import_button": "Importar agora"
   },
   "rm": {
     "newtab_page_title": "Nov tab",
     "default_label_loading": "Chargiar…",
     "header_top_sites": "Paginas preferidas",
     "header_highlights": "Accents",
     "header_stories": "Artitgels populars",
     "header_stories_from": "da",
@@ -4282,24 +4438,26 @@
   "si": {},
   "sk": {
     "newtab_page_title": "Nová karta",
     "default_label_loading": "Načítava sa…",
     "header_top_sites": "Top stránky",
     "header_stories": "Top príbehy",
     "header_visit_again": "Navštívte znova",
     "header_bookmarks": "Nedávno pridané záložky",
+    "header_recommended_by": "Odporúča {provider}",
     "header_bookmarks_placeholder": "Zatiaľ nemáte žiadne záložky.",
     "header_stories_from": "zo služby",
     "type_label_visited": "Navštívené",
     "type_label_bookmarked": "V záložkách",
     "type_label_synced": "Synchronizované z ďalšieho zariadenia",
     "type_label_recommended": "Trendy",
     "type_label_open": "Otvorené",
     "type_label_topic": "Téma",
+    "type_label_now": "Teraz",
     "menu_action_bookmark": "Pridať medzi záložky",
     "menu_action_remove_bookmark": "Odstrániť záložku",
     "menu_action_copy_address": "Kopírovať adresu",
     "menu_action_email_link": "Odoslať odkaz e-mailom…",
     "menu_action_open_new_window": "Otvoriť v novom okne",
     "menu_action_open_private_window": "Otvoriť v novom okne režimu Súkromné prehliadanie",
     "menu_action_dismiss": "Skryť",
     "menu_action_delete": "Odstrániť z histórie",
@@ -4308,16 +4466,17 @@
     "confirm_history_delete_p1": "Ste si istí, že chcete odstrániť všetky výskyty tejto stránky zo svojej histórie prehliadania?",
     "confirm_history_delete_notice_p2": "Túto akciu nie je možné vrátiť späť.",
     "menu_action_save_to_pocket": "Uložiť do služby Pocket",
     "search_for_something_with": "Hľadať {search_term} pomocou:",
     "search_button": "Hľadať",
     "search_header": "Vyhľadávanie pomocou {search_engine_name}",
     "search_web_placeholder": "Vyhľadávanie na webe",
     "search_settings": "Zmeniť nastavenia vyhľadávania",
+    "section_info_option": "Informácie",
     "welcome_title": "Vitajte na stránke novej karty",
     "welcome_body": "Firefox bude na tomto mieste zobrazovať často zobrazované záložky, články, videá a stránky, ktoré ste nedávno navštívili. Váš prístup k nim je tak omnoho ľahší.",
     "welcome_label": "Identifikácia vybraných stránok",
     "time_label_less_than_minute": "< 1 min",
     "time_label_minute": "{number} min",
     "time_label_hour": "{number} hod",
     "time_label_day": "{number} d",
     "settings_pane_button_label": "Prispôsobte si svoju stránku Nová karta",
@@ -4352,33 +4511,38 @@
     "topsites_form_add_button": "Pridať",
     "topsites_form_save_button": "Uložiť",
     "topsites_form_cancel_button": "Zrušiť",
     "topsites_form_url_validation": "Vyžaduje sa platná URL",
     "pocket_read_more": "Populárne témy:",
     "pocket_read_even_more": "Zobraziť ďalšie príbehy",
     "pocket_feedback_header": "To najlepšie z webu - podľa názoru 25 miliónov ľudí.",
     "pocket_feedback_body": "Pocket, súčasť Mozilla rodiny, vám pomôže nájsť vysokokvalitný obsah, ktorý by ste inde zrejme nenašli.",
-    "pocket_send_feedback": "Odoslať spätnú väzbu"
+    "pocket_send_feedback": "Odoslať spätnú väzbu",
+    "topstories_empty_state": "Už ste prečítali všetko. Ďalšie príbehy zo služby {provider} tu nájdete opäť neskôr. Nemôžete sa dočkať? Vyberte si populárnu tému a pozrite sa na ďalšie skvelé príbehy z celého webu.",
+    "manual_migration_explanation": "Vyskúšajte Firefox so svojimi obľúbenými stránkami a záložkami z iného prehliadača.",
+    "manual_migration_cancel_button": "Nie, ďakujem",
+    "manual_migration_import_button": "Importovať teraz"
   },
   "sl": {
     "newtab_page_title": "Nov zavihek",
     "default_label_loading": "Nalaganje …",
     "header_top_sites": "Glavne strani",
     "header_stories": "Glavne vesti",
     "header_visit_again": "Obiščite znova",
     "header_bookmarks": "Nedavni zaznamki",
     "header_bookmarks_placeholder": "Nimate še nobenih zaznamkov.",
     "header_stories_from": "od",
     "type_label_visited": "Obiskano",
     "type_label_bookmarked": "Med zaznamki",
     "type_label_synced": "Sinhronizirano z druge naprave",
     "type_label_recommended": "Najbolj priljubljeno",
     "type_label_open": "Odpri",
     "type_label_topic": "Tema",
+    "type_label_now": "Zdaj",
     "menu_action_bookmark": "Dodaj med zaznamke",
     "menu_action_remove_bookmark": "Odstrani zaznamek",
     "menu_action_copy_address": "Kopiraj naslov",
     "menu_action_email_link": "Pošlji povezavo po e-pošti …",
     "menu_action_open_new_window": "Odpri v novem oknu",
     "menu_action_open_private_window": "Odpri v novem zasebnem oknu",
     "menu_action_dismiss": "Opusti",
     "menu_action_delete": "Izbriši iz zgodovine",
@@ -4431,17 +4595,20 @@
     "topsites_form_add_button": "Dodaj",
     "topsites_form_save_button": "Shrani",
     "topsites_form_cancel_button": "Prekliči",
     "topsites_form_url_validation": "Vnesite veljaven URL",
     "pocket_read_more": "Priljubljene teme:",
     "pocket_read_even_more": "Prikaži več vesti",
     "pocket_feedback_header": "Najboljše s spleta, kar je izbralo več kot 25 milijonov ljudi.",
     "pocket_feedback_body": "Pocket, del Mozilline družine, vam bo pomagal pridobiti visokokakovostne vsebine, ki jih sicer ne bi našli.",
-    "pocket_send_feedback": "Pošlji povratne informacije"
+    "pocket_send_feedback": "Pošlji povratne informacije",
+    "manual_migration_explanation": "Preskusite Firefox s svojimi priljubljenimi stranmi in zaznamki iz drugih brskalnikov.",
+    "manual_migration_cancel_button": "Ne, hvala",
+    "manual_migration_import_button": "Uvozi zdaj"
   },
   "son": {},
   "sq": {
     "newtab_page_title": "Skedë e Re",
     "default_label_loading": "Po ngarkohet…",
     "header_top_sites": "Sajte Kryesues",
     "header_highlights": "Highlights",
     "type_label_visited": "Të vizituara",
@@ -4570,24 +4737,26 @@
   },
   "sv-SE": {
     "newtab_page_title": "Ny flik",
     "default_label_loading": "Laddar…",
     "header_top_sites": "Mest besökta",
     "header_stories": "Huvudnyheter",
     "header_visit_again": "Besökt igen",
     "header_bookmarks": "Senaste bokmärken",
+    "header_recommended_by": "Rekommenderas av {provider}",
     "header_bookmarks_placeholder": "Du har inga bokmärken ännu.",
     "header_stories_from": "från",
     "type_label_visited": "Besökta",
     "type_label_bookmarked": "Bokmärkta",
     "type_label_synced": "Synkroniserade från en annan enhet",
     "type_label_recommended": "Trend",
     "type_label_open": "Öppna",
     "type_label_topic": "Ämne",
+    "type_label_now": "Nu",
     "menu_action_bookmark": "Bokmärke",
     "menu_action_remove_bookmark": "Ta bort bokmärke",
     "menu_action_copy_address": "Kopiera adress",
     "menu_action_email_link": "E-posta länk…",
     "menu_action_open_new_window": "Öppna i nytt fönster",
     "menu_action_open_private_window": "Öppna i nytt privat fönster",
     "menu_action_dismiss": "Avfärda",
     "menu_action_delete": "Ta bort från historik",
@@ -4596,16 +4765,17 @@
     "confirm_history_delete_p1": "Är du säker på att du vill radera varje förekomst av den här sidan från din historik?",
     "confirm_history_delete_notice_p2": "Den här åtgärden kan inte ångras.",
     "menu_action_save_to_pocket": "Spara till Pocket",
     "search_for_something_with": "Sök efter {search_term} med:",
     "search_button": "Sök",
     "search_header": "{search_engine_name}",
     "search_web_placeholder": "Sök på webben",
     "search_settings": "Ändra sökinställningar",
+    "section_info_option": "Info",
     "welcome_title": "Välkommen till ny flik",
     "welcome_body": "Firefox kommer att använda detta utrymme för att visa dina mest relevanta bokmärken, artiklar, videor och sidor du nyligen besökt, så du kan hitta dem lätt.",
     "welcome_label": "Identifierar dina höjdpunkter",
     "time_label_less_than_minute": "<1 min",
     "time_label_minute": "{number} min",
     "time_label_hour": "{number} h",
     "time_label_day": "{number} d",
     "settings_pane_button_label": "Anpassa sidan för Ny flik",
@@ -4640,17 +4810,21 @@
     "topsites_form_add_button": "Lägg till",
     "topsites_form_save_button": "Spara",
     "topsites_form_cancel_button": "Avbryt",
     "topsites_form_url_validation": "Giltig URL krävs",
     "pocket_read_more": "Populära ämnen:",
     "pocket_read_even_more": "Visa fler nyheter",
     "pocket_feedback_header": "Det bästa av webben, sammanställt av över 25 miljoner människor.",
     "pocket_feedback_body": "Pocket, en del av Mozilla-familjen, hjälper dig att hitta högkvalitativt innehåll som du kanske annars inte hade hittat.",
-    "pocket_send_feedback": "Skicka återkoppling"
+    "pocket_send_feedback": "Skicka återkoppling",
+    "topstories_empty_state": "Det finns inte fler. Kom tillbaka senare för fler huvudnyheter från {provider}. Kan du inte vänta? Välj ett populärt ämne för att hitta fler bra nyheter från hela världen.",
+    "manual_migration_explanation": "Prova Firefox med dina favoritwebbplatser och bokmärken från en annan webbläsare.",
+    "manual_migration_cancel_button": "Nej tack",
+    "manual_migration_import_button": "Importera nu"
   },
   "ta": {
     "newtab_page_title": "புதிய கீற்று",
     "default_label_loading": "ஏற்றுகிறது…",
     "header_top_sites": "சிறந்த தளங்கள்",
     "header_stories": "முக்கிய கதைகள்",
     "header_visit_again": "மீண்டும் வருக",
     "header_bookmarks": "சமீபத்திய புத்தகக்குறிகள்",
@@ -4808,24 +4982,26 @@
   },
   "th": {
     "newtab_page_title": "แท็บใหม่",
     "default_label_loading": "กำลังโหลด…",
     "header_top_sites": "ไซต์เด่น",
     "header_stories": "เรื่องราวเด่น",
     "header_visit_again": "เยี่ยมชมอีกครั้ง",
     "header_bookmarks": "ที่คั่นหน้าเมื่อเร็ว ๆ นี้",
+    "header_recommended_by": "แนะนำโดย {provider}",
     "header_bookmarks_placeholder": "คุณยังไม่มีที่คั่นหน้าใด ๆ",
     "header_stories_from": "จาก",
     "type_label_visited": "เยี่ยมชมแล้ว",
     "type_label_bookmarked": "มีที่คั่นหน้าแล้ว",
     "type_label_synced": "ซิงค์จากอุปกรณ์อื่น",
     "type_label_recommended": "กำลังนิยม",
     "type_label_open": "เปิด",
     "type_label_topic": "หัวข้อ",
+    "type_label_now": "ตอนนี้",
     "menu_action_bookmark": "เพิ่มที่คั่นหน้า",
     "menu_action_remove_bookmark": "เอาที่คั่นหน้าออก",
     "menu_action_copy_address": "คัดลอกที่อยู่",
     "menu_action_email_link": "ส่งอีเมลลิงก์…",
     "menu_action_open_new_window": "เปิดในหน้าต่างใหม่",
     "menu_action_open_private_window": "เปิดในหน้าต่างส่วนตัวใหม่",
     "menu_action_dismiss": "ยกเลิก",
     "menu_action_delete": "ลบออกจากประวัติ",
@@ -4833,16 +5009,17 @@
     "menu_action_unpin": "ถอดหมุด",
     "confirm_history_delete_notice_p2": "การกระทำนี้ไม่สามารถเลิกทำได้",
     "menu_action_save_to_pocket": "บันทึกไปยัง Pocket",
     "search_for_something_with": "ค้นหาสำหรับ {search_term} ด้วย:",
     "search_button": "ค้นหา",
     "search_header": "ค้นหา {search_engine_name}",
     "search_web_placeholder": "ค้นหาเว็บ",
     "search_settings": "เปลี่ยนการตั้งค่าการค้นหา",
+    "section_info_option": "ข้อมูล",
     "welcome_title": "ยินดีต้อนรับสู่แท็บใหม่",
     "welcome_body": "Firefox จะใช้พื้นที่นี้เพื่อแสดงที่คั่นหน้า, บทความ, วิดีโอ และหน้าที่คุณเพิ่งเยี่ยมชมที่เกี่ยวข้องกับคุณมากที่สุด เพื่อให้คุณสามารถกลับมาชมได้อย่างง่ายดาย",
     "welcome_label": "กำลังระบุรายการเด่นของคุณ",
     "time_label_less_than_minute": "<1 นาที",
     "time_label_minute": "{number} นาที",
     "time_label_hour": "{number} ชั่วโมง",
     "time_label_day": "{number} วัน",
     "settings_pane_button_label": "ปรับแต่งหน้าแท็บใหม่ของคุณ",
@@ -4875,17 +5052,20 @@
     "topsites_form_add_button": "เพิ่ม",
     "topsites_form_save_button": "บันทึก",
     "topsites_form_cancel_button": "ยกเลิก",
     "topsites_form_url_validation": "ต้องการ URL ที่ถูกต้อง",
     "pocket_read_more": "หัวข้อยอดนิยม:",
     "pocket_read_even_more": "ดูเรื่องราวเพิ่มเติม",
     "pocket_feedback_header": "ที่สุดของเว็บ จัดรายการโดยผู้คนกว่า 25 ล้านคน",
     "pocket_feedback_body": "Pocket ส่วนหนึ่งของครอบครัว Mozilla จะช่วยเชื่อมต่อคุณกับเนื้อหาคุณภาพสูงที่คุณอาจไม่พบที่อื่น",
-    "pocket_send_feedback": "ส่งข้อคิดเห็น"
+    "pocket_send_feedback": "ส่งข้อคิดเห็น",
+    "manual_migration_explanation": "ลอง Firefox ด้วยไซต์โปรดและที่คั่นหน้าของคุณจากเบราว์เซอร์อื่น",
+    "manual_migration_cancel_button": "ไม่ ขอบคุณ",
+    "manual_migration_import_button": "นำเข้าตอนนี้"
   },
   "tl": {
     "newtab_page_title": "Bagong Tab",
     "default_label_loading": "Pagkarga…",
     "header_top_sites": "Tuktok na mga Site",
     "header_highlights": "Highlights",
     "type_label_visited": "Binisita",
     "type_label_bookmarked": "Bookmarked",
@@ -4934,24 +5114,26 @@
   },
   "tr": {
     "newtab_page_title": "Yeni Sekme",
     "default_label_loading": "Yükleniyor…",
     "header_top_sites": "En Sık Kullanılan Siteler",
     "header_stories": "İlginç Yazılar",
     "header_visit_again": "Yeniden Ziyaret Edin",
     "header_bookmarks": "Son Yer imleri",
+    "header_recommended_by": "{provider} öneriyor",
     "header_bookmarks_placeholder": "Henüz hiç yer iminiz yok.",
     "header_stories_from": "kaynak:",
     "type_label_visited": "Ziyaret edildi",
     "type_label_bookmarked": "Yer imlerine eklendi",
     "type_label_synced": "Başka bir cihazdan eşitlendi",
     "type_label_recommended": "Popüler",
     "type_label_open": "Açık",
     "type_label_topic": "Konu",
+    "type_label_now": "Şimdi",
     "menu_action_bookmark": "Yer imlerine ekle",
     "menu_action_remove_bookmark": "Yer imini sil",
     "menu_action_copy_address": "Adresi kopyala",
     "menu_action_email_link": "Bağlantıyı e-postayla gönder…",
     "menu_action_open_new_window": "Yeni pencerede aç",
     "menu_action_open_private_window": "Yeni gizli pencerede aç",
     "menu_action_dismiss": "Kapat",
     "menu_action_delete": "Geçmişten sil",
@@ -4960,16 +5142,17 @@
     "confirm_history_delete_p1": "Bu sayfanın tüm kayıtlarını geçmişinizden silmek istediğinizden emin misiniz?",
     "confirm_history_delete_notice_p2": "Bu işlem geri alınamaz.",
     "menu_action_save_to_pocket": "Pocket’a kaydet",
     "search_for_something_with": "{search_term} terimini şununla ara:",
     "search_button": "Ara",
     "search_header": "{search_engine_name} Araması",
     "search_web_placeholder": "Web'de ara",
     "search_settings": "Arama ayarlarını değiştir",
+    "section_info_option": "Bilgi",
     "welcome_title": "Yeni sekmeye hoş geldiniz",
     "welcome_body": "Firefox son zamanlarda ziyaret ettiğiniz ve sık kullandığınız yer imlerini, makaleleri, videoları ve sayfaları onlara tekrar kolayca geri dönebilmeniz için bu alanda gösterecektir.",
     "welcome_label": "Öne Çıkanlar'ınızı tanıyın",
     "time_label_less_than_minute": "<1 dk",
     "time_label_minute": "{number} dk",
     "time_label_hour": "{number} sa",
     "time_label_day": "{number} g",
     "settings_pane_button_label": "Yeni Sekme sayfanızı özelleştirin",
@@ -5004,17 +5187,21 @@
     "topsites_form_add_button": "Ekle",
     "topsites_form_save_button": "Kaydet",
     "topsites_form_cancel_button": "İptal",
     "topsites_form_url_validation": "Geçerli bir adres gerekli",
     "pocket_read_more": "Popüler konular:",
     "pocket_read_even_more": "Daha fazla yazı göster",
     "pocket_feedback_header": "25 milyon kişinin katkılarıyla, web’in en iyileri.",
     "pocket_feedback_body": "Mozilla ailesinin yeni üyesi Pocket, kolayca bulamayacağınız, kaliteli içerikleri karşınıza getiriyor.",
-    "pocket_send_feedback": "Görüş gönder"
+    "pocket_send_feedback": "Görüş gönder",
+    "topstories_empty_state": "Hepsini bitirdiniz. Yeni {provider} haberleri için daha fazla yine gelin. Beklemek istemiyor musunuz? İlginç yazılara ulaşmak için popüler konulardan birini seçebilirsiniz.",
+    "manual_migration_explanation": "Başka tarayıcılardaki sevdiğiniz siteleri ve yer imlerinizi Firefox’a aktarabilirsiniz.",
+    "manual_migration_cancel_button": "Gerek yok",
+    "manual_migration_import_button": "Olur, aktaralım"
   },
   "uk": {
     "newtab_page_title": "Нова вкладка",
     "default_label_loading": "Завантаження…",
     "header_top_sites": "Популярні сайти",
     "header_stories": "Головні новини",
     "header_visit_again": "Відвідати знову",
     "header_bookmarks": "Недавно закладені",
@@ -5202,24 +5389,26 @@
   "xh": {},
   "zh-CN": {
     "newtab_page_title": "新标签页",
     "default_label_loading": "正在载入…",
     "header_top_sites": "常用网站",
     "header_stories": "热门报道",
     "header_visit_again": "再次造访",
     "header_bookmarks": "最近的书签",
+    "header_recommended_by": "{provider} 推荐",
     "header_bookmarks_placeholder": "您还没有最近的书签。",
     "header_stories_from": "出自",
     "type_label_visited": "曾经访问",
     "type_label_bookmarked": "已加书签",
     "type_label_synced": "从其他设备同步而来",
     "type_label_recommended": "趋势",
     "type_label_open": "打开",
     "type_label_topic": "主题",
+    "type_label_now": "现在",
     "menu_action_bookmark": "添加书签",
     "menu_action_remove_bookmark": "移除书签",
     "menu_action_copy_address": "复制地址",
     "menu_action_email_link": "用邮件发送链接…",
     "menu_action_open_new_window": "在新窗口中打开",
     "menu_action_open_private_window": "在新的隐私浏览窗口中打开",
     "menu_action_dismiss": "消除",
     "menu_action_delete": "从历史记录中删除",
@@ -5228,16 +5417,17 @@
     "confirm_history_delete_p1": "确定删除此页面在您的历史记录中的所有记录?",
     "confirm_history_delete_notice_p2": "此操作不能撤销。",
     "menu_action_save_to_pocket": "保存到 Pocket",
     "search_for_something_with": "搜索 {search_term},使用:",
     "search_button": "搜索",
     "search_header": "{search_engine_name} 搜索",
     "search_web_placeholder": "在网络上搜索",
     "search_settings": "更改搜索设置",
+    "section_info_option": "信息",
     "welcome_title": "欢迎使用新标签页",
     "welcome_body": "Firefox 会在这里显示对您最有用的书签、文章、视频和访问过的页面,便于您回到这些网站。",
     "welcome_label": "正在为您准备集锦",
     "time_label_less_than_minute": "1 分钟内",
     "time_label_minute": "{number} 分钟前",
     "time_label_hour": "{number} 小时前",
     "time_label_day": "{number} 天前",
     "settings_pane_button_label": "定制您的新标签页",
@@ -5272,33 +5462,39 @@
     "topsites_form_add_button": "添加",
     "topsites_form_save_button": "保存",
     "topsites_form_cancel_button": "取消",
     "topsites_form_url_validation": "需要有效的网址",
     "pocket_read_more": "热门主题:",
     "pocket_read_even_more": "查看更多报道",
     "pocket_feedback_header": "超过2500万人构成的互联网。",
     "pocket_feedback_body": "Pocket,Mozilla 家族的一员,它可以帮助您找到更多不易发现的高品质内容。",
-    "pocket_send_feedback": "发送反馈"
+    "pocket_send_feedback": "发送反馈",
+    "topstories_empty_state": "已经都看过了。请过会再来查看 {provider} 提供的热门故事。不想等待?选择一个热门话题,找到网络上的更多好故事。",
+    "manual_migration_explanation": "将您在其他浏览器中常用的网站和书签导入 Firefox,体验别具一格的浏览器。",
+    "manual_migration_cancel_button": "不用了",
+    "manual_migration_import_button": "立即导入"
   },
   "zh-TW": {
     "newtab_page_title": "新分頁",
     "default_label_loading": "載入中…",
     "header_top_sites": "熱門網站",
     "header_stories": "熱門文章",
     "header_visit_again": "再次造訪",
     "header_bookmarks": "近期新增的書籤",
+    "header_recommended_by": "{provider} 推薦",
     "header_bookmarks_placeholder": "您還沒有任何書籤。",
     "header_stories_from": "來自",
     "type_label_visited": "造訪過的網站",
     "type_label_bookmarked": "已加入書籤",
     "type_label_synced": "從其他裝置同步過來",
     "type_label_recommended": "熱門",
     "type_label_open": "開啟",
     "type_label_topic": "主題",
+    "type_label_now": "現在",
     "menu_action_bookmark": "書籤",
     "menu_action_remove_bookmark": "移除書籤",
     "menu_action_copy_address": "複製網址",
     "menu_action_email_link": "郵寄鏈結…",
     "menu_action_open_new_window": "用新視窗開啟",
     "menu_action_open_private_window": "用新隱私視窗開啟",
     "menu_action_dismiss": "隱藏",
     "menu_action_delete": "從瀏覽紀錄刪除",
@@ -5307,16 +5503,17 @@
     "confirm_history_delete_p1": "您確定要刪除此頁面的所有瀏覽紀錄?",
     "confirm_history_delete_notice_p2": "無法還原此操作。",
     "menu_action_save_to_pocket": "儲存至 Pocket",
     "search_for_something_with": "搜尋 {search_term} 使用:",
     "search_button": "搜尋",
     "search_header": "{search_engine_name} 搜尋",
     "search_web_placeholder": "搜尋 Web",
     "search_settings": "變更搜尋選項",
+    "section_info_option": "更多資訊",
     "welcome_title": "歡迎來到新分頁",
     "welcome_body": "Firefox 會使用此空間來顯示與您最相關的書籤、文章、影片以及您最近造訪的頁面,這樣您就可以快速回到這些網站。",
     "welcome_label": "找出您的精選網站",
     "time_label_less_than_minute": "不到 1 分鐘內",
     "time_label_minute": "{number} 分鐘",
     "time_label_hour": "{number} 小時",
     "time_label_day": "{number} 天",
     "settings_pane_button_label": "自訂您的新分頁頁面",
@@ -5327,17 +5524,17 @@
     "settings_pane_topsites_header": "熱門網站",
     "settings_pane_topsites_body": "前往您最常造訪的網站。",
     "settings_pane_topsites_options_showmore": "顯示兩行",
     "settings_pane_bookmarks_header": "近期新增的書籤",
     "settings_pane_bookmarks_body": "將您新建立的書籤,放在隨手可得的地方。",
     "settings_pane_visit_again_header": "再次造訪",
     "settings_pane_visit_again_body": "Firefox 將顯示您一部份可能想要再次開啟的瀏覽紀錄。",
     "settings_pane_pocketstories_header": "熱門文章",
-    "settings_pane_pocketstories_body": "Pocket 是 Mozilla 大家庭的一份子,可讓您與您還沒發現的高品質內容連結起來。",
+    "settings_pane_pocketstories_body": "Pocket 是 Mozilla 家族的一份子,將您可能沒發現的高品質內容帶到眼前。",
     "settings_pane_done_button": "完成",
     "edit_topsites_button_text": "編輯",
     "edit_topsites_button_label": "自訂您的「熱門網站」區塊",
     "edit_topsites_showmore_button": "顯示更多",
     "edit_topsites_showless_button": "顯示更少",
     "edit_topsites_done_button": "完成",
     "edit_topsites_pin_button": "釘選此網站",
     "edit_topsites_unpin_button": "取消釘選此網站",
@@ -5349,14 +5546,18 @@
     "topsites_form_title_placeholder": "輸入標題",
     "topsites_form_url_placeholder": "輸入或貼上網址",
     "topsites_form_add_button": "新增",
     "topsites_form_save_button": "儲存",
     "topsites_form_cancel_button": "取消",
     "topsites_form_url_validation": "請輸入有效的網址",
     "pocket_read_more": "熱門主題:",
     "pocket_read_even_more": "檢視更多文章",
-    "pocket_feedback_header": "由超過兩千五百萬使用者一同策展出最棒的 Web。",
-    "pocket_feedback_body": "Pocket 是 Mozilla 大家庭的一份子,可讓您與您還沒發現的高品質內容連結起來。",
-    "pocket_send_feedback": "傳送意見回饋"
+    "pocket_feedback_header": "由超過兩千五百萬人找出來的 Web 最佳內容。",
+    "pocket_feedback_body": "Pocket 是 Mozilla 家族的一份子,將您可能沒發現的高品質內容帶到眼前。",
+    "pocket_send_feedback": "傳送意見回饋",
+    "topstories_empty_state": "所有文章都讀完啦!晚點再來,{provider} 將提供更多推薦故事。等不及了?選擇熱門主題,看看 Web 上各式精采資訊。",
+    "manual_migration_explanation": "匯入其他瀏覽器裡的書籤和網站,體驗 Firefox 的方便之處。",
+    "manual_migration_cancel_button": "不必了",
+    "manual_migration_import_button": "立即匯入"
   },
   "zu": {}
 }
\ No newline at end of file
--- a/browser/extensions/activity-stream/lib/ActivityStream.jsm
+++ b/browser/extensions/activity-stream/lib/ActivityStream.jsm
@@ -1,14 +1,15 @@
 /* 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";
 
 const {utils: Cu} = Components;
+Cu.import("resource://gre/modules/Services.jsm");
 
 // NB: Eagerly load modules that will be loaded/constructed/initialized in the
 // common case to avoid the overhead of wrapping and detecting lazy loading.
 const {actionTypes: at} = Cu.import("resource://activity-stream/common/Actions.jsm", {});
 const {DefaultPrefs} = Cu.import("resource://activity-stream/lib/ActivityStreamPrefs.jsm", {});
 const {LocalizationFeed} = Cu.import("resource://activity-stream/lib/LocalizationFeed.jsm", {});
 const {ManualMigration} = Cu.import("resource://activity-stream/lib/ManualMigration.jsm", {});
 const {NewTabInit} = Cu.import("resource://activity-stream/lib/NewTabInit.jsm", {});
@@ -23,17 +24,18 @@ const {TopStoriesFeed} = Cu.import("reso
 
 const REASON_ADDON_UNINSTALL = 6;
 
 // Sections, keyed by section id
 const SECTIONS = new Map([
   ["topstories", {
     feed: TopStoriesFeed,
     prefTitle: "Fetches content recommendations from a configurable content provider",
-    showByDefault: false
+     // for now, we only want to show top stories by default to the following locales
+    showByDefault: ["en-US", "en-CA"].includes(Services.locale.getRequestedLocale())
   }]
 ]);
 
 const SECTION_FEEDS_CONFIG = Array.from(SECTIONS.entries()).map(entry => {
   const id = entry[0];
   const {feed: Feed, prefTitle, showByDefault: value} = entry[1];
   return {
     name: `section.${id}`,
@@ -69,23 +71,25 @@ const PREFS_CONFIG = new Map([
   ["telemetry.ping.endpoint", {
     title: "Telemetry server endpoint",
     value: "https://tiles.services.mozilla.com/v4/links/activity-stream"
   }],
   ["feeds.section.topstories.options", {
     title: "Configuration options for top stories feed",
     value: `{
       "stories_endpoint": "https://getpocket.com/v3/firefox/global-recs?consumer_key=$apiKey",
+      "stories_referrer": "https://getpocket.com/recommendations",
       "topics_endpoint": "https://getpocket.com/v3/firefox/trending-topics?consumer_key=$apiKey",
       "read_more_endpoint": "https://getpocket.com/explore/trending?src=ff_new_tab",
       "learn_more_endpoint": "https://getpocket.com/firefox_learnmore?src=ff_newtab",
       "survey_link": "https://www.surveymonkey.com/r/newtabffx",
       "api_key_pref": "extensions.pocket.oAuthConsumerKey",
       "provider_name": "Pocket",
-      "provider_icon": "pocket"
+      "provider_icon": "pocket",
+      "provider_description": "pocket_feedback_body"
     }`
   }],
   ["migrationExpired", {
     title: "Boolean flag that decides whether to show the migration message or not.",
     value: false
   }],
   ["migrationRemainingDays", {
     title: "Number of days to show the manual migration message",
--- a/browser/extensions/activity-stream/lib/ActivityStreamMessageChannel.jsm
+++ b/browser/extensions/activity-stream/lib/ActivityStreamMessageChannel.jsm
@@ -42,16 +42,17 @@ this.ActivityStreamMessageChannel = clas
   constructor(options = {}) {
     Object.assign(this, DEFAULT_OPTIONS, options);
     this.channel = null;
 
     this.middleware = this.middleware.bind(this);
     this.onMessage = this.onMessage.bind(this);
     this.onNewTabLoad = this.onNewTabLoad.bind(this);
     this.onNewTabUnload = this.onNewTabUnload.bind(this);
+    this.onNewTabInit = this.onNewTabInit.bind(this);
   }
 
   /**
    * middleware - Redux middleware that looks for SendToContent and BroadcastToContent type
    *              actions, and sends them out.
    *
    * @param  {object} store A redux store
    * @return {function} Redux middleware
@@ -125,32 +126,43 @@ this.ActivityStreamMessageChannel = clas
    *                 between the main process and child pages
    */
   createChannel() {
     //  RemotePageManager must be disabled for about:newtab, since only one can exist at once
     if (this.pageURL === ABOUT_NEW_TAB_URL) {
       AboutNewTab.override();
     }
     this.channel = new RemotePages(this.pageURL);
+    this.channel.addMessageListener("RemotePage:Init", this.onNewTabInit);
     this.channel.addMessageListener("RemotePage:Load", this.onNewTabLoad);
     this.channel.addMessageListener("RemotePage:Unload", this.onNewTabUnload);
     this.channel.addMessageListener(this.incomingMessageName, this.onMessage);
   }
 
   /**
    * destroyChannel - Destroys the RemotePages channel
    */
   destroyChannel() {
     this.channel.destroy();
     this.channel = null;
     if (this.pageURL === ABOUT_NEW_TAB_URL) {
       AboutNewTab.reset();
     }
   }
 
+/**
+ * onNewTabInit - Handler for special RemotePage:Init message fired
+ * by RemotePages
+ *
+ * @param  {obj} msg The messsage from a page that was just initialized
+ */
+  onNewTabInit(msg) {
+    this.onActionFromContent({type: at.NEW_TAB_INIT}, msg.target.portID);
+  }
+
   /**
    * onNewTabLoad - Handler for special RemotePage:Load message fired by RemotePages
    *
    * @param  {obj} msg The messsage from a page that was just loaded
    */
   onNewTabLoad(msg) {
     this.onActionFromContent({type: at.NEW_TAB_LOAD}, msg.target.portID);
   }
--- a/browser/extensions/activity-stream/lib/PlacesFeed.jsm
+++ b/browser/extensions/activity-stream/lib/PlacesFeed.jsm
@@ -181,16 +181,24 @@ class PlacesFeed {
     if (topic === LINK_BLOCKED_EVENT) {
       this.store.dispatch(ac.BroadcastToContent({
         type: at.PLACES_LINK_BLOCKED,
         data: {url: value}
       }));
     }
   }
 
+  openNewWindow(action, isPrivate = false) {
+    const win = action._target.browser.ownerGlobal;
+    const privateParam = {private: isPrivate};
+    const params = (action.data.referrer) ?
+      Object.assign(privateParam, {referrerURI: Services.io.newURI(action.data.referrer)}) : privateParam;
+    win.openLinkIn(action.data.url, "window", params);
+  }
+
   onAction(action) {
     switch (action.type) {
       case at.INIT:
         // Briefly avoid loading services for observing for better startup timing
         Services.tm.dispatchToMainThread(() => this.addObservers());
         break;
       case at.UNINIT:
         this.removeObservers();
@@ -202,19 +210,33 @@ class PlacesFeed {
         NewTabUtils.activityStreamLinks.addBookmark(action.data);
         break;
       case at.DELETE_BOOKMARK_BY_ID:
         NewTabUtils.activityStreamLinks.deleteBookmark(action.data);
         break;
       case at.DELETE_HISTORY_URL:
         NewTabUtils.activityStreamLinks.deleteHistoryEntry(action.data);
         break;
+      case at.OPEN_NEW_WINDOW:
+        this.openNewWindow(action);
+        break;
+      case at.OPEN_PRIVATE_WINDOW:
+        this.openNewWindow(action, true);
+        break;
       case at.SAVE_TO_POCKET:
         Pocket.savePage(action._target.browser, action.data.site.url, action.data.site.title);
         break;
+      case at.OPEN_LINK: {
+        if (action.data.referrer) {
+          action._target.browser.loadURI(action.data.url, Services.io.newURI(action.data.referrer));
+        } else {
+          action._target.browser.loadURI(action.data.url);
+        }
+        break;
+      }
     }
   }
 }
 
 this.PlacesFeed = PlacesFeed;
 
 // Exported for testing only
 PlacesFeed.HistoryObserver = HistoryObserver;
--- a/browser/extensions/activity-stream/lib/SnippetsFeed.jsm
+++ b/browser/extensions/activity-stream/lib/SnippetsFeed.jsm
@@ -1,52 +1,71 @@
 /* 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";
 
 const {utils: Cu} = Components;
 
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/Console.jsm");
 const {actionTypes: at, actionCreators: ac} = Cu.import("resource://activity-stream/common/Actions.jsm", {});
 
+XPCOMUtils.defineLazyModuleGetter(this, "ProfileAge",
+  "resource://gre/modules/ProfileAge.jsm");
+
 // Url to fetch snippets, in the urlFormatter service format.
 const SNIPPETS_URL_PREF = "browser.aboutHomeSnippets.updateUrl";
+const TELEMETRY_PREF = "datareporting.healthreport.uploadEnabled";
 
 // Should be bumped up if the snippets content format changes.
-const STARTPAGE_VERSION = 4;
+const STARTPAGE_VERSION = 5;
+
+const ONE_WEEK = 7 * 24 * 60 * 60 * 1000;
 
 this.SnippetsFeed = class SnippetsFeed {
   constructor() {
-    this._onUrlChange = this._onUrlChange.bind(this);
+    this._refresh = this._refresh.bind(this);
   }
   get snippetsURL() {
     const updateURL = Services
       .prefs.getStringPref(SNIPPETS_URL_PREF)
       .replace("%STARTPAGE_VERSION%", STARTPAGE_VERSION);
     return Services.urlFormatter.formatURL(updateURL);
   }
-  init() {
+  async getProfileInfo() {
+    const profileAge = new ProfileAge(null, null);
+    const createdDate = await profileAge.created;
+    const resetDate = await profileAge.reset;
+    return {
+      createdWeeksAgo:  Math.floor((Date.now() - createdDate) / ONE_WEEK),
+      resetWeeksAgo: resetDate ? Math.floor((Date.now() - resetDate) / ONE_WEEK) : null
+    };
+  }
+  async _refresh() {
+    const profileInfo = await this.getProfileInfo();
     const data = {
       snippetsURL: this.snippetsURL,
-      version: STARTPAGE_VERSION
+      version: STARTPAGE_VERSION,
+      profileCreatedWeeksAgo: profileInfo.createdWeeksAgo,
+      profileResetWeeksAgo: profileInfo.resetWeeksAgo,
+      telemetryEnabled: Services.prefs.getBoolPref(TELEMETRY_PREF)
     };
+
     this.store.dispatch(ac.BroadcastToContent({type: at.SNIPPETS_DATA, data}));
-    Services.prefs.addObserver(SNIPPETS_URL_PREF, this._onUrlChange);
+  }
+  async init() {
+    await this._refresh();
+    Services.prefs.addObserver(SNIPPETS_URL_PREF, this._refresh);
+    Services.prefs.addObserver(TELEMETRY_PREF, this._refresh);
   }
   uninit() {
     this.store.dispatch({type: at.SNIPPETS_RESET});
-    Services.prefs.removeObserver(SNIPPETS_URL_PREF, this._onUrlChange);
-  }
-  _onUrlChange() {
-    this.store.dispatch(ac.BroadcastToContent({
-      type: at.SNIPPETS_DATA,
-      data: {snippetsURL: this.snippetsURL}
-    }));
+    Services.prefs.removeObserver(SNIPPETS_URL_PREF, this._refresh);
+    Services.prefs.removeObserver(TELEMETRY_PREF, this._refresh);
   }
   onAction(action) {
     switch (action.type) {
       case at.INIT:
         this.init();
         break;
       case at.FEED_INIT:
         if (action.data === "feeds.snippets") { this.init(); }
--- a/browser/extensions/activity-stream/lib/TelemetryFeed.jsm
+++ b/browser/extensions/activity-stream/lib/TelemetryFeed.jsm
@@ -30,16 +30,51 @@ this.TelemetryFeed = class TelemetryFeed
   init() {
     Services.obs.addObserver(this.browserOpenNewtabStart, "browser-open-newtab-start");
   }
 
   browserOpenNewtabStart() {
     perfService.mark("browser-open-newtab-start");
   }
 
+  setLoadTriggerInfo(port) {
+    // XXX note that there is a race condition here; we're assuming that no
+    // other tab will be interleaving calls to browserOpenNewtabStart and
+    // when at.NEW_TAB_INIT gets triggered by RemotePages and calls this
+    // method.  For manually created windows, it's hard to imagine us hitting
+    // this race condition.
+    //
+    // However, for session restore, where multiple windows with multiple tabs
+    // might be restored much closer together in time, it's somewhat less hard,
+    // though it should still be pretty rare.
+    //
+    // The fix to this would be making all of the load-trigger notifications
+    // return some data with their notifications, and somehow propagate that
+    // data through closures into the tab itself so that we could match them
+    //
+    // As of this writing (very early days of system add-on perf telemetry),
+    // the hypothesis is that hitting this race should be so rare that makes
+    // more sense to live with the slight data inaccuracy that it would
+    // introduce, rather than doing the correct but complicated thing.  It may
+    // well be worth reexamining this hypothesis after we have more experience
+    // with the data.
+
+    let data_to_save;
+    try {
+      data_to_save = {
+        load_trigger_ts: perfService.getMostRecentAbsMarkStartByName("browser-open-newtab-start"),
+        load_trigger_type: "menu_plus_or_keyboard"
+      };
+    } catch (e) {
+      // if no mark was returned, we have nothing to save
+      return;
+    }
+    this.saveSessionPerfData(port, data_to_save);
+  }
+
   /**
    * Lazily get the Telemetry id promise
    */
   get telemetryClientId() {
     Object.defineProperty(this, "telemetryClientId", {value: ClientID.getClientID()});
     return this.telemetryClientId;
   }
 
@@ -50,62 +85,27 @@ this.TelemetryFeed = class TelemetryFeed
     Object.defineProperty(this, "telemetrySender", {value: new TelemetrySender()});
     return this.telemetrySender;
   }
 
   /**
    * addSession - Start tracking a new session
    *
    * @param  {string} id the portID of the open session
-   * @param  {number} absVisChangeTime Optional. Absolute timestamp of
-   *                                   document.visibilityState becoming visible
+   *
    * @return {obj}    Session object
    */
-  addSession(id, absVisChangeTime) {
-    // XXX note that there is a race condition here; we're assuming that no
-    // other tab will be interleaving calls to browserOpenNewtabStart and
-    // addSession on this object.  For manually created windows, it's hard to
-    // imagine us hitting this race condition.
-    //
-    // However, for session restore, where multiple windows with multiple tabs
-    // might be restored much closer together in time, it's somewhat less hard,
-    // though it should still be pretty rare.
-    //
-    // The fix to this would be making all of the load-trigger notifications
-    // return some data with their notifications, and somehow propagate that
-    // data through closures into the tab itself so that we could match them
-    //
-    // As of this writing (very early days of system add-on perf telemetry),
-    // the hypothesis is that hitting this race should be so rare that makes
-    // more sense to live with the slight data inaccuracy that it would
-    // introduce, rather than doing the correct by complicated thing.  It may
-    // well be worth reexamining this hypothesis after we have more experience
-    // with the data.
-    let absBrowserOpenTabStart;
-    try {
-      absBrowserOpenTabStart = perfService.getMostRecentAbsMarkStartByName("browser-open-newtab-start");
-    } catch (e) {
-      // Just use undefined so it doesn't get sent to the server
-    }
+  addSession(id) {
+    const session = {
+      session_id: String(gUUIDGenerator.generateUUID()),
+      page: "about:newtab", // TODO: Handle about:home here
+      // "unexpected" will be overwritten when appropriate
+      perf: {load_trigger_type: "unexpected"}
+    };
 
-    // If we're missing either starting timestamps, treat it as an unexpected
-    // session; otherwise, assume it's the usual behavior.
-    const triggerType = absBrowserOpenTabStart === undefined ||
-      absVisChangeTime === undefined ? "unexpected" : "menu_plus_or_keyboard";
-
-    const session = {
-      start_time: Components.utils.now(),
-      session_id: String(gUUIDGenerator.generateUUID()),
-      page: "about:newtab", // TODO: Handle about:home here and in perf below
-      perf: {
-        load_trigger_ts: absBrowserOpenTabStart,
-        load_trigger_type: triggerType,
-        visibility_event_rcvd_ts: absVisChangeTime
-      }
-    };
     this.sessions.set(id, session);
     return session;
   }
 
   /**
    * endSession - Stop tracking a session
    *
    * @param  {string} portID the portID of the session that just closed
@@ -113,17 +113,20 @@ this.TelemetryFeed = class TelemetryFeed
   endSession(portID) {
     const session = this.sessions.get(portID);
 
     if (!session) {
       // It's possible the tab was never visible – in which case, there was no user session.
       return;
     }
 
-    session.session_duration = Math.round(Components.utils.now() - session.start_time);
+    if (session.perf.visibility_event_rcvd_ts) {
+      session.session_duration = Math.round(perfService.absNow() - session.perf.visibility_event_rcvd_ts);
+    }
+
     this.sendEvent(this.createSessionEndEvent(session));
     this.sessions.delete(portID);
   }
 
   /**
    * createPing - Create a ping with common properties
    *
    * @param  {string} id The portID of the session, if a session is relevant (optional)
@@ -162,17 +165,17 @@ this.TelemetryFeed = class TelemetryFeed
       {value: 0}, // Default value
       action.data,
       {action: "activity_stream_undesired_event"}
     );
   }
 
   async createPerformanceEvent(action) {
     return Object.assign(
-      await this.createPing(au.getPortIdOfSender(action)),
+      await this.createPing(),
       action.data,
       {action: "activity_stream_performance_event"}
     );
   }
 
   async createSessionEndEvent(session) {
     return Object.assign(
       await this.createPing(),
@@ -190,35 +193,59 @@ this.TelemetryFeed = class TelemetryFeed
     this.telemetrySender.sendPing(await eventPromise);
   }
 
   onAction(action) {
     switch (action.type) {
       case at.INIT:
         this.init();
         break;
-      case at.NEW_TAB_VISIBLE:
-        this.addSession(au.getPortIdOfSender(action),
-          action.data.absVisibilityChangeTime);
+      case at.NEW_TAB_INIT:
+        this.addSession(au.getPortIdOfSender(action));
+        this.setLoadTriggerInfo(au.getPortIdOfSender(action));
         break;
       case at.NEW_TAB_UNLOAD:
         this.endSession(au.getPortIdOfSender(action));
         break;
+      case at.SAVE_SESSION_PERF_DATA:
+        this.saveSessionPerfData(au.getPortIdOfSender(action), action.data);
+        break;
       case at.TELEMETRY_UNDESIRED_EVENT:
         this.sendEvent(this.createUndesiredEvent(action));
         break;
       case at.TELEMETRY_USER_EVENT:
         this.sendEvent(this.createUserEvent(action));
         break;
       case at.TELEMETRY_PERFORMANCE_EVENT:
         this.sendEvent(this.createPerformanceEvent(action));
         break;
     }
   }
 
+  /**
+   * Take all enumerable members of the data object and merge them into
+   * the session.perf object for the given port, so that it is sent to the
+   * server when the session ends.  All members of the data object should
+   * be valid values of the perf object, as defined in pings.js and the
+   * data*.md documentation.
+   *
+   * @note Any existing keys with the same names already in the
+   * session perf object will be overwritten by values passed in here.
+   *
+   * @param {String} port  The session with which this is associated
+   * @param {Object} data  The perf data to be
+   */
+  saveSessionPerfData(port, data) {
+    // XXX should use try/catch and send a bad state indicator if this
+    // get blows up.
+    let session = this.sessions.get(port);
+
+    Object.assign(session.perf, data);
+  }
+
   uninit() {
     Services.obs.removeObserver(this.browserOpenNewtabStart,
       "browser-open-newtab-start");
 
     // Only uninit if the getter has initialized it
     if (Object.prototype.hasOwnProperty.call(this, "telemetrySender")) {
       this.telemetrySender.uninit();
     }
--- a/browser/extensions/activity-stream/lib/TopSitesFeed.jsm
+++ b/browser/extensions/activity-stream/lib/TopSitesFeed.jsm
@@ -83,20 +83,16 @@ this.TopSitesFeed = class TopSitesFeed {
       // Send an update to content so the preloaded tab can get the updated content
       this.store.dispatch(ac.SendToContent(newAction, target));
     } else {
       // Broadcast an update to all open content pages
       this.store.dispatch(ac.BroadcastToContent(newAction));
     }
     this.lastUpdated = Date.now();
   }
-  openNewWindow(action, isPrivate = false) {
-    const win = action._target.browser.ownerGlobal;
-    win.openLinkIn(action.data.url, "window", {private: isPrivate});
-  }
   _getPinnedWithData() {
     // Augment the pinned links with any other extra data we have for them already in the store
     const links = this.store.getState().TopSites.rows;
     const pinned = NewTabUtils.pinnedLinks.links;
     return pinned.map(pinnedLink => (pinnedLink ? Object.assign(links.find(link => link && link.url === pinnedLink.url) || {}, pinnedLink) : pinnedLink));
   }
   pin(action) {
     const {site, index} = action.data;
@@ -129,22 +125,16 @@ this.TopSitesFeed = class TopSitesFeed {
 
           // When a new tab is opened, if the last time we refreshed the data
           // is greater than 15 minutes, refresh the data.
           (Date.now() - this.lastUpdated >= UPDATE_TIME)
         ) {
           this.refresh(action.meta.fromTarget);
         }
         break;
-      case at.OPEN_NEW_WINDOW:
-        this.openNewWindow(action);
-        break;
-      case at.OPEN_PRIVATE_WINDOW:
-        this.openNewWindow(action, true);
-        break;
       case at.PLACES_HISTORY_CLEARED:
         this.refresh();
         break;
       case at.TOP_SITES_PIN:
         this.pin(action);
         break;
       case at.TOP_SITES_UNPIN:
         this.unpin(action);
--- a/browser/extensions/activity-stream/lib/TopStoriesFeed.jsm
+++ b/browser/extensions/activity-stream/lib/TopStoriesFeed.jsm
@@ -26,28 +26,30 @@ this.TopStoriesFeed = class TopStoriesFe
   init() {
     try {
       const prefs = new Prefs();
       const options = JSON.parse(prefs.get("feeds.section.topstories.options"));
       const apiKey = this._getApiKeyFromPref(options.api_key_pref);
       this.stories_endpoint = this._produceUrlWithApiKey(options.stories_endpoint, apiKey);
       this.topics_endpoint = this._produceUrlWithApiKey(options.topics_endpoint, apiKey);
       this.read_more_endpoint = options.read_more_endpoint;
+      this.stories_referrer = options.stories_referrer;
 
       // TODO https://github.com/mozilla/activity-stream/issues/2902
       const sectionOptions = {
         id: SECTION_ID,
+        eventSource: "TOP_STORIES",
         icon: options.provider_icon,
         title: {id: "header_recommended_by", values: {provider: options.provider_name}},
         rows: [],
         maxCards: 3,
         contextMenuOptions: ["CheckBookmark", "SaveToPocket", "Separator", "OpenInNewWindow", "OpenInPrivateWindow", "Separator", "BlockUrl"],
         infoOption: {
           header: {id: "pocket_feedback_header"},
-          body: {id: "pocket_feedback_body"},
+          body: {id: options.provider_description},
           link: {
             href: options.survey_link,
             id: "pocket_send_feedback"
           }
         },
         emptyState: {
           message: {id: "topstories_empty_state", values: {provider: options.provider_name}},
           icon: "check"
@@ -80,16 +82,17 @@ this.TopStoriesFeed = class TopStoriesFe
           items = items
             .filter(s => !NewTabUtils.blockedLinks.isBlocked({"url": s.dedupe_url}))
             .map(s => ({
               "guid": s.id,
               "type": (Date.now() - (s.published_timestamp * 1000)) <= STORIES_NOW_THRESHOLD ? "now" : "trending",
               "title": s.title,
               "description": s.excerpt,
               "image": this._normalizeUrl(s.image_src),
+              "referrer": this.stories_referrer,
               "url": s.dedupe_url
             }));
           return items;
         })
         .catch(error => Cu.reportError(`Failed to fetch content: ${error.message}`));
 
       if (stories) {
         this.dispatchUpdateEvent(this.storiesLastUpdated,
--- a/browser/extensions/activity-stream/test/schemas/pings.js
+++ b/browser/extensions/activity-stream/test/schemas/pings.js
@@ -65,17 +65,17 @@ const PerfPing = Joi.object().keys(Objec
   event: Joi.string().required(),
   action: Joi.valid("activity_stream_performance_event").required(),
   value: Joi.number().required()
 }));
 
 const SessionPing = Joi.object().keys(Object.assign({}, baseKeys, {
   session_id: baseKeys.session_id.required(),
   page: baseKeys.page.required(),
-  session_duration: Joi.number().integer().required(),
+  session_duration: Joi.number().integer(),
   action: Joi.valid("activity_stream_session").required(),
   perf: Joi.object().keys({
     // Timestamp of the action perceived by the user to trigger the load
     // of this page.
     //
     // Not required at least for the error cases where the
     // observer event doesn't fire
     load_trigger_ts: Joi.number().positive()
@@ -83,16 +83,23 @@ const SessionPing = Joi.object().keys(Ob
 
     // What was the perceived trigger of the load action?
     //
     // Not required at least for the error cases where the observer event
     // doesn't fire
     load_trigger_type: Joi.valid(["menu_plus_or_keyboard", "unexpected"])
       .notes(["server counter", "server counter alert"]).required(),
 
+    // When did the topsites element finish painting?  Note that, at least for
+    // the first tab to be loaded, and maybe some others, this will be before
+    // topsites has yet to receive screenshots updates from the add-on code,
+    // and is therefore just showing placeholder screenshots.
+    topsites_first_painted_ts: Joi.number().positive()
+      .notes(["server counter", "server counter alert"]),
+
     // When the page itself receives an event that document.visibilityState
     // == visible.
     //
     // Not required at least for the (error?) case where the
     // visibility_event doesn't fire.  (It's not clear whether this
     // can happen in practice, but if it does, we'd like to know about it).
     visibility_event_rcvd_ts: Joi.number().positive()
       .notes(["server counter", "server counter alert"])
--- a/browser/extensions/activity-stream/test/unit/common/PerfService.test.js
+++ b/browser/extensions/activity-stream/test/unit/common/PerfService.test.js
@@ -13,16 +13,23 @@ describe("_PerfService", () => {
     fakePerfObj = new FakePerformance();
     perfService = new _PerfService({performanceObj: fakePerfObj});
   });
 
   afterEach(() => {
     sandbox.restore();
   });
 
+  describe("#absNow", () => {
+    it("should return a number > the time origin", () => {
+      const absNow = perfService.absNow();
+
+      assert.isAbove(absNow, perfService.timeOrigin);
+    });
+  });
   describe("#getEntriesByName", () => {
     it("should call getEntriesByName on the appropriate Window.performance",
     () => {
       sandbox.spy(fakePerfObj, "getEntriesByName");
 
       perfService.getEntriesByName("monkey", "mark");
 
       assert.calledOnce(fakePerfObj.getEntriesByName);
@@ -73,12 +80,12 @@ describe("_PerfService", () => {
 
       assert.calledOnce(fakePerfObj.mark);
       assert.calledWithExactly(fakePerfObj.mark, "monkey");
     });
   });
 
   describe("#timeOrigin", () => {
     it("should get the origin of the wrapped performance object", () => {
-      assert.equal(perfService.timeOrigin, 10000); // fake origin from utils.js
+      assert.equal(perfService.timeOrigin, fakePerfObj.timeOrigin);
     });
   });
 });
--- a/browser/extensions/activity-stream/test/unit/lib/ActivityStreamMessageChannel.test.js
+++ b/browser/extensions/activity-stream/test/unit/lib/ActivityStreamMessageChannel.test.js
@@ -47,19 +47,19 @@ describe("ActivityStreamMessageChannel",
   });
   describe("Creating/destroying the channel", () => {
     describe("#createChannel", () => {
       it("should create .channel with the correct URL", () => {
         mm.createChannel();
         assert.ok(mm.channel);
         assert.equal(mm.channel.url, mm.pageURL);
       });
-      it("should add 3 message listeners", () => {
+      it("should add 4 message listeners", () => {
         mm.createChannel();
-        assert.callCount(mm.channel.addMessageListener, 3);
+        assert.callCount(mm.channel.addMessageListener, 4);
       });
       it("should add the custom message listener to the channel", () => {
         mm.createChannel();
         assert.calledWith(mm.channel.addMessageListener, mm.incomingMessageName, mm.onMessage);
       });
       it("should override AboutNewTab", () => {
         mm.createChannel();
         assert.calledOnce(global.AboutNewTab.override);
@@ -106,16 +106,24 @@ describe("ActivityStreamMessageChannel",
       });
       it("should return null if the target doesn't exist", () => {
         const t = {portID: "foo"};
         mm.createChannel();
         mm.channel.messagePorts.push(t);
         assert.equal(mm.getTargetById("bar"), null);
       });
     });
+    describe("#onNewTabInit", () => {
+      it("should dispatch a NEW_TAB_INIT action", () => {
+        const t = {portID: "foo"};
+        sinon.stub(mm, "onActionFromContent");
+        mm.onNewTabInit({target: t});
+        assert.calledWith(mm.onActionFromContent, {type: at.NEW_TAB_INIT}, "foo");
+      });
+    });
     describe("#onNewTabLoad", () => {
       it("should dispatch a NEW_TAB_LOAD action", () => {
         const t = {portID: "foo"};
         sinon.stub(mm, "onActionFromContent");
         mm.onNewTabLoad({target: t});
         assert.calledWith(mm.onActionFromContent, {type: at.NEW_TAB_LOAD}, "foo");
       });
     });
--- a/browser/extensions/activity-stream/test/unit/lib/PlacesFeed.test.js
+++ b/browser/extensions/activity-stream/test/unit/lib/PlacesFeed.test.js
@@ -94,16 +94,59 @@ describe("PlacesFeed", () => {
     it("should delete a bookmark on DELETE_BOOKMARK_BY_ID", () => {
       feed.onAction({type: at.DELETE_BOOKMARK_BY_ID, data: "g123kd"});
       assert.calledWith(global.NewTabUtils.activityStreamLinks.deleteBookmark, "g123kd");
     });
     it("should delete a history entry on DELETE_HISTORY_URL", () => {
       feed.onAction({type: at.DELETE_HISTORY_URL, data: "guava.com"});
       assert.calledWith(global.NewTabUtils.activityStreamLinks.deleteHistoryEntry, "guava.com");
     });
+    it("should call openNewWindow with the correct url on OPEN_NEW_WINDOW", () => {
+      sinon.stub(feed, "openNewWindow");
+      const openWindowAction = {type: at.OPEN_NEW_WINDOW, data: {url: "foo.com"}};
+      feed.onAction(openWindowAction);
+      assert.calledWith(feed.openNewWindow, openWindowAction);
+    });
+    it("should call openNewWindow with the correct url and privacy args on OPEN_PRIVATE_WINDOW", () => {
+      sinon.stub(feed, "openNewWindow");
+      const openWindowAction = {type: at.OPEN_PRIVATE_WINDOW, data: {url: "foo.com"}};
+      feed.onAction(openWindowAction);
+      assert.calledWith(feed.openNewWindow, openWindowAction, true);
+    });
+    it("should call openNewWindow with the correct url on OPEN_NEW_WINDOW", () => {
+      const openWindowAction = {
+        type: at.OPEN_NEW_WINDOW,
+        data: {url: "foo.com"},
+        _target: {browser: {ownerGlobal: {openLinkIn: () => {}}}}
+      };
+      sinon.stub(openWindowAction._target.browser.ownerGlobal, "openLinkIn");
+      feed.onAction(openWindowAction);
+      assert.calledOnce(openWindowAction._target.browser.ownerGlobal.openLinkIn);
+    });
+    it("should open link on OPEN_LINK", () => {
+      sinon.stub(feed, "openNewWindow");
+      const openLinkAction = {
+        type: at.OPEN_LINK,
+        data: {url: "foo.com"},
+        _target: {browser: {loadURI: sinon.spy()}}
+      };
+      feed.onAction(openLinkAction);
+      assert.calledWith(openLinkAction._target.browser.loadURI, openLinkAction.data.url);
+    });
+    it("should open link with referrer on OPEN_LINK", () => {
+      globals.set("Services", {io: {newURI: url => `URI:${url}`}});
+      sinon.stub(feed, "openNewWindow");
+      const openLinkAction = {
+        type: at.OPEN_LINK,
+        data: {url: "foo.com", referrer: "foo.com/ref"},
+        _target: {browser: {loadURI: sinon.spy()}}
+      };
+      feed.onAction(openLinkAction);
+      assert.calledWith(openLinkAction._target.browser.loadURI, openLinkAction.data.url, `URI:${openLinkAction.data.referrer}`);
+    });
     it("should save to Pocket on SAVE_TO_POCKET", () => {
       feed.onAction({type: at.SAVE_TO_POCKET, data: {site: {url: "raspberry.com", title: "raspberry"}}, _target: {browser: {}}});
       assert.calledWith(global.Pocket.savePage, {}, "raspberry.com", "raspberry");
     });
   });
 
   describe("#observe", () => {
     it("should dispatch a PLACES_LINK_BLOCKED action with the url of the blocked link", () => {
--- a/browser/extensions/activity-stream/test/unit/lib/SnippetsFeed.test.js
+++ b/browser/extensions/activity-stream/test/unit/lib/SnippetsFeed.test.js
@@ -1,34 +1,65 @@
 const {SnippetsFeed} = require("lib/SnippetsFeed.jsm");
-const {actionTypes: at, actionCreators: ac} = require("common/Actions.jsm");
+const {actionTypes: at} = require("common/Actions.jsm");
+const {GlobalOverrider} = require("test/unit/utils");
+
+const WEEK_IN_MS = 7 * 24 * 60 * 60 * 1000;
+
+let overrider = new GlobalOverrider();
 
 describe("SnippetsFeed", () => {
   let sandbox;
+  let clock;
   beforeEach(() => {
+    clock = sinon.useFakeTimers();
+    overrider.set({
+      ProfileAge: class ProfileAge {
+        constructor() {
+          this.created = Promise.resolve(0);
+          this.reset = Promise.resolve(WEEK_IN_MS);
+        }
+      }
+    });
     sandbox = sinon.sandbox.create();
   });
   afterEach(() => {
+    clock.restore();
+    overrider.restore();
     sandbox.restore();
   });
-  it("should dispatch the right version and snippetsURL on INIT", () => {
+  it("should dispatch a SNIPPETS_DATA action with the right data on INIT", async () => {
     const url = "foo.com/%STARTPAGE_VERSION%";
     sandbox.stub(global.Services.prefs, "getStringPref").returns(url);
+    sandbox.stub(global.Services.prefs, "getBoolPref").returns(true);
     const feed = new SnippetsFeed();
     feed.store = {dispatch: sandbox.stub()};
 
+    clock.tick(WEEK_IN_MS * 2);
+
+    await feed.init();
+
+    assert.calledOnce(feed.store.dispatch);
+
+    const action = feed.store.dispatch.firstCall.args[0];
+    assert.propertyVal(action, "type", at.SNIPPETS_DATA);
+    assert.isObject(action.data);
+    assert.propertyVal(action.data, "snippetsURL", "foo.com/5");
+    assert.propertyVal(action.data, "version", 5);
+    assert.propertyVal(action.data, "profileCreatedWeeksAgo", 2);
+    assert.propertyVal(action.data, "profileResetWeeksAgo", 1);
+    assert.propertyVal(action.data, "telemetryEnabled", true);
+  });
+  it("should call .init on an INIT aciton", () => {
+    const feed = new SnippetsFeed();
+    sandbox.stub(feed, "init");
+    feed.store = {dispatch: sandbox.stub()};
+
     feed.onAction({type: at.INIT});
-
-    assert.calledWith(feed.store.dispatch, ac.BroadcastToContent({
-      type: at.SNIPPETS_DATA,
-      data: {
-        snippetsURL: "foo.com/4",
-        version: 4
-      }
-    }));
+    assert.calledOnce(feed.init);
   });
   it("should call .init when a FEED_INIT happens for feeds.snippets", () => {
     const feed = new SnippetsFeed();
     sandbox.stub(feed, "init");
     feed.store = {dispatch: sandbox.stub()};
 
     feed.onAction({type: at.FEED_INIT, data: "feeds.snippets"});
 
@@ -37,24 +68,9 @@ describe("SnippetsFeed", () => {
   it("should dispatch a SNIPPETS_RESET on uninit", () => {
     const feed = new SnippetsFeed();
     feed.store = {dispatch: sandbox.stub()};
 
     feed.uninit();
 
     assert.calledWith(feed.store.dispatch, {type: at.SNIPPETS_RESET});
   });
-  describe("_onUrlChange", () => {
-    it("should dispatch a new snippetsURL", () => {
-      const url = "boo.com/%STARTPAGE_VERSION%";
-      sandbox.stub(global.Services.prefs, "getStringPref").returns(url);
-      const feed = new SnippetsFeed();
-      feed.store = {dispatch: sandbox.stub()};
-
-      feed._onUrlChange();
-
-      assert.calledWith(feed.store.dispatch, ac.BroadcastToContent({
-        type: at.SNIPPETS_DATA,
-        data: {snippetsURL: "boo.com/4"}
-      }));
-    });
-  });
 });
--- a/browser/extensions/activity-stream/test/unit/lib/TelemetryFeed.test.js
+++ b/browser/extensions/activity-stream/test/unit/lib/TelemetryFeed.test.js
@@ -18,17 +18,21 @@ describe("TelemetryFeed", () => {
   let globals;
   let sandbox;
   let store = {
     dispatch() {},
     getState() { return {App: {version: "1.0.0", locale: "en-US"}}; }
   };
   let instance;
   class TelemetrySender {sendPing() {} uninit() {}}
-  class PerfService {getMostRecentAbsMarkStartByName() { return 1234; } mark() {}}
+  class PerfService {
+    getMostRecentAbsMarkStartByName() { return 1234; }
+    mark() {}
+    absNow() { return 123; }
+  }
   const perfService = new PerfService();
   const {TelemetryFeed} = injector({
     "lib/TelemetrySender.jsm": {TelemetrySender},
     "common/PerfService.jsm": {perfService}
   });
 
   beforeEach(() => {
     globals = new GlobalOverrider();
@@ -59,24 +63,16 @@ describe("TelemetryFeed", () => {
     });
   });
   describe("#addSession", () => {
     it("should add a session and return it", () => {
       const session = instance.addSession("foo");
 
       assert.equal(instance.sessions.get("foo"), session);
     });
-    it("should set the start_time", () => {
-      sandbox.spy(Components.utils, "now");
-
-      const session = instance.addSession("foo");
-
-      assert.calledOnce(Components.utils.now);
-      assert.equal(session.start_time, Components.utils.now.firstCall.returnValue);
-    });
     it("should set the session_id", () => {
       sandbox.spy(global.gUUIDGenerator, "generateUUID");
 
       const session = instance.addSession("foo");
 
       assert.calledOnce(global.gUUIDGenerator.generateUUID);
       assert.equal(session.session_id, global.gUUIDGenerator.generateUUID.firstCall.returnValue);
     });
@@ -85,54 +81,50 @@ describe("TelemetryFeed", () => {
 
       assert.equal(session.page, "about:newtab"); // This is hardcoded for now.
     });
     it("should set the perf type when lacking timestamp", () => {
       const session = instance.addSession("foo");
 
       assert.propertyVal(session.perf, "load_trigger_type", "unexpected");
     });
-    it("should set the perf type with timestamp", () => {
-      const session = instance.addSession("foo", 123);
-
-      assert.propertyVal(session.perf, "load_trigger_type", "menu_plus_or_keyboard"); // This is hardcoded for now.
-    });
-    it("should save visibility time", () => {
-      const session = instance.addSession("foo", 123);
-
-      assert.propertyVal(session.perf, "visibility_event_rcvd_ts", 123);
-    });
-    it("should not save visibility time when lacking timestamp", () => {
-      const session = instance.addSession("foo");
-
-      assert.propertyVal(session.perf, "visibility_event_rcvd_ts", undefined);
-    });
   });
   describe("#browserOpenNewtabStart", () => {
     it("should call perfService.mark with browser-open-newtab-start", () => {
       sandbox.stub(perfService, "mark");
 
       instance.browserOpenNewtabStart();
 
       assert.calledOnce(perfService.mark);
       assert.calledWithExactly(perfService.mark, "browser-open-newtab-start");
     });
   });
 
   describe("#endSession", () => {
     it("should not throw if there is no session for the given port ID", () => {
       assert.doesNotThrow(() => instance.endSession("doesn't exist"));
     });
-    it("should add a session_duration", () => {
+    it("should add a session_duration integer if there is a visibility_event_rcvd_ts", () => {
+      sandbox.stub(instance, "sendEvent");
+      const session = instance.addSession("foo");
+      session.perf.visibility_event_rcvd_ts = 444.4732;
+
+      instance.endSession("foo");
+
+      assert.isNumber(session.session_duration);
+      assert.ok(Number.isInteger(session.session_duration),
+        "session_duration should be an integer");
+    });
+    it("shouldn't add session_duration if there's no visibility_event_rcvd_ts", () => {
       sandbox.stub(instance, "sendEvent");
       const session = instance.addSession("foo");
 
       instance.endSession("foo");
 
-      assert.property(session, "session_duration");
+      assert.notProperty(session, "session_duration");
     });
     it("should remove the session from .sessions", () => {
       sandbox.stub(instance, "sendEvent");
       instance.addSession("foo");
 
       instance.endSession("foo");
 
       assert.isFalse(instance.sessions.has("foo"));
@@ -226,31 +218,16 @@ describe("TelemetryFeed", () => {
         const action = ac.PerfEvent({event: "SCREENSHOT_FINISHED", value: 100});
         const ping = await instance.createPerformanceEvent(action);
 
         // Is it valid?
         assert.validate(ping, PerfPing);
         // Does it have the right value?
         assert.propertyVal(ping, "value", 100);
       });
-      it("should create a valid event with a session", async () => {
-        const portID = "foo";
-        const data = {event: "PAGE_LOADED", value: 100};
-        const action = ac.SendToMain(ac.PerfEvent(data), portID);
-        const session = instance.addSession(portID);
-
-        const ping = await instance.createPerformanceEvent(action);
-
-        // Is it valid?
-        assert.validate(ping, PerfPing);
-        // Does it have the right session_id?
-        assert.propertyVal(ping, "session_id", session.session_id);
-        // Does it have the right value?
-        assert.propertyVal(ping, "value", 100);
-      });
     });
     describe("#createSessionEndEvent", () => {
       it("should create a valid event", async () => {
         const ping = await instance.createSessionEndEvent({
           session_id: FAKE_UUID,
           page: "about:newtab",
           session_duration: 12345,
           perf: {
@@ -285,16 +262,53 @@ describe("TelemetryFeed", () => {
   describe("#sendEvent", () => {
     it("should call telemetrySender", async () => {
       sandbox.stub(instance.telemetrySender, "sendPing");
       const event = {};
       await instance.sendEvent(Promise.resolve(event));
       assert.calledWith(instance.telemetrySender.sendPing, event);
     });
   });
+
+  describe("#setLoadTriggerInfo", () => {
+    it("should call saveSessionPerfData w/load_trigger_{ts,type} data", () => {
+      const stub = sandbox.stub(instance, "saveSessionPerfData");
+      sandbox.stub(perfService, "getMostRecentAbsMarkStartByName").returns(777);
+      instance.addSession("port123");
+
+      instance.setLoadTriggerInfo("port123");
+
+      assert.calledWith(stub, "port123", {
+        load_trigger_ts: 777,
+        load_trigger_type: "menu_plus_or_keyboard"
+      });
+    });
+
+    it("should not call saveSessionPerfData when getting mark throws", () => {
+      const stub = sandbox.stub(instance, "saveSessionPerfData");
+      sandbox.stub(perfService, "getMostRecentAbsMarkStartByName").throws();
+      instance.addSession("port123");
+
+      instance.setLoadTriggerInfo("port123");
+
+      assert.notCalled(stub);
+    });
+  });
+
+  describe("#saveSessionPerfData", () => {
+    it("should update the given session with the given data", () => {
+      instance.addSession("port123");
+      assert.notProperty(instance.sessions.get("port123"), "fake_ts");
+      const data = {fake_ts: 456, other_fake_ts: 789};
+
+      instance.saveSessionPerfData("port123", data);
+
+      assert.include(instance.sessions.get("port123").perf, data);
+    });
+  });
   describe("#uninit", () => {
     it("should call .telemetrySender.uninit", () => {
       const stub = sandbox.stub(instance.telemetrySender, "uninit");
       instance.uninit();
       assert.calledOnce(stub);
     });
     it("should make this.browserOpenNewtabStart() stop observing browser-open-newtab-start", async () => {
       await instance.init();
@@ -309,29 +323,53 @@ describe("TelemetryFeed", () => {
     });
   });
   describe("#onAction", () => {
     it("should call .init() on an INIT action", () => {
       const stub = sandbox.stub(instance, "init");
       instance.onAction({type: at.INIT});
       assert.calledOnce(stub);
     });
-    it("should call .addSession() on a NEW_TAB_VISIBLE action", () => {
+    it("should call .addSession() on a NEW_TAB_INIT action", () => {
       const stub = sandbox.stub(instance, "addSession");
+      sandbox.stub(instance, "setLoadTriggerInfo");
+
       instance.onAction(ac.SendToMain({
-        type: at.NEW_TAB_VISIBLE,
-        data: {absVisibilityChangeTime: 789}
+        type: at.NEW_TAB_INIT,
+        data: {}
       }, "port123"));
+
+      assert.calledOnce(stub);
+      assert.calledWith(stub, "port123");
+    });
+    it("should call .setLoadTriggerInfo() on NEW_TAB_INIT action", () => {
+      const stub = sandbox.stub(instance, "setLoadTriggerInfo");
+
+      instance.onAction(ac.SendToMain({
+        type: at.NEW_TAB_INIT,
+        data: {}
+      }, "port123"));
+
+      assert.calledOnce(stub);
       assert.calledWith(stub, "port123");
     });
     it("should call .endSession() on a NEW_TAB_UNLOAD action", () => {
       const stub = sandbox.stub(instance, "endSession");
       instance.onAction(ac.SendToMain({type: at.NEW_TAB_UNLOAD}, "port123"));
       assert.calledWith(stub, "port123");
     });
+    it("should call .saveSessionPerfData on SAVE_SESSION_PERF_DATA", () => {
+      const stub = sandbox.stub(instance, "saveSessionPerfData");
+      const data = {some_ts: 10};
+      const action = {type: at.SAVE_SESSION_PERF_DATA, data};
+
+      instance.onAction(ac.SendToMain(action, "port123"));
+
+      assert.calledWith(stub, "port123", data);
+    });
     it("should send an event on an TELEMETRY_UNDESIRED_EVENT action", () => {
       const sendEvent = sandbox.stub(instance, "sendEvent");
       const eventCreator = sandbox.stub(instance, "createUndesiredEvent");
       const action = {type: at.TELEMETRY_UNDESIRED_EVENT};
       instance.onAction(action);
       assert.calledWith(eventCreator, action);
       assert.calledWith(sendEvent, eventCreator.returnValue);
     });
--- a/browser/extensions/activity-stream/test/unit/lib/TopSitesFeed.test.js
+++ b/browser/extensions/activity-stream/test/unit/lib/TopSitesFeed.test.js
@@ -160,38 +160,16 @@ describe("Top Sites Feed", () => {
     });
     it("should not call refresh if .lastUpdated is less than update time on NEW_TAB_LOAD", () => {
       feed.lastUpdated = 0;
       clock.tick(UPDATE_TIME - 1);
       sinon.stub(feed, "refresh");
       feed.onAction(newTabAction);
       assert.notCalled(feed.refresh);
     });
-    it("should call openNewWindow with the correct url on OPEN_NEW_WINDOW", () => {
-      sinon.stub(feed, "openNewWindow");
-      const openWindowAction = {type: at.OPEN_NEW_WINDOW, data: {url: "foo.com"}};
-      feed.onAction(openWindowAction);
-      assert.calledWith(feed.openNewWindow, openWindowAction);
-    });
-    it("should call openNewWindow with the correct url and privacy args on OPEN_PRIVATE_WINDOW", () => {
-      sinon.stub(feed, "openNewWindow");
-      const openWindowAction = {type: at.OPEN_PRIVATE_WINDOW, data: {url: "foo.com"}};
-      feed.onAction(openWindowAction);
-      assert.calledWith(feed.openNewWindow, openWindowAction, true);
-    });
-    it("should call openNewWindow with the correct url on OPEN_NEW_WINDOW", () => {
-      const openWindowAction = {
-        type: at.OPEN_NEW_WINDOW,
-        data: {url: "foo.com"},
-        _target: {browser: {ownerGlobal: {openLinkIn: () => {}}}}
-      };
-      sinon.stub(openWindowAction._target.browser.ownerGlobal, "openLinkIn");
-      feed.onAction(openWindowAction);
-      assert.calledOnce(openWindowAction._target.browser.ownerGlobal.openLinkIn);
-    });
     it("should call with correct parameters on TOP_SITES_PIN", () => {
       const pinAction = {
         type: at.TOP_SITES_PIN,
         data: {site: {url: "foo.com"}, index: 7}
       };
       feed.onAction(pinAction);
       assert.calledOnce(fakeNewTabUtils.pinnedLinks.pin);
       assert.calledWith(fakeNewTabUtils.pinnedLinks.pin, pinAction.data.site, pinAction.data.index);
--- a/browser/extensions/activity-stream/test/unit/lib/TopStoriesFeed.test.js
+++ b/browser/extensions/activity-stream/test/unit/lib/TopStoriesFeed.test.js
@@ -11,21 +11,23 @@ describe("Top Stories Feed", () => {
   let SECTION_ID;
   let instance;
   let clock;
   let globals;
 
   beforeEach(() => {
     FakePrefs.prototype.prefs["feeds.section.topstories.options"] = `{
       "stories_endpoint": "https://somedomain.org/stories?key=$apiKey",
+      "stories_referrer": "https://somedomain.org/referrer",
       "topics_endpoint": "https://somedomain.org/topics?key=$apiKey",
       "survey_link": "https://www.surveymonkey.com/r/newtabffx",
       "api_key_pref": "apiKeyPref",
       "provider_name": "test-provider",
-      "provider_icon": "provider-icon"
+      "provider_icon": "provider-icon",
+      "provider_description": "provider_desc"
     }`;
     FakePrefs.prototype.prefs.apiKeyPref = "test-api-key";
 
     globals = new GlobalOverrider();
     clock = sinon.useFakeTimers();
 
     ({TopStoriesFeed, STORIES_UPDATE_TIME, TOPICS_UPDATE_TIME, SECTION_ID} = injector({"lib/ActivityStreamPrefs.jsm": {Prefs: FakePrefs}}));
     instance = new TopStoriesFeed();
@@ -37,29 +39,31 @@ describe("Top Stories Feed", () => {
   });
   describe("#init", () => {
     it("should create a TopStoriesFeed", () => {
       assert.instanceOf(instance, TopStoriesFeed);
     });
     it("should initialize endpoints based on prefs", () => {
       instance.onAction({type: at.INIT});
       assert.equal("https://somedomain.org/stories?key=test-api-key", instance.stories_endpoint);
+      assert.equal("https://somedomain.org/referrer", instance.stories_referrer);
       assert.equal("https://somedomain.org/topics?key=test-api-key", instance.topics_endpoint);
     });
     it("should register section", () => {
       const expectedSectionOptions = {
         id: SECTION_ID,
+        eventSource: "TOP_STORIES",
         icon: "provider-icon",
         title: {id: "header_recommended_by", values: {provider: "test-provider"}},
         rows: [],
         maxCards: 3,
         contextMenuOptions: ["CheckBookmark", "SaveToPocket", "Separator", "OpenInNewWindow", "OpenInPrivateWindow", "Separator", "BlockUrl"],
         infoOption: {
           header: {id: "pocket_feedback_header"},
-          body: {id: "pocket_feedback_body"},
+          body: {id: "provider_desc"},
           link: {
             href: "https://www.surveymonkey.com/r/newtabffx",
             id: "pocket_send_feedback"
           }
         },
         emptyState: {
           message: {id: "topstories_empty_state", values: {provider: "test-provider"}},
           icon: "check"
@@ -140,20 +144,22 @@ describe("Top Stories Feed", () => {
         "published_timestamp" : "123"
       }]}`;
       const stories = [{
         "guid": "1",
         "type": "now",
         "title": "title",
         "description": "description",
         "image": "image-url",
+        "referrer": "referrer",
         "url": "rec-url"
       }];
 
       instance.stories_endpoint = "stories-endpoint";
+      instance.stories_referrer = "referrer";
       fetchStub.resolves({ok: true, status: 200, text: () => response});
       await instance.fetchStories();
 
       assert.calledOnce(fetchStub);
       assert.calledWithExactly(fetchStub, instance.stories_endpoint);
       assert.calledOnce(instance.store.dispatch);
       assert.propertyVal(instance.store.dispatch.firstCall.args[0], "type", at.SECTION_ROWS_UPDATE);
       assert.deepEqual(instance.store.dispatch.firstCall.args[0].data.id, SECTION_ID);
--- a/browser/extensions/activity-stream/test/unit/unit-entry.js
+++ b/browser/extensions/activity-stream/test/unit/unit-entry.js
@@ -38,16 +38,17 @@ overrider.set({
     obs: {
       addObserver() {},
       removeObserver() {}
     },
     prefs: {
       addObserver() {},
       removeObserver() {},
       getStringPref() {},
+      getBoolPref() {},
       getDefaultBranch() {
         return {
           setBoolPref() {},
           setIntPref() {},
           setStringPref() {},
           clearUserPref() {}
         };
       }
--- a/browser/extensions/activity-stream/test/unit/utils.js
+++ b/browser/extensions/activity-stream/test/unit/utils.js
@@ -120,19 +120,19 @@ FakePrefs.prototype = {
 };
 
 function FakePerformance() {}
 FakePerformance.prototype = {
   marks: new Map(),
   now() {
     return window.performance.now();
   },
-  timing: {navigationStart: 222222},
+  timing: {navigationStart: 222222.123},
   get timeOrigin() {
-    return 10000;
+    return 10000.234;
   },
   // XXX assumes type == "mark"
   getEntriesByName(name, type) {
     if (this.marks.has(name)) {
       return this.marks.get(name);
     }
     return [];
   },