Merge mozilla-central to mozilla-inbound
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Tue, 25 Jul 2017 14:38:43 +0200
changeset 421982 4b4a6f82e3e8e9b4ecee284666eeb397f31aa8fc
parent 421981 e00f60085ca6ddd86acee9757c582baf57232807 (current diff)
parent 421904 07484bfdb96bc7297c404e377eea93f1d8ca4442 (diff)
child 421983 3d0a9de378ccae2e704832e6528267e090e4c071
push id1517
push userjlorenzo@mozilla.com
push dateThu, 14 Sep 2017 16:50:54 +0000
treeherdermozilla-release@3b41fd564418 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone56.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge mozilla-central to mozilla-inbound
build/moz.configure/toolchain.configure
devtools/client/jsonview/main.js
devtools/client/shared/shim/Services.js
devtools/client/shared/shim/moz.build
devtools/client/shared/shim/test/.eslintrc.js
devtools/client/shared/shim/test/file_service_wm.html
devtools/client/shared/shim/test/mochitest.ini
devtools/client/shared/shim/test/prefs-wrapper.js
devtools/client/shared/shim/test/test_service_appinfo.html
devtools/client/shared/shim/test/test_service_focus.html
devtools/client/shared/shim/test/test_service_prefs.html
devtools/client/shared/shim/test/test_service_prefs_defaults.html
devtools/client/shared/shim/test/test_service_wm.html
dom/tests/mochitest/chrome/test_window_getAppLocales.html
dom/tests/mochitest/chrome/test_window_getRegionalPrefsLocales.html
gfx/layers/d3d11/genshaders.py
gfx/layers/moz.build
mobile/android/app/src/main/res/drawable/as_contextmenu_divider.xml
mobile/android/app/src/main/res/drawable/as_contextmenu_divider_helper.xml
mobile/android/branding/beta/res/drawable/firefox_logo.png
mobile/android/branding/nightly-old-id/res/drawable/firefox_logo.png
mobile/android/branding/nightly/res/drawable/firefox_logo.png
mobile/android/branding/official/res/drawable/firefox_logo.png
mobile/android/branding/unofficial/res/drawable/firefox_logo.png
modules/libpref/init/all.js
netwerk/protocol/res/ExtensionProtocolHandler.cpp
testing/tools/autotry/__init__.py
testing/tools/autotry/autotry.py
third_party/rust/cssparser/src/big-data-url.css
third_party/rust/cssparser/src/compact_cow_str.rs
third_party/rust/cssparser/src/css-parsing-tests/An+B.json
third_party/rust/cssparser/src/css-parsing-tests/LICENSE
third_party/rust/cssparser/src/css-parsing-tests/README.rst
third_party/rust/cssparser/src/css-parsing-tests/color3.json
third_party/rust/cssparser/src/css-parsing-tests/color3_hsl.json
third_party/rust/cssparser/src/css-parsing-tests/color3_keywords.json
third_party/rust/cssparser/src/css-parsing-tests/component_value_list.json
third_party/rust/cssparser/src/css-parsing-tests/declaration_list.json
third_party/rust/cssparser/src/css-parsing-tests/make_color3_hsl.py
third_party/rust/cssparser/src/css-parsing-tests/make_color3_keywords.py
third_party/rust/cssparser/src/css-parsing-tests/one_component_value.json
third_party/rust/cssparser/src/css-parsing-tests/one_declaration.json
third_party/rust/cssparser/src/css-parsing-tests/one_rule.json
third_party/rust/cssparser/src/css-parsing-tests/rule_list.json
third_party/rust/cssparser/src/css-parsing-tests/stylesheet.json
third_party/rust/cssparser/src/css-parsing-tests/stylesheet_bytes.json
third_party/rust/cssparser/src/css-parsing-tests/urange.json
tools/profiler/core/platform.cpp
tools/tryselect/selectors/syntax.py
--- a/.taskcluster.yml
+++ b/.taskcluster.yml
@@ -1,128 +1,134 @@
----
-version: 0
-metadata:
-  name: 'Taskcluster tasks for Gecko'
-  description: "The taskcluster task graph for Gecko trees"
-  owner: mozilla-taskcluster-maintenance@mozilla.com
-  source: {{{source}}}
+# This file is rendered via JSON-e by
+# - mozilla-taskcluster - https://docs.taskcluster.net/reference/integrations/mozilla-taskcluster/docs/taskcluster-yml
+# - cron tasks - taskcluster/taskgraph/cron/decision.py
+version: 1
+tasks:
+  $let:
+    # sometimes the push user is just `ffxbld` or the like, but we want an email-like field..
+    ownerEmail: {$if: '"@" in push.owner', then: '${push.owner}', else: '${push.owner}@noreply.mozilla.org'}
+    # ensure there's no trailing `/` on the repo URL
+    repoUrl: {$if: 'repository.url[-1] == "/"', then: {$eval: 'repository.url[:-1]'}, else: {$eval: 'repository.url'}}
+  in:
+  - taskId: '${as_slugid("decision")}'
+    taskGroupId: '${as_slugid("decision")}' # same as tsakId; this is how automation identifies a decision tsak
+    schedulerId: 'gecko-level-${repository.level}'
 
-scopes:
-  # Note the below scopes are insecure however these get overriden on the server
-  # side to whatever scopes are set by mozilla-taskcluster.
-  - queue:*
-  - docker-worker:*
-  - scheduler:*
+    created: {$fromNow: ''}
+    deadline: {$fromNow: '1 day'}
+    expires: {$fromNow: '1 year 1 second'} # 1 second so artifacts expire first, despite rounding errors
+    metadata:
+      $merge:
+        - owner: "${ownerEmail}"
+          source: "${repoUrl}/raw-file/${push.revision}/.taskcluster.yml"
+        - $if: 'tasks_for == "hg-push"'
+          then:
+            name: "Gecko Decision Task"
+            description: 'The task that creates all of the other tasks in the task graph'
+          else:
+            name: "Decision Task for cron job ${cron.job_name}"
+            description: 'Created by a [cron task](https://tools.taskcluster.net/tasks/${cron.task_id})'
 
-# This file undergoes substitution to create tasks.  For on-push tasks, that
-# substitution is done by mozilla-taskcluster.  For cron tasks, that substitution
-# is done by `taskcluster/taskgraph/cron/decision.py`.  If you change any of the
-# template parameters, please do so in all three places!
-#
-# Available template parameters:
-#
-# - now:            current time
-# - owner:          push user (email address)
-# - source:         URL of this YAML file
-# - url:            repository URL
-# - project:        alias for the destination repository (basename of
-#                   the repo url)
-# - level:          SCM level of the destination repository
-#                   (1 = try, 3 = core)
-# - revision:       hg revision of the head of the push
-# - comment:        comment of the push
-# - pushlog_id:     id in the pushlog table of the repository
-#
-# and functions:
-# - as_slugid:      convert a label into a slugId
-# - from_now:       generate a timestamp at a fixed offset from now
-# - shellquote:     quote the contents for injection into shell
+    provisionerId: "aws-provisioner-v1"
+    workerType: "gecko-decision"
+
+    tags:
+      $if: 'tasks_for == "hg-push"'
+      then: {createdForUser: "${ownerEmail}"}
 
-# The resulting tasks' taskGroupId will be equal to the taskId of the first
-# task listed here, which should be the decision task.  This gives other tools
-# an easy way to determine the ID of the decision task that created a
-# particular group.
+    routes:
+      $if: 'tasks_for == "hg-push"'
+      then:
+        - "index.gecko.v2.${repository.project}.latest.firefox.decision"
+        - "index.gecko.v2.${repository.project}.pushlog-id.${push.pushlog_id}.decision"
+        - "tc-treeherder.v2.${repository.project}.${push.revision}.${push.pushlog_id}"
+        - "tc-treeherder-stage.v2.${repository.project}.${push.revision}.${push.pushlog_id}"
+        - "notify.email.${ownerEmail}.on-failed"
+        - "notify.email.${ownerEmail}.on-exception"
+      else:
+        - "index.gecko.v2.${repository.project}.latest.firefox.decision-${cron.job_name}"
+        - "tc-treeherder.v2.${repository.project}.${push.revision}.${push.pushlog_id}"
+        - "tc-treeherder-stage.v2.${repository.project}.${push.revision}.${push.pushlog_id}"
 
-tasks:
-  - taskId: '{{#as_slugid}}decision task{{/as_slugid}}'
-    task:
-      created: '{{now}}'
-      deadline: '{{#from_now}}1 day{{/from_now}}'
-      expires: '{{#from_now}}365 day{{/from_now}}'
-      metadata:
-        owner: mozilla-taskcluster-maintenance@mozilla.com
-        source: {{{source}}}
-        name: "Gecko Decision Task"
-        description: |
-            The task that creates all of the other tasks in the task graph
+    scopes:
+      $if: 'tasks_for == "hg-push"'
+      then:
+        - 'assume:repo:${repoUrl[8:]}:*'
+        - 'queue:route:notify.email.${ownerEmail}.*'
+      else:
+        - 'assume:repo:${repoUrl[8:]}:cron:${cron.job_name}'
 
-      workerType: "gecko-decision"
-      provisionerId: "aws-provisioner-v1"
+    dependencies: []
+    requires: all-completed
 
-      tags:
-        createdForUser: {{owner}}
+    priority: lowest
+    retries: 5
 
-      routes:
-        - "index.gecko.v2.{{project}}.latest.firefox.decision"
-        - "index.gecko.v2.{{project}}.pushlog-id.{{pushlog_id}}.decision"
-        - "tc-treeherder.v2.{{project}}.{{revision}}.{{pushlog_id}}"
-        - "tc-treeherder-stage.v2.{{project}}.{{revision}}.{{pushlog_id}}"
-        - "notify.email.{{owner}}.on-failed"
-        - "notify.email.{{owner}}.on-exception"
+    payload:
+      env:
+        # checkout-gecko uses these to check out the source; the inputs
+        # to `mach taskgraph decision` are all on the command line.
+        GECKO_BASE_REPOSITORY: 'https://hg.mozilla.org/mozilla-unified'
+        GECKO_HEAD_REPOSITORY: '${repoUrl}'
+        GECKO_HEAD_REF: '${push.revision}'
+        GECKO_HEAD_REV: '${push.revision}'
+        GECKO_COMMIT_MSG: '${push.comment}'
+        HG_STORE_PATH: /home/worker/checkouts/hg-store
 
-      payload:
-        env:
-          # checkout-gecko uses these to check out the source; the inputs
-          # to `mach taskgraph decision` are all on the command line.
-          GECKO_BASE_REPOSITORY: 'https://hg.mozilla.org/mozilla-unified'
-          GECKO_HEAD_REPOSITORY: '{{{url}}}'
-          GECKO_HEAD_REF: '{{revision}}'
-          GECKO_HEAD_REV: '{{revision}}'
-          HG_STORE_PATH: /home/worker/checkouts/hg-store
+      cache:
+        level-${repository.level}-checkouts: /home/worker/checkouts
+
+      features:
+        taskclusterProxy: true
+        chainOfTrust: true
 
-        cache:
-          level-{{level}}-checkouts: /home/worker/checkouts
-
-        features:
-          taskclusterProxy: true
-          chainOfTrust: true
+      # Note: This task is built server side without the context or tooling that
+      # exist in tree so we must hard code the hash
+      # XXX Changing this will break Chain of Trust without an associated puppet and
+      # scriptworker patch!
+      image: 'taskcluster/decision:0.1.8@sha256:195d8439c8e90d59311d877bd2a8964849b2e43bfc6c234092618518d8b2891b'
 
-        # Note: This task is built server side without the context or tooling that
-        # exist in tree so we must hard code the hash
-        # XXX Changing this will break Chain of Trust without an associated puppet and
-        # scriptworker patch!
-        image: 'taskcluster/decision:0.1.8@sha256:195d8439c8e90d59311d877bd2a8964849b2e43bfc6c234092618518d8b2891b'
-
-        maxRunTime: 1800
+      maxRunTime: 1800
 
-        # TODO use mozilla-unified for the base repository once the tc-vcs
-        # tar.gz archives are created or tc-vcs isn't being used.
-        command:
-          - /home/worker/bin/run-task
-          - '--vcs-checkout=/home/worker/checkouts/gecko'
-          - '--'
-          - bash
-          - -cx
-          - >
-              cd /home/worker/checkouts/gecko &&
-              ln -s /home/worker/artifacts artifacts &&
-              ./mach --log-no-times taskgraph decision
-              --pushlog-id='{{pushlog_id}}'
-              --pushdate='{{pushdate}}'
-              --project='{{project}}'
-              --message={{#shellquote}}{{{comment}}}{{/shellquote}}
-              --owner='{{owner}}'
-              --level='{{level}}'
-              --base-repository='https://hg.mozilla.org/mozilla-central'
-              --head-repository='{{{url}}}'
-              --head-ref='{{revision}}'
-              --head-rev='{{revision}}'
+      # TODO use mozilla-unified for the base repository once the tc-vcs
+      # tar.gz archives are created or tc-vcs isn't being used.
+      command:
+        - /home/worker/bin/run-task
+        - '--vcs-checkout=/home/worker/checkouts/gecko'
+        - '--'
+        - bash
+        - -cx
+        - $let:
+            extraArgs: {$if: 'tasks_for == "hg-push"', then: '', else: '${cron.quoted_args}'}
+          # NOTE: the explicit reference to mozilla-central below is required because android-stuff
+          # still uses tc-vcs, which does not support mozilla-unified
+          # https://bugzilla.mozilla.org/show_bug.cgi?id=1383973
+          in: >
+            cd /home/worker/checkouts/gecko &&
+            ln -s /home/worker/artifacts artifacts &&
+            ./mach --log-no-times taskgraph decision
+            --pushlog-id='${push.pushlog_id}'
+            --pushdate='${push.pushdate}'
+            --project='${repository.project}'
+            --message="$GECKO_COMMIT_MSG"
+            --owner='${ownerEmail}'
+            --level='${repository.level}'
+            --base-repository='https://hg.mozilla.org/mozilla-central'
+            --head-repository="$GECKO_HEAD_REPOSITORY"
+            --head-ref="$GECKO_HEAD_REF"
+            --head-rev="$GECKO_HEAD_REV"
+            ${extraArgs}
 
-        artifacts:
-          'public':
-            type: 'directory'
-            path: '/home/worker/artifacts'
-            expires: '{{#from_now}}364 days{{/from_now}}'
+      artifacts:
+        'public':
+          type: 'directory'
+          path: '/home/worker/artifacts'
+          expires: {$fromNow: '1 year'}
 
-      extra:
-        treeherder:
+    extra:
+      treeherder:
+        $if: 'tasks_for == "hg-push"'
+        then:
           symbol: D
+        else:
+          groupSymbol: cron
+          symbol: "${cron.job_symbol}"
--- a/browser/app/Makefile.in
+++ b/browser/app/Makefile.in
@@ -84,17 +84,17 @@ MAC_BUNDLE_VERSION = $(shell $(PYTHON) $
 
 .PHONY: repackage
 tools repackage:: $(DIST)/bin/$(MOZ_APP_NAME)
 	rm -rf $(dist_dest)
 	$(MKDIR) -p $(dist_dest)/Contents/MacOS
 	$(MKDIR) -p $(dist_dest)/$(LPROJ)
 	rsync -a --exclude '*.in' $(srcdir)/macbuild/Contents $(dist_dest) --exclude English.lproj
 	rsync -a --exclude '*.in' $(srcdir)/macbuild/Contents/Resources/English.lproj/ $(dist_dest)/$(LPROJ)
-	sed -e 's/%APP_VERSION%/$(MOZ_APP_VERSION)/' -e 's/%MAC_APP_NAME%/$(MAC_APP_NAME)/' -e 's/%MOZ_MACBUNDLE_ID%/$(MOZ_MACBUNDLE_ID)/' -e 's/%MAC_BUNDLE_VERSION%/$(MAC_BUNDLE_VERSION)/' $(srcdir)/macbuild/Contents/Info.plist.in > $(dist_dest)/Contents/Info.plist
+	sed -e 's/%APP_VERSION%/$(MOZ_APP_VERSION)/' -e 's/%MAC_APP_NAME%/$(MAC_APP_NAME)/' -e 's/%MOZ_MACBUNDLE_ID%/$(MOZ_MACBUNDLE_ID)/' -e 's/%MAC_BUNDLE_VERSION%/$(MAC_BUNDLE_VERSION)/' -e 's|%MOZ_DEVELOPER_REPO_PATH%|$(topsrcdir)|' -e 's|%MOZ_DEVELOPER_OBJ_PATH%|$(topobjdir)|' $(srcdir)/macbuild/Contents/Info.plist.in > $(dist_dest)/Contents/Info.plist
 	sed -e 's/%MAC_APP_NAME%/$(MAC_APP_NAME)/' $(srcdir)/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in | iconv -f UTF-8 -t UTF-16 > $(dist_dest)/$(LPROJ)/InfoPlist.strings
 	rsync -a --exclude-from='$(srcdir)/macbuild/Contents/MacOS-files.in' $(DIST)/bin/ $(dist_dest)/Contents/Resources
 	rsync -a --include-from='$(srcdir)/macbuild/Contents/MacOS-files.in' --exclude '*' $(DIST)/bin/ $(dist_dest)/Contents/MacOS
 	$(RM) $(dist_dest)/Contents/MacOS/$(MOZ_APP_NAME)
 	rsync -aL $(DIST)/bin/$(MOZ_APP_NAME) $(dist_dest)/Contents/MacOS
 	cp -RL $(DIST)/branding/firefox.icns $(dist_dest)/Contents/Resources/firefox.icns
 	cp -RL $(DIST)/branding/document.icns $(dist_dest)/Contents/Resources/document.icns
 	$(MKDIR) -p $(dist_dest)/Contents/Library/LaunchServices
--- a/browser/app/macbuild/Contents/Info.plist.in
+++ b/browser/app/macbuild/Contents/Info.plist.in
@@ -215,10 +215,14 @@
   <string>GeckoNSApplication</string>
 	<key>SMPrivilegedExecutables</key>
 	<dict>
 		<key>org.mozilla.updater</key>
 		<string>identifier "org.mozilla.updater" and ((anchor apple generic and certificate leaf[field.1.2.840.113635.100.6.1.9]) or (anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] and certificate leaf[field.1.2.840.113635.100.6.1.13] and certificate leaf[subject.OU] = "43AQ936H96"))</string>
 	</dict>
   <key>NSDisablePersistence</key>
   <true/>
+  <key>MozillaDeveloperRepoPath</key>
+  <string>%MOZ_DEVELOPER_REPO_PATH%</string>
+  <key>MozillaDeveloperObjPath</key>
+  <string>%MOZ_DEVELOPER_OBJ_PATH%</string>
 </dict>
 </plist>
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1131,17 +1131,17 @@ pref("security.sandbox.content.syscall_w
 // when a temporary writable file is required in a level 1 sandbox.
 pref("security.sandbox.content.tempDirSuffix", "");
 #endif
 #endif
 
 #if defined(MOZ_SANDBOX)
 // This pref determines if messages relevant to sandbox violations are
 // logged.
-#if defined(XP_WIN)
+#if defined(XP_WIN) || defined(XP_MACOSX)
 pref("security.sandbox.logging.enabled", false);
 #else
 pref("security.sandbox.logging.enabled", true);
 #endif
 #endif
 
 // This pref governs whether we attempt to work around problems caused by
 // plugins using OS calls to manipulate the cursor while running out-of-
--- a/browser/base/content/browser-places.js
+++ b/browser/base/content/browser-places.js
@@ -71,36 +71,48 @@ var StarUI = {
         elt.removeAttribute("disabled");
       elt.removeAttribute("wasDisabled");
     });
   },
 
   // nsIDOMEventListener
   handleEvent(aEvent) {
     switch (aEvent.type) {
+      case "animationend": {
+        let libraryButton = document.getElementById("library-button");
+        if (aEvent.animationName.startsWith("library-bookmark-animation")) {
+          libraryButton.setAttribute("fade", "true");
+        } else if (aEvent.animationName == "library-bookmark-fade") {
+          libraryButton.removeEventListener("animationend", this);
+          libraryButton.removeAttribute("animate");
+          libraryButton.removeAttribute("fade");
+        }
+        break;
+      }
       case "mousemove":
         clearTimeout(this._autoCloseTimer);
         // The autoclose timer is not disabled on generic mouseout
         // because the user may not have actually interacted with the popup.
         break;
-      case "popuphidden":
+      case "popuphidden": {
         clearTimeout(this._autoCloseTimer);
         if (aEvent.originalTarget == this.panel) {
           if (!this._element("editBookmarkPanelContent").hidden)
             this.quitEditMode();
 
           if (this._anchorToolbarButton) {
             this._anchorToolbarButton.removeAttribute("open");
             this._anchorToolbarButton = null;
           }
           this._restoreCommandsState();
           this._itemId = -1;
           if (this._batching)
             this.endBatch();
 
+          let libraryButton;
           if (this._uriForRemoval) {
             if (this._isNewBookmark) {
               if (!PlacesUIUtils.useAsyncTransactions) {
                 PlacesUtils.transactionManager.undoTransaction();
                 break;
               }
               PlacesTransactions.undo().catch(Cu.reportError);
               break;
@@ -113,19 +125,31 @@ var StarUI = {
                 let txn = new PlacesRemoveItemTransaction(itemId);
                 PlacesUtils.transactionManager.doTransaction(txn);
               }
               break;
             }
 
             PlacesTransactions.RemoveBookmarksForUrls([this._uriForRemoval])
                               .transact().catch(Cu.reportError);
+          } else if (this._isNewBookmark &&
+                     Services.prefs.getBoolPref("toolkit.cosmeticAnimations.enabled") &&
+                     AppConstants.MOZ_PHOTON_ANIMATIONS &&
+                     (libraryButton = document.getElementById("library-button")) &&
+                     libraryButton.getAttribute("cui-areatype") != "menu-panel" &&
+                     libraryButton.getAttribute("overflowedItem") != "true" &&
+                     libraryButton.closest("#nav-bar")) {
+            BrowserUtils.setToolbarButtonHeightProperty(libraryButton);
+            libraryButton.removeAttribute("fade");
+            libraryButton.setAttribute("animate", "bookmark");
+            libraryButton.addEventListener("animationend", this);
           }
         }
         break;
+      }
       case "keypress":
         clearTimeout(this._autoCloseTimer);
         this._autoCloseTimerEnabled = false;
 
         if (aEvent.defaultPrevented) {
           // The event has already been consumed inside of the panel.
           break;
         }
@@ -1681,24 +1705,35 @@ var BookmarkingUI = {
     }
   },
 
   init() {
     CustomizableUI.addListener(this);
     if (!AppConstants.MOZ_PHOTON_THEME) {
       this._updateCustomizationState();
     }
+
+    if (AppConstants.MOZ_PHOTON_ANIMATIONS &&
+        Services.prefs.getBoolPref("toolkit.cosmeticAnimations.enabled")) {
+      let starButtonBox = document.getElementById("star-button-box");
+      starButtonBox.setAttribute("animationsenabled", "true");
+      this.star.addEventListener("mouseover", this, {once: true});
+    }
   },
 
   _hasBookmarksObserver: false,
   _itemGuids: new Set(),
   uninit: function BUI_uninit() {
     this.updateBookmarkPageMenuItem(true);
     CustomizableUI.removeListener(this);
 
+    if (AppConstants.MOZ_PHOTON_ANIMATIONS) {
+      this.star.removeEventListener("mouseover", this);
+    }
+
     this._uninitView();
 
     if (this._hasBookmarksObserver) {
       PlacesUtils.bookmarks.removeObserver(this);
     }
 
     if (this._pendingUpdate) {
       delete this._pendingUpdate;
@@ -1766,16 +1801,17 @@ var BookmarkingUI = {
     if (this._itemGuids.size > 0) {
       this.broadcaster.setAttribute("starred", "true");
       this.broadcaster.setAttribute("buttontooltiptext", this._starredTooltip);
       this.broadcaster.setAttribute("tooltiptext", this._starredTooltip);
       if (!AppConstants.MOZ_PHOTON_THEME && this.button.getAttribute("overflowedItem") == "true") {
         this.button.setAttribute("label", this._starButtonOverflowedStarredLabel);
       }
     } else {
+      this.star.removeAttribute("animate");
       this.broadcaster.removeAttribute("starred");
       this.broadcaster.setAttribute("buttontooltiptext", this._unstarredTooltip);
       this.broadcaster.setAttribute("tooltiptext", this._unstarredTooltip);
       if (!AppConstants.MOZ_PHOTON_THEME && this.button.getAttribute("overflowedItem") == "true") {
         this.button.setAttribute("label", this._starButtonOverflowedLabel);
       }
     }
   },
@@ -1900,26 +1936,36 @@ var BookmarkingUI = {
 
   onStarCommand(aEvent) {
     // Ignore clicks on the star if we are updating its state.
     if (!this._pendingUpdate) {
       let isBookmarked = this._itemGuids.size > 0;
       // Disable the old animation in photon
       if (!isBookmarked && !AppConstants.MOZ_PHOTON_THEME)
         this._showBookmarkedNotification();
+      // Set up variables for new animation in Photon
+      if (!isBookmarked && AppConstants.MOZ_PHOTON_ANIMATIONS) {
+        BrowserUtils.setToolbarButtonHeightProperty(this.star);
+        this.star.setAttribute("animate", "true");
+      }
       PlacesCommandHook.bookmarkCurrentPage(true);
     }
   },
 
   onCurrentPageContextPopupShowing() {
     this.updateBookmarkPageMenuItem();
   },
 
   handleEvent: function BUI_handleEvent(aEvent) {
     switch (aEvent.type) {
+      case "mouseover":
+        if (AppConstants.MOZ_PHOTON_ANIMATIONS) {
+          this.star.setAttribute("preloadanimations", "true");
+        }
+        break;
       case "ViewShowing":
         this.onPanelMenuViewShowing(aEvent);
         break;
       case "ViewHiding":
         this.onPanelMenuViewHiding(aEvent);
         break;
     }
   },
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -586,16 +586,22 @@ html|input.urlbar-input[textoverflow]:no
 
 /* For non-action items, hide the action text; for action items, hide the URL
    text. */
 .ac-url[actiontype],
 .ac-action:not([actiontype]) {
   display: none;
 }
 
+/* Never show a scrollbar for the Location Bar popup.  This overrides the
+   richlistbox inline overflow: auto style.*/
+#PopupAutoCompleteRichResult > richlistbox > scrollbox {
+  overflow: hidden !important;
+}
+
 /* For action items in a noactions popup, show the URL text and hide the action
    text and type icon. */
 #PopupAutoCompleteRichResult[noactions] > richlistbox > richlistitem.overridable-action > .ac-url {
   display: -moz-box;
 }
 #PopupAutoCompleteRichResult[noactions] > richlistbox > richlistitem.overridable-action > .ac-action {
   display: none;
 }
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -803,17 +803,16 @@
                      autocompletesearchparam="enable-actions"
                      autocompletepopup="PopupAutoCompleteRichResult"
                      completeselectedindex="true"
                      shrinkdelay="250"
                      tabscrolling="true"
                      showcommentcolumn="true"
                      showimagecolumn="true"
                      enablehistory="true"
-                     maxrows="10"
                      newlines="stripsurroundingwhitespace"
                      ontextentered="this.handleCommand(param);"
                      ontextreverted="return this.handleRevert();"
                      pageproxystate="invalid">
               <!-- Use onclick instead of normal popup= syntax since the popup
                    code fires onmousedown, and hence eats our favicon drag events. -->
               <box id="identity-box" role="button"
                    align="center"
@@ -900,22 +899,28 @@
                        hidden="true"
                        tooltiptext="&pageReportIcon.tooltip;"
                        onmousedown="gPopupBlockerObserver.onReportButtonMousedown(event);"/>
                 <image id="reader-mode-button"
                        class="urlbar-icon"
                        hidden="true"
                        onclick="ReaderParent.buttonClick(event);"/>
 #ifdef MOZ_PHOTON_THEME
-                <image id="star-button"
-                       class="urlbar-icon"
-                       onclick="BookmarkingUI.onStarCommand(event);">
-                  <observes element="bookmarkThisPageBroadcaster" attribute="starred"/>
-                  <observes element="bookmarkThisPageBroadcaster" attribute="tooltiptext"/>
-                </image>
+                <hbox id="star-button-box">
+                  <image id="star-button"
+                         class="urlbar-icon"
+                         onclick="BookmarkingUI.onStarCommand(event);">
+                    <observes element="bookmarkThisPageBroadcaster" attribute="starred"/>
+                    <observes element="bookmarkThisPageBroadcaster" attribute="tooltiptext"/>
+                  </image>
+                  <hbox id="star-button-animatable-box">
+                    <image id="star-button-animatable-image"
+                           onclick="BookmarkingUI.onStarCommand(event);"/>
+                  </hbox>
+                </hbox>
 #endif
                 <toolbarbutton id="urlbar-zoom-button"
                        onclick="FullZoom.reset();"
                        tooltip="dynamic-shortcut-tooltip"
                        hidden="true"/>
               </hbox>
               <hbox id="userContext-icons" hidden="true">
                 <label id="userContext-label"/>
--- a/browser/base/content/test/performance/browser_startup_images.js
+++ b/browser/base/content/test/performance/browser_startup_images.js
@@ -30,21 +30,16 @@ const whitelist = [
     platforms: ["linux", "win", "macosx"],
     photon: true,
   },
   {
     file: "chrome://browser/skin/toolbarbutton-dropdown-arrow.png",
     platforms: ["win"],
     photon: true,
   },
-  {
-    file: "chrome://browser/skin/bookmark-hollow.svg",
-    platforms: ["linux", "win", "macosx"],
-    photon: true,
-  },
 
   // Non-Photon-only entries
   {
     file: "chrome://browser/skin/toolbarbutton-dropdown-arrow.png",
     platforms: ["linux", "win", "macosx"],
     photon: false,
   },
 
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -176,16 +176,22 @@ file, You can obtain one at http://mozil
 
       <!--
         For performance reasons we want to limit the size of the text runs we
         build and show to the user.
       -->
       <field name="textRunsMaxLen">255</field>
 
       <!--
+        Since we never want scrollbars, we always use the maxResults value.
+      -->
+      <property name="maxRows"
+                onget="return this.popup.maxResults;"/>
+
+      <!--
         onBeforeValueGet is called by the base-binding's .value getter.
         It can return an object with a "value" property, to override the
         return value of the getter.
       -->
       <method name="onBeforeValueGet">
         <body><![CDATA[
           return { value: this._value };
         ]]></body>
@@ -1086,16 +1092,18 @@ file, You can obtain one at http://mozil
                 delete this._whichSearchSuggestionsNotification;
                 break;
               case "trimURLs":
                 this._mayTrimURLs = this._prefs.getBoolPref(aData);
                 break;
               case "oneOffSearches":
                 this._enableOrDisableOneOffSearches();
                 break;
+              case "maxRichResults":
+                this.popup.maxResults = this._prefs.getIntPref(aData);
             }
           }
         ]]></body>
       </method>
 
       <method name="_enableOrDisableOneOffSearches">
         <body><![CDATA[
           let enable = this._prefs.getBoolPref("oneOffSearches");
@@ -1785,20 +1793,17 @@ file, You can obtain one at http://mozil
           ]]>
         </getter>
       </property>
 
       <property name="maxResults">
         <getter>
           <![CDATA[
             if (!this._maxResults) {
-              var prefService =
-                Components.classes["@mozilla.org/preferences-service;1"]
-                          .getService(Components.interfaces.nsIPrefBranch);
-              this._maxResults = prefService.getIntPref("browser.urlbar.maxRichResults");
+              this._maxResults = Services.prefs.getIntPref("browser.urlbar.maxRichResults");
             }
             return this._maxResults;
           ]]>
         </getter>
         <setter>
           <![CDATA[
             return this._maxResults = parseInt(val);
           ]]>
--- a/browser/components/extensions/ext-browserAction.js
+++ b/browser/components/extensions/ext-browserAction.js
@@ -176,16 +176,22 @@ this.browserAction = class extends Exten
         let popupURL = this.getProperty(tab, "popup");
         this.tabManager.addActiveTabPermission(tab);
 
         // Popups are shown only if a popup URL is defined; otherwise
         // a "click" event is dispatched. This is done for compatibility with the
         // Google Chrome onClicked extension API.
         if (popupURL) {
           try {
+            if (event.target.closest("panelmultiview")) {
+              // FIXME: The line below needs to change eventually, but for now:
+              // ensure the view is _always_ visible _before_ `popup.attach()` is
+              // called. PanelMultiView.jsm dictates different behavior.
+              event.target.setAttribute("current", true);
+            }
             let popup = this.getPopup(document.defaultView, popupURL);
             let attachPromise = popup.attach(event.target);
             event.detail.addBlocker(attachPromise);
             await attachPromise;
             TelemetryStopwatch.finish(POPUP_OPEN_MS_HISTOGRAM, this);
             if (this.eventQueue.length) {
               let histogram = Services.telemetry.getHistogramById(POPUP_RESULT_HISTOGRAM);
               histogram.add("popupShown");
--- a/browser/components/preferences/in-content-new/findInPage.js
+++ b/browser/components/preferences/in-content-new/findInPage.js
@@ -2,26 +2,24 @@
  * 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/. */
 
 /* import-globals-from preferences.js */
 
 var gSearchResultsPane = {
   listSearchTooltips: new Set(),
   listSearchMenuitemIndicators: new Set(),
-  searchResultsCategory: null,
   searchInput: null,
   inited: false,
 
   init() {
     if (this.inited) {
       return;
     }
     this.inited = true;
-    this.searchResultsCategory = document.getElementById("category-search-results");
     this.searchInput = document.getElementById("searchInput");
     this.searchInput.hidden = !Services.prefs.getBoolPref("browser.preferences.search");
     if (!this.searchInput.hidden) {
       this.searchInput.addEventListener("command", this);
       window.addEventListener("load", () => {
         this.searchInput.focus();
         this.initializeCategories();
       });
@@ -228,18 +226,16 @@ var gSearchResultsPane = {
     this.removeAllSearchMenuitemIndicators();
 
     let srHeader = document.getElementById("header-searchResults");
 
     if (this.query) {
       // Showing the Search Results Tag
       gotoPref("paneSearchResults");
 
-      this.searchResultsCategory.hidden = false;
-
       let resultsFound = false;
 
       // Building the range for highlighted areas
       let rootPreferencesChildren = document
         .querySelectorAll("#mainPrefPane > *:not([data-hidden-from-search])");
 
       // Showing all the children to bind JS, Access Keys, etc
       for (let i = 0; i < rootPreferencesChildren.length; i++) {
@@ -274,17 +270,16 @@ var gSearchResultsPane = {
         // eslint-disable-next-line no-unsanitized/property
         document.getElementById("need-help").innerHTML =
           strings.getFormattedString("searchResults.needHelp2", [helpUrl, brandName]);
       } else {
         // Creating tooltips for all the instances found
         this.listSearchTooltips.forEach((anchorNode) => this.createSearchTooltip(anchorNode, this.query));
       }
     } else {
-      this.searchResultsCategory.hidden = true;
       document.getElementById("sorry-message").textContent = "";
       // Going back to General when cleared
       gotoPref("paneGeneral");
     }
   },
 
   /**
    * Finding leaf nodes and checking their content for words to search,
--- a/browser/components/preferences/in-content-new/main.js
+++ b/browser/components/preferences/in-content-new/main.js
@@ -1113,36 +1113,49 @@ var gMainPane = {
       defaultPerformancePref.value = false;
     }
   },
 
   updatePerformanceSettingsBox() {
     let defaultPerformancePref =
       document.getElementById("browser.preferences.defaultPerformanceSettings.enabled");
     let performanceSettings = document.getElementById("performanceSettings");
+    let processCountPref = document.getElementById("dom.ipc.processCount");
     if (defaultPerformancePref.value) {
-      let processCountPref = document.getElementById("dom.ipc.processCount");
       let accelerationPref = document.getElementById("layers.acceleration.disabled");
+      // Unset the value so process count will be decided by e10s rollout.
       processCountPref.value = processCountPref.defaultValue;
       accelerationPref.value = accelerationPref.defaultValue;
       performanceSettings.hidden = true;
     } else {
+      let e10sRolloutProcessCountPref =
+        document.getElementById("dom.ipc.processCount.web");
+      // Take the e10s rollout value as the default value (if it exists),
+      // but don't overwrite the user set value.
+      if (e10sRolloutProcessCountPref.value &&
+          processCountPref.value == processCountPref.defaultValue) {
+        processCountPref.value = e10sRolloutProcessCountPref.value;
+      }
       performanceSettings.hidden = false;
     }
   },
 
   buildContentProcessCountMenuList() {
     if (gMainPane.isE10SEnabled()) {
       let processCountPref = document.getElementById("dom.ipc.processCount");
+      let e10sRolloutProcessCountPref =
+        document.getElementById("dom.ipc.processCount.web");
+      let defaultProcessCount =
+        e10sRolloutProcessCountPref.value || processCountPref.defaultValue;
       let bundlePreferences = document.getElementById("bundlePreferences");
       let label = bundlePreferences.getFormattedString("defaultContentProcessCount",
-        [processCountPref.defaultValue]);
+        [defaultProcessCount]);
       let contentProcessCount =
         document.querySelector(`#contentProcessCount > menupopup >
-                                menuitem[value="${processCountPref.defaultValue}"]`);
+                                menuitem[value="${defaultProcessCount}"]`);
       contentProcessCount.label = label;
 
       document.getElementById("limitContentProcess").disabled = false;
       document.getElementById("contentProcessCount").disabled = false;
       document.getElementById("contentProcessCountEnabledDescription").hidden = false;
       document.getElementById("contentProcessCountDisabledDescription").hidden = true;
     } else {
       document.getElementById("limitContentProcess").disabled = true;
--- a/browser/components/preferences/in-content-new/main.xul
+++ b/browser/components/preferences/in-content-new/main.xul
@@ -179,16 +179,20 @@
   <preference id="browser.preferences.defaultPerformanceSettings.enabled"
               name="browser.preferences.defaultPerformanceSettings.enabled"
               type="bool"/>
 
   <preference id="dom.ipc.processCount"
               name="dom.ipc.processCount"
               type="int"/>
 
+  <preference id="dom.ipc.processCount.web"
+              name="dom.ipc.processCount.web"
+              type="int"/>
+
   <preference id="layers.acceleration.disabled"
               name="layers.acceleration.disabled"
               type="bool"
               inverted="true"/>
 
   <!-- Files and Applications -->
   <preference id="browser.feeds.handler"
               name="browser.feeds.handler"
--- a/browser/components/preferences/in-content-new/preferences.js
+++ b/browser/components/preferences/in-content-new/preferences.js
@@ -157,53 +157,60 @@ function gotoPref(aCategory) {
   // until proper search support is enabled (bug 1353954).
   let subcategory = breakIndex != -1 && category.substring(breakIndex + 1);
   if (subcategory) {
     category = category.substring(0, breakIndex);
   }
   category = friendlyPrefCategoryNameToInternalName(category);
   if (category != "paneSearchResults") {
     gSearchResultsPane.searchInput.value = "";
-    gSearchResultsPane.searchResultsCategory.hidden = true;
     gSearchResultsPane.getFindSelection(window).removeAllRanges();
     gSearchResultsPane.removeAllSearchTooltips();
     gSearchResultsPane.removeAllSearchMenuitemIndicators();
   } else if (!gSearchResultsPane.searchInput.value) {
     // Something tried to send us to the search results pane without
     // a query string. Default to the General pane instead.
     category = kDefaultCategoryInternalName;
     document.location.hash = kDefaultCategory;
     gSearchResultsPane.query = null;
   }
 
   // Updating the hash (below) or changing the selected category
   // will re-enter gotoPref.
   if (gLastHash == category && !subcategory)
     return;
-  let item = categories.querySelector(".category[value=" + category + "]");
-  if (!item) {
-    category = kDefaultCategoryInternalName;
+
+  let item;
+  if (category != "paneSearchResults") {
     item = categories.querySelector(".category[value=" + category + "]");
+    if (!item) {
+      category = kDefaultCategoryInternalName;
+      item = categories.querySelector(".category[value=" + category + "]");
+    }
   }
 
   try {
     init_category_if_required(category);
   } catch (ex) {
     Cu.reportError("Error initializing preference category " + category + ": " + ex);
     throw ex;
   }
 
   let friendlyName = internalPrefCategoryNameToFriendlyName(category);
   if (gLastHash || category != kDefaultCategoryInternalName || subcategory) {
     document.location.hash = friendlyName;
   }
   // Need to set the gLastHash before setting categories.selectedItem since
   // the categories 'select' event will re-enter the gotoPref codepath.
   gLastHash = category;
-  categories.selectedItem = item;
+  if (item) {
+    categories.selectedItem = item;
+  } else {
+    categories.clearSelection();
+  }
   window.history.replaceState(category, document.title);
   search(category, "data-category", subcategory, "data-subcategory");
 
   let mainContent = document.querySelector(".main-content");
   mainContent.scrollTop = 0;
 
   Services.telemetry
           .getHistogramById("FX_PREFERENCES_CATEGORY_OPENED_V2")
--- a/browser/components/preferences/in-content-new/preferences.xul
+++ b/browser/components/preferences/in-content-new/preferences.xul
@@ -118,27 +118,16 @@
                   src="chrome://browser/locale/preferences/applicationManager.properties"/>
   </stringbundleset>
 
   <stack flex="1">
   <hbox flex="1">
 
     <!-- category list -->
     <richlistbox id="categories">
-      <richlistitem id="category-search-results"
-                    class="category"
-                    value="paneSearchResults"
-                    helpTopic="prefs-main"
-                    tooltiptext="&paneSearchResults.title;"
-                    align="center"
-                    hidden="true">
-        <image class="category-icon"/>
-        <label class="category-name" flex="1">&paneSearchResults.title;</label>
-      </richlistitem>
-
       <richlistitem id="category-general"
                     class="category"
                     value="paneGeneral"
                     helpTopic="prefs-main"
                     tooltiptext="&paneGeneral.title;"
                     align="center">
         <image class="category-icon"/>
         <label class="category-name" flex="1">&paneGeneral.title;</label>
--- a/browser/components/preferences/in-content-new/tests/browser_search_within_preferences_1.js
+++ b/browser/components/preferences/in-content-new/tests/browser_search_within_preferences_1.js
@@ -51,21 +51,17 @@ add_task(async function() {
 
   searchInput.value = "password";
   searchInput.doCommand();
 
   let categoriesList = gBrowser.contentDocument.getElementById("categories");
 
   for (let i = 0; i < categoriesList.childElementCount; i++) {
     let child = categoriesList.children[i]
-    if (child.id == "category-search-results") {
-      is(child.selected, true, "Search results panel should be selected");
-    } else if (child.id) {
-      is(child.selected, false, "No other panel should be selected");
-    }
+    is(child.selected, false, "No other panel should be selected");
   }
   // Takes search off
   searchInput.value = "";
   searchInput.doCommand();
 
   // Checks if back to generalPane
   for (let i = 0; i < categoriesList.childElementCount; i++) {
     let child = categoriesList.children[i]
@@ -237,29 +233,25 @@ add_task(async function() {
 });
 
 /**
  * Test for if we go to another tab after searching
  */
 add_task(async function() {
   await openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
   let searchInput = gBrowser.contentDocument.getElementById("searchInput");
-  let searchResultsCategory = gBrowser.contentDocument.getElementById("category-search-results");
 
   is(searchInput, gBrowser.contentDocument.activeElement.closest("#searchInput"),
     "Search input should be focused when visiting preferences");
 
   searchInput.value = "password";
   searchInput.doCommand();
-  is(searchResultsCategory.hidden, false, "search results category should be shown");
-  is(searchResultsCategory.selected, true, "search results category should be selected");
 
   let privacyCategory = gBrowser.contentDocument.getElementById("category-privacy");
   privacyCategory.click();
-  is(searchResultsCategory.hidden, true, "search results category should not be shown");
   is(searchInput.value, "", "search input should be empty");
   let categoriesList = gBrowser.contentDocument.getElementById("categories");
   for (let i = 0; i < categoriesList.childElementCount; i++) {
     let child = categoriesList.children[i]
     if (child.id == "category-privacy") {
       is(child.selected, true, "Privacy panel should be selected");
     } else if (child.id) {
       is(child.selected, false, "No other panel should be selected");
--- a/browser/components/preferences/in-content/main.js
+++ b/browser/components/preferences/in-content/main.js
@@ -424,36 +424,49 @@ var gMainPane = {
       defaultPerformancePref.value = false;
     }
   },
 
   updatePerformanceSettingsBox() {
     let defaultPerformancePref =
       document.getElementById("browser.preferences.defaultPerformanceSettings.enabled");
     let performanceSettings = document.getElementById("performanceSettings");
+    let processCountPref = document.getElementById("dom.ipc.processCount");
     if (defaultPerformancePref.value) {
-      let processCountPref = document.getElementById("dom.ipc.processCount");
       let accelerationPref = document.getElementById("layers.acceleration.disabled");
+      // Unset the value so process count will be decided by e10s rollout.
       processCountPref.value = processCountPref.defaultValue;
       accelerationPref.value = accelerationPref.defaultValue;
       performanceSettings.hidden = true;
     } else {
+      let e10sRolloutProcessCountPref =
+        document.getElementById("dom.ipc.processCount.web");
+      // Take the e10s rollout value as the default value (if it exists),
+      // but don't overwrite the user set value.
+      if (e10sRolloutProcessCountPref.value &&
+          processCountPref.value == processCountPref.defaultValue) {
+        processCountPref.value = e10sRolloutProcessCountPref.value;
+      }
       performanceSettings.hidden = false;
     }
   },
 
   buildContentProcessCountMenuList() {
     if (gMainPane.isE10SEnabled()) {
       let processCountPref = document.getElementById("dom.ipc.processCount");
+      let e10sRolloutProcessCountPref =
+        document.getElementById("dom.ipc.processCount.web");
+      let defaultProcessCount =
+        e10sRolloutProcessCountPref.value || processCountPref.defaultValue;
       let bundlePreferences = document.getElementById("bundlePreferences");
       let label = bundlePreferences.getFormattedString("defaultContentProcessCount",
-        [processCountPref.defaultValue]);
+        [defaultProcessCount]);
       let contentProcessCount =
         document.querySelector(`#contentProcessCount > menupopup >
-                                menuitem[value="${processCountPref.defaultValue}"]`);
+                                menuitem[value="${defaultProcessCount}"]`);
       contentProcessCount.label = label;
 
       document.getElementById("limitContentProcess").disabled = false;
       document.getElementById("contentProcessCount").disabled = false;
       document.getElementById("contentProcessCountEnabledDescription").hidden = false;
       document.getElementById("contentProcessCountDisabledDescription").hidden = true;
     } else {
       document.getElementById("limitContentProcess").disabled = true;
--- a/browser/components/preferences/in-content/main.xul
+++ b/browser/components/preferences/in-content/main.xul
@@ -114,16 +114,20 @@
   <preference id="browser.preferences.defaultPerformanceSettings.enabled"
               name="browser.preferences.defaultPerformanceSettings.enabled"
               type="bool"/>
 
   <preference id="dom.ipc.processCount"
               name="dom.ipc.processCount"
               type="int"/>
 
+  <preference id="dom.ipc.processCount.web"
+              name="dom.ipc.processCount.web"
+              type="int"/>
+
   <preference id="layers.acceleration.disabled"
               name="layers.acceleration.disabled"
               type="bool"
               inverted="true"/>
 </preferences>
 
 <hbox id="header-general"
       class="header"
--- a/browser/extensions/activity-stream/common/Actions.jsm
+++ b/browser/extensions/activity-stream/common/Actions.jsm
@@ -29,16 +29,18 @@ for (const type of [
   "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",
--- a/browser/extensions/activity-stream/common/Reducers.jsm
+++ b/browser/extensions/activity-stream/common/Reducers.jsm
@@ -197,16 +197,47 @@ function Sections(prevState = INITIAL_ST
       return newState;
     case at.SECTION_ROWS_UPDATE:
       return prevState.map(section => {
         if (section && section.id === action.data.id) {
           return Object.assign({}, section, action.data);
         }
         return section;
       });
+    case at.PLACES_BOOKMARK_ADDED:
+      if (!action.data) {
+        return prevState;
+      }
+      return prevState.map(section => Object.assign({}, section, {
+        rows: section.rows.map(item => {
+          // find the item within the rows that is attempted to be bookmarked
+          if (item.url === action.data.url) {
+            const {bookmarkGuid, bookmarkTitle, lastModified} = action.data;
+            Object.assign(item, {bookmarkGuid, bookmarkTitle, bookmarkDateCreated: lastModified});
+          }
+          return item;
+        })
+      }));
+    case at.PLACES_BOOKMARK_REMOVED:
+      if (!action.data) {
+        return prevState;
+      }
+      return prevState.map(section => Object.assign({}, section, {
+        rows: section.rows.map(item => {
+          // find the bookmark within the rows that is attempted to be removed
+          if (item.url === action.data.url) {
+            const newSite = Object.assign({}, item);
+            delete newSite.bookmarkGuid;
+            delete newSite.bookmarkTitle;
+            delete newSite.bookmarkDateCreated;
+            return newSite;
+          }
+          return item;
+        })
+      }));
     case at.PLACES_LINK_DELETED:
     case at.PLACES_LINK_BLOCKED:
       return prevState.map(section =>
         Object.assign({}, section, {rows: section.rows.filter(site => site.url !== action.data.url)}));
     default:
       return prevState;
   }
 }
--- a/browser/extensions/activity-stream/data/content/activity-stream.bundle.js
+++ b/browser/extensions/activity-stream/data/content/activity-stream.bundle.js
@@ -1,74 +1,74 @@
 /******/ (function(modules) { // webpackBootstrap
 /******/ 	// The module cache
 /******/ 	var installedModules = {};
-
+/******/
 /******/ 	// The require function
 /******/ 	function __webpack_require__(moduleId) {
-
+/******/
 /******/ 		// Check if module is in cache
 /******/ 		if(installedModules[moduleId])
 /******/ 			return installedModules[moduleId].exports;
-
+/******/
 /******/ 		// Create a new module (and put it into the cache)
 /******/ 		var module = installedModules[moduleId] = {
 /******/ 			i: moduleId,
 /******/ 			l: false,
 /******/ 			exports: {}
 /******/ 		};
-
+/******/
 /******/ 		// Execute the module function
 /******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
-
+/******/
 /******/ 		// Flag the module as loaded
 /******/ 		module.l = true;
-
+/******/
 /******/ 		// Return the exports of the module
 /******/ 		return module.exports;
 /******/ 	}
-
-
+/******/
+/******/
 /******/ 	// expose the modules object (__webpack_modules__)
 /******/ 	__webpack_require__.m = modules;
-
+/******/
 /******/ 	// expose the module cache
 /******/ 	__webpack_require__.c = installedModules;
-
+/******/
 /******/ 	// identity function for calling harmony imports with the correct context
 /******/ 	__webpack_require__.i = function(value) { return value; };
-
+/******/
 /******/ 	// define getter function for harmony exports
 /******/ 	__webpack_require__.d = function(exports, name, getter) {
 /******/ 		if(!__webpack_require__.o(exports, name)) {
 /******/ 			Object.defineProperty(exports, name, {
 /******/ 				configurable: false,
 /******/ 				enumerable: true,
 /******/ 				get: getter
 /******/ 			});
 /******/ 		}
 /******/ 	};
-
+/******/
 /******/ 	// getDefaultExport function for compatibility with non-harmony modules
 /******/ 	__webpack_require__.n = function(module) {
 /******/ 		var getter = module && module.__esModule ?
 /******/ 			function getDefault() { return module['default']; } :
 /******/ 			function getModuleExports() { return module; };
 /******/ 		__webpack_require__.d(getter, 'a', getter);
 /******/ 		return getter;
 /******/ 	};
-
+/******/
 /******/ 	// Object.prototype.hasOwnProperty.call
 /******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
-
+/******/
 /******/ 	// __webpack_public_path__
 /******/ 	__webpack_require__.p = "";
-
+/******/
 /******/ 	// Load entry module and return exports
-/******/ 	return __webpack_require__(__webpack_require__.s = 25);
+/******/ 	return __webpack_require__(__webpack_require__.s = 26);
 /******/ })
 /************************************************************************/
 /******/ ([
 /* 0 */
 /***/ (function(module, exports) {
 
 module.exports = React;
 
@@ -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", "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_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"]) {
   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) {
@@ -307,31 +307,32 @@ module.exports = ReactRedux;
  * @param  {obj} link A link object
  *         {str} link.url (required)- The url of the link
  *         {str} link.eTLD (required) - The tld of the link
  *               e.g. for https://foo.org, the tld would be "org"
  *               Note that this property is added in various queries for ActivityStream
  *               via Services.eTLD.getPublicSuffix
  *         {str} link.hostname (optional) - The hostname of the url
  *               e.g. for http://www.hello.com/foo/bar, the hostname would be "www.hello.com"
+ *         {str} link.title (optional) - The title of the link
  * @return {str}   A short url
  */
 module.exports = function shortURL(link) {
   if (!link.url && !link.hostname) {
     return "";
   }
   const eTLD = link.eTLD;
 
   const hostname = (link.hostname || new URL(link.url).hostname).replace(/^www\./i, "");
 
   // Remove the eTLD (e.g., com, net) and the preceding period from the hostname
   const eTLDLength = (eTLD || "").length || hostname.match(/\.com$/) && 3;
   const eTLDExtra = eTLDLength > 0 ? -(eTLDLength + 1) : Infinity;
   // If URL and hostname are not present fallback to page title.
-  return hostname.slice(0, eTLDExtra).toLowerCase() || hostname || link.title;
+  return hostname.slice(0, eTLDExtra).toLowerCase() || hostname || link.title || link.url;
 };
 
 /***/ }),
 /* 5 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
@@ -343,17 +344,17 @@ var _require = __webpack_require__(2);
 const injectIntl = _require.injectIntl;
 
 const ContextMenu = __webpack_require__(15);
 
 var _require2 = __webpack_require__(1);
 
 const ac = _require2.actionCreators;
 
-const linkMenuOptions = __webpack_require__(21);
+const linkMenuOptions = __webpack_require__(22);
 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;
@@ -415,21 +416,22 @@ 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__(19);
-const Search = __webpack_require__(17);
+const TopSites = __webpack_require__(20);
+const Search = __webpack_require__(18);
 const ConfirmDialog = __webpack_require__(14);
-const PreferencesPane = __webpack_require__(16);
-const Sections = __webpack_require__(18);
+const ManualMigration = __webpack_require__(16);
+const PreferencesPane = __webpack_require__(17);
+const Sections = __webpack_require__(19);
 
 // 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) {
@@ -463,31 +465,31 @@ class Base extends React.Component {
   render() {
     const props = this.props;
     var _props$App = props.App;
     const locale = _props$App.locale,
           strings = _props$App.strings,
           initialized = _props$App.initialized;
 
     const prefs = props.Prefs.values;
-
     if (!initialized) {
       return null;
     }
 
     return React.createElement(
       IntlProvider,
       { key: locale, locale: locale, messages: strings },
       React.createElement(
         "div",
         { className: "outer-wrapper" },
         React.createElement(
           "main",
           null,
           prefs.showSearch && React.createElement(Search, null),
+          !prefs.migrationExpired && React.createElement(ManualMigration, null),
           prefs.showTopSites && React.createElement(TopSites, null),
           React.createElement(Sections, null),
           React.createElement(ConfirmDialog, null)
         ),
         React.createElement(PreferencesPane, null)
       )
     );
   }
@@ -501,17 +503,17 @@ module.exports = connect(state => ({ App
 
 "use strict";
 
 
 var _require = __webpack_require__(1);
 
 const at = _require.actionTypes;
 
-var _require2 = __webpack_require__(22);
+var _require2 = __webpack_require__(23);
 
 const perfSvc = _require2.perfService;
 
 
 const VISIBLE = "visible";
 const VISIBILITY_CHANGE_EVENT = "visibilitychange";
 
 module.exports = class DetectUserSessionStart {
@@ -574,17 +576,17 @@ module.exports = class DetectUserSession
 /* 8 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 /* eslint-env mozilla/frame-script */
 
-var _require = __webpack_require__(24);
+var _require = __webpack_require__(25);
 
 const createStore = _require.createStore,
       combineReducers = _require.combineReducers,
       applyMiddleware = _require.applyMiddleware;
 
 var _require2 = __webpack_require__(1);
 
 const au = _require2.actionUtils;
@@ -639,17 +641,17 @@ const messageMiddleware = store => next 
 module.exports = function initStore(reducers) {
   const store = createStore(mergeStateReducer(combineReducers(reducers)), applyMiddleware(messageMiddleware));
 
   addMessageListener(INCOMING_MESSAGE_NAME, msg => {
     try {
       store.dispatch(msg.data);
     } catch (ex) {
       console.error("Content msg:", msg, "Dispatch error: ", ex); // eslint-disable-line no-console
-      dump(`Content msg: ${ JSON.stringify(msg) }\nDispatch error: ${ ex }\n${ ex.stack }`);
+      dump(`Content msg: ${JSON.stringify(msg)}\nDispatch error: ${ex}\n${ex.stack}`);
     }
   });
 
   return store;
 };
 
 module.exports.MERGE_STORE_ACTION = MERGE_STORE_ACTION;
 module.exports.OUTGOING_MESSAGE_NAME = OUTGOING_MESSAGE_NAME;
@@ -848,17 +850,17 @@ class SnippetsProvider {
   }
 
   _showRemoteSnippets() {
     const snippetsEl = document.getElementById(this.elementId);
     const containerEl = document.getElementById(this.containerElementId);
     const payload = this.snippetsMap.get("snippets");
 
     if (!snippetsEl) {
-      throw new Error(`No element was found with id '${ this.elementId }'.`);
+      throw new Error(`No element was found with id '${this.elementId}'.`);
     }
 
     // This could happen if fetching failed
     if (!payload) {
       throw new Error("No remote snippets were found in gSnippetsMap.");
     }
 
     // Note that injecting snippets can throw if they're invalid XML.
@@ -915,17 +917,17 @@ class SnippetsProvider {
       this._showDefaultSnippets(e);
     }
   }
 }
 
 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__(23)))
+/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(24)))
 
 /***/ }),
 /* 10 */
 /***/ (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
@@ -1154,16 +1156,51 @@ function Sections() {
       return newState;
     case at.SECTION_ROWS_UPDATE:
       return prevState.map(section => {
         if (section && section.id === action.data.id) {
           return Object.assign({}, section, action.data);
         }
         return section;
       });
+    case at.PLACES_BOOKMARK_ADDED:
+      if (!action.data) {
+        return prevState;
+      }
+      return prevState.map(section => Object.assign({}, section, {
+        rows: section.rows.map(item => {
+          // find the item within the rows that is attempted to be bookmarked
+          if (item.url === action.data.url) {
+            var _action$data3 = action.data;
+            const bookmarkGuid = _action$data3.bookmarkGuid,
+                  bookmarkTitle = _action$data3.bookmarkTitle,
+                  lastModified = _action$data3.lastModified;
+
+            Object.assign(item, { bookmarkGuid, bookmarkTitle, bookmarkDateCreated: lastModified });
+          }
+          return item;
+        })
+      }));
+    case at.PLACES_BOOKMARK_REMOVED:
+      if (!action.data) {
+        return prevState;
+      }
+      return prevState.map(section => Object.assign({}, section, {
+        rows: section.rows.map(item => {
+          // find the bookmark within the rows that is attempted to be removed
+          if (item.url === action.data.url) {
+            const newSite = Object.assign({}, item);
+            delete newSite.bookmarkGuid;
+            delete newSite.bookmarkTitle;
+            delete newSite.bookmarkDateCreated;
+            return newSite;
+          }
+          return item;
+        })
+      }));
     case at.PLACES_LINK_DELETED:
     case at.PLACES_LINK_BLOCKED:
       return prevState.map(section => Object.assign({}, section, { rows: section.rows.filter(site => site.url !== action.data.url) }));
     default:
       return prevState;
   }
 }
 
@@ -1219,19 +1256,28 @@ const cardContextTypes = __webpack_requi
  * 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);
   }
-  toggleContextMenu(event, index) {
-    this.setState({ showContextMenu: true, activeCard: index });
+  onMenuButtonClick(event) {
+    event.preventDefault();
+    this.setState({
+      activeCard: this.props.index,
+      showContextMenu: true
+    });
+  }
+  onMenuUpdate(showContextMenu) {
+    this.setState({ showContextMenu });
   }
   render() {
     var _props = this.props;
     const index = _props.index,
           link = _props.link,
           dispatch = _props.dispatch,
           contextMenuOptions = _props.contextMenuOptions;
 
@@ -1239,85 +1285,82 @@ class Card extends React.Component {
     const hostname = shortURL(link);
     var _cardContextTypes$lin = cardContextTypes[link.type];
     const icon = _cardContextTypes$lin.icon,
           intlID = _cardContextTypes$lin.intlID;
 
 
     return React.createElement(
       "li",
-      { className: `card-outer${ isContextMenuOpen ? " active" : "" }` },
+      { className: `card-outer${isContextMenuOpen ? " active" : ""}` },
       React.createElement(
         "a",
         { href: link.url },
         React.createElement(
           "div",
           { className: "card" },
-          link.image && React.createElement("div", { className: "card-preview-image", style: { backgroundImage: `url(${ link.image })` } }),
+          link.image && React.createElement("div", { className: "card-preview-image", style: { backgroundImage: `url(${link.image})` } }),
           React.createElement(
             "div",
             { className: "card-details" },
             React.createElement(
               "div",
               { className: "card-host-name" },
               " ",
               hostname,
               " "
             ),
             React.createElement(
               "div",
-              { className: `card-text${ link.image ? "" : " full-height" }` },
+              { className: `card-text${link.image ? "" : " full-height"}` },
               React.createElement(
                 "h4",
-                { className: "card-title" },
+                { className: "card-title", dir: "auto" },
                 " ",
                 link.title,
                 " "
               ),
               React.createElement(
                 "p",
-                { className: "card-description" },
+                { className: "card-description", dir: "auto" },
                 " ",
                 link.description,
                 " "
               )
             ),
             React.createElement(
               "div",
               { className: "card-context" },
-              React.createElement("span", { className: `card-context-icon icon icon-${ icon }` }),
+              React.createElement("span", { className: `card-context-icon icon icon-${icon}` }),
               React.createElement(
                 "div",
                 { className: "card-context-label" },
                 React.createElement(FormattedMessage, { id: intlID, defaultMessage: "Visited" })
               )
             )
           )
         )
       ),
       React.createElement(
         "button",
         { className: "context-menu-button",
-          onClick: e => {
-            e.preventDefault();
-            this.toggleContextMenu(e, index);
-          } },
+          onClick: this.onMenuButtonClick },
         React.createElement(
           "span",
           { className: "sr-only" },
-          `Open context menu for ${ link.title }`
+          `Open context menu for ${link.title}`
         )
       ),
       React.createElement(LinkMenu, {
         dispatch: dispatch,
-        visible: isContextMenuOpen,
-        onUpdate: val => this.setState({ showContextMenu: val }),
         index: index,
+        onUpdate: this.onMenuUpdate,
+        options: link.context_menu_options || contextMenuOptions,
         site: link,
-        options: link.context_menu_options || contextMenuOptions })
+        visible: isContextMenuOpen })
     );
   }
 }
 module.exports = Card;
 
 /***/ }),
 /* 13 */
 /***/ (function(module, exports, __webpack_require__) {
@@ -1332,16 +1375,20 @@ module.exports = {
   },
   bookmark: {
     intlID: "type_label_bookmarked",
     icon: "bookmark"
   },
   trending: {
     intlID: "type_label_recommended",
     icon: "trending"
+  },
+  now: {
+    intlID: "type_label_now",
+    icon: "now"
   }
 };
 
 /***/ }),
 /* 14 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -1484,84 +1531,173 @@ class ContextMenu extends React.Componen
       setTimeout(() => {
         window.addEventListener("click", this.hideContext);
       }, 0);
     }
     if (!this.props.visible && prevProps.visible) {
       window.removeEventListener("click", this.hideContext);
     }
   }
-  componentDidUnmount() {
+  componentWillUnmount() {
     window.removeEventListener("click", this.hideContext);
   }
-  onKeyDown(event, option) {
-    switch (event.key) {
-      case "Tab":
-        // tab goes down in context menu, shift + tab goes up in context menu
-        // if we're on the last item, one more tab will close the context menu
-        // similarly, if we're on the first item, one more shift + tab will close it
-        if (event.shiftKey && option.first || !event.shiftKey && option.last) {
-          this.hideContext();
-        }
-        break;
-      case "Enter":
-        this.hideContext();
-        option.onClick();
-        break;
-    }
-  }
   render() {
     return React.createElement(
       "span",
       { hidden: !this.props.visible, className: "context-menu" },
       React.createElement(
         "ul",
         { role: "menu", className: "context-menu-list" },
-        this.props.options.map((option, i) => {
-          if (option.type === "separator") {
-            return React.createElement("li", { key: i, className: "separator" });
-          }
-          return React.createElement(
-            "li",
-            { role: "menuitem", className: "context-menu-item", key: i },
-            React.createElement(
-              "a",
-              { tabIndex: "0",
-                onKeyDown: e => this.onKeyDown(e, option),
-                onClick: () => {
-                  this.hideContext();
-                  option.onClick();
-                } },
-              option.icon && React.createElement("span", { className: `icon icon-spacer icon-${ option.icon }` }),
-              option.label
-            )
-          );
-        })
+        this.props.options.map((option, i) => option.type === "separator" ? React.createElement("li", { key: i, className: "separator" }) : React.createElement(ContextMenuItem, { key: i, option: option, hideContext: this.hideContext }))
+      )
+    );
+  }
+}
+
+class ContextMenuItem extends React.Component {
+  constructor(props) {
+    super(props);
+    this.onClick = this.onClick.bind(this);
+    this.onKeyDown = this.onKeyDown.bind(this);
+  }
+  onClick() {
+    this.props.hideContext();
+    this.props.option.onClick();
+  }
+  onKeyDown(event) {
+    const option = this.props.option;
+
+    switch (event.key) {
+      case "Tab":
+        // tab goes down in context menu, shift + tab goes up in context menu
+        // if we're on the last item, one more tab will close the context menu
+        // similarly, if we're on the first item, one more shift + tab will close it
+        if (event.shiftKey && option.first || !event.shiftKey && option.last) {
+          this.props.hideContext();
+        }
+        break;
+      case "Enter":
+        this.props.hideContext();
+        option.onClick();
+        break;
+    }
+  }
+  render() {
+    const option = this.props.option;
+
+    return React.createElement(
+      "li",
+      { role: "menuitem", className: "context-menu-item" },
+      React.createElement(
+        "a",
+        { onClick: this.onClick, onKeyDown: this.onKeyDown, tabIndex: "0" },
+        option.icon && React.createElement("span", { className: `icon icon-spacer icon-${option.icon}` }),
+        option.label
       )
     );
   }
 }
 
 module.exports = ContextMenu;
+module.exports.ContextMenu = ContextMenu;
+module.exports.ContextMenuItem = ContextMenuItem;
 
 /***/ }),
 /* 16 */
 /***/ (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 FormattedMessage = _require2.FormattedMessage;
+
+var _require3 = __webpack_require__(1);
+
+const at = _require3.actionTypes,
+      ac = _require3.actionCreators;
+
+/**
+ * Manual migration component used to start the profile import wizard.
+ * Message is presented temporarily and will go away if:
+ * 1.  User clicks "No Thanks"
+ * 2.  User completed the data import
+ * 3.  After 3 active days
+ * 4.  User clicks "Cancel" on the import wizard (currently not implemented).
+ */
+
+class ManualMigration extends React.Component {
+  constructor(props) {
+    super(props);
+    this.onLaunchTour = this.onLaunchTour.bind(this);
+    this.onCancelTour = this.onCancelTour.bind(this);
+  }
+  onLaunchTour() {
+    this.props.dispatch(ac.SendToMain({ type: at.MIGRATION_START }));
+    this.props.dispatch(ac.UserEvent({ event: at.MIGRATION_START }));
+  }
+
+  onCancelTour() {
+    this.props.dispatch(ac.SendToMain({ type: at.MIGRATION_CANCEL }));
+    this.props.dispatch(ac.UserEvent({ event: at.MIGRATION_CANCEL }));
+  }
+
+  render() {
+    return React.createElement(
+      "div",
+      { className: "manual-migration-container" },
+      React.createElement(
+        "p",
+        null,
+        React.createElement("span", { className: "icon icon-info" }),
+        React.createElement(FormattedMessage, { id: "manual_migration_explanation" })
+      ),
+      React.createElement(
+        "div",
+        { className: "manual-migration-actions actions" },
+        React.createElement(
+          "button",
+          { onClick: this.onCancelTour },
+          React.createElement(FormattedMessage, { id: "manual_migration_cancel_button" })
+        ),
+        React.createElement(
+          "button",
+          { className: "done", onClick: this.onLaunchTour },
+          React.createElement(FormattedMessage, { id: "manual_migration_import_button" })
+        )
+      )
+    );
+  }
+}
+
+module.exports = connect()(ManualMigration);
+module.exports._unconnected = ManualMigration;
+
+/***/ }),
+/* 17 */
+/***/ (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 injectIntl = _require2.injectIntl,
       FormattedMessage = _require2.FormattedMessage;
 
 var _require3 = __webpack_require__(1);
 
 const ac = _require3.actionCreators;
 
 
@@ -1616,26 +1752,26 @@ class PreferencesPane extends React.Comp
     const isVisible = this.state.visible;
     return React.createElement(
       "div",
       { className: "prefs-pane-wrapper", ref: "wrapper" },
       React.createElement(
         "div",
         { className: "prefs-pane-button" },
         React.createElement("button", {
-          className: `prefs-button icon ${ isVisible ? "icon-dismiss" : "icon-settings" }`,
+          className: `prefs-button icon ${isVisible ? "icon-dismiss" : "icon-settings"}`,
           title: props.intl.formatMessage({ id: isVisible ? "settings_pane_done_button" : "settings_pane_button_label" }),
           onClick: this.togglePane })
       ),
       React.createElement(
         "div",
         { className: "prefs-pane" },
         React.createElement(
           "div",
-          { className: `sidebar ${ isVisible ? "" : "hidden" }` },
+          { className: `sidebar ${isVisible ? "" : "hidden"}` },
           React.createElement(
             "div",
             { className: "prefs-modal-inner-wrapper" },
             React.createElement(
               "h1",
               null,
               React.createElement(FormattedMessage, { id: "settings_pane_header" })
             ),
@@ -1666,17 +1802,17 @@ class PreferencesPane extends React.Comp
   }
 }
 
 module.exports = connect(state => ({ Prefs: state.Prefs }))(injectIntl(PreferencesPane));
 module.exports.PreferencesPane = PreferencesPane;
 module.exports.PreferencesInput = PreferencesInput;
 
 /***/ }),
-/* 17 */
+/* 18 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 /* globals ContentSearchUIController */
 
 
 const React = __webpack_require__(0);
 
@@ -1765,17 +1901,17 @@ class Search extends React.Component {
     );
   }
 }
 
 module.exports = connect()(injectIntl(Search));
 module.exports._unconnected = Search;
 
 /***/ }),
-/* 18 */
+/* 19 */
 /***/ (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);
@@ -1784,17 +1920,17 @@ 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__(20);
+const Topics = __webpack_require__(21);
 
 class Section extends React.Component {
   render() {
     var _props = this.props;
     const id = _props.id,
           title = _props.title,
           icon = _props.icon,
           rows = _props.rows,
@@ -1812,17 +1948,17 @@ class Section extends React.Component {
       "section",
       null,
       React.createElement(
         "div",
         { className: "section-top-bar" },
         React.createElement(
           "h3",
           { className: "section-title" },
-          React.createElement("span", { className: `icon icon-small-spacer icon-${ icon }` }),
+          React.createElement("span", { className: `icon icon-small-spacer icon-${icon}` }),
           React.createElement(FormattedMessage, title)
         ),
         infoOption && React.createElement(
           "span",
           { className: "section-info-option" },
           React.createElement(
             "span",
             { className: "sr-only" },
@@ -1856,17 +1992,17 @@ class Section extends React.Component {
         rows.slice(0, maxCards).map((link, index) => link && React.createElement(Card, { index: index, dispatch: dispatch, link: link, contextMenuOptions: contextMenuOptions }))
       ),
       !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 }` }),
+          React.createElement("img", { className: `empty-state-icon icon icon-${emptyState.icon}` }),
           React.createElement(
             "p",
             { className: "empty-state-message" },
             React.createElement(FormattedMessage, emptyState.message)
           )
         )
       ),
       shouldShowTopics && React.createElement(Topics, { topics: this.props.topics, read_more_endpoint: this.props.read_more_endpoint })
@@ -1885,17 +2021,17 @@ class Sections extends React.Component {
   }
 }
 
 module.exports = connect(state => ({ Sections: state.Sections }))(Sections);
 module.exports._unconnected = Sections;
 module.exports.Section = Section;
 
 /***/ }),
-/* 19 */
+/* 20 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 const React = __webpack_require__(0);
 
 var _require = __webpack_require__(3);
@@ -1915,96 +2051,106 @@ const ac = _require3.actionCreators;
 
 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 };
+    this.onLinkClick = this.onLinkClick.bind(this);
+    this.onMenuButtonClick = this.onMenuButtonClick.bind(this);
+    this.onMenuUpdate = this.onMenuUpdate.bind(this);
   }
   toggleContextMenu(event, index) {
-    this.setState({ showContextMenu: true, activeTile: index });
+    this.setState({
+      activeTile: index,
+      showContextMenu: true
+    });
   }
-  trackClick() {
+  onLinkClick() {
     this.props.dispatch(ac.UserEvent({
       event: "CLICK",
       source: TOP_SITES_SOURCE,
       action_position: this.props.index
     }));
   }
+  onMenuButtonClick(event) {
+    event.preventDefault();
+    this.toggleContextMenu(event, this.props.index);
+  }
+  onMenuUpdate(showContextMenu) {
+    this.setState({ showContextMenu });
+  }
   render() {
     var _props = this.props;
     const link = _props.link,
           index = _props.index,
           dispatch = _props.dispatch;
 
     const isContextMenuOpen = this.state.showContextMenu && this.state.activeTile === index;
     const title = link.pinTitle || shortURL(link);
-    const screenshotClassName = `screenshot${ link.screenshot ? " active" : "" }`;
-    const topSiteOuterClassName = `top-site-outer${ isContextMenuOpen ? " active" : "" }`;
-    const style = { backgroundImage: link.screenshot ? `url(${ link.screenshot })` : "none" };
+    const screenshotClassName = `screenshot${link.screenshot ? " active" : ""}`;
+    const topSiteOuterClassName = `top-site-outer${isContextMenuOpen ? " active" : ""}`;
+    const style = { backgroundImage: link.screenshot ? `url(${link.screenshot})` : "none" };
     return React.createElement(
       "li",
       { className: topSiteOuterClassName, key: link.guid || link.url },
       React.createElement(
         "a",
-        { onClick: () => this.trackClick(), href: link.url },
+        { href: link.url, onClick: this.onLinkClick },
         React.createElement(
           "div",
           { className: "tile", "aria-hidden": true },
           React.createElement(
             "span",
             { className: "letter-fallback" },
             title[0]
           ),
           React.createElement("div", { className: screenshotClassName, style: style })
         ),
         React.createElement(
           "div",
-          { className: `title ${ link.isPinned ? "pinned" : "" }` },
+          { className: `title ${link.isPinned ? "pinned" : ""}` },
           link.isPinned && React.createElement("div", { className: "icon icon-pin-small" }),
           React.createElement(
             "span",
-            null,
+            { dir: "auto" },
             title
           )
         )
       ),
       React.createElement(
         "button",
-        { className: "context-menu-button",
-          onClick: e => {
-            e.preventDefault();
-            this.toggleContextMenu(e, index);
-          } },
+        { className: "context-menu-button", onClick: this.onMenuButtonClick },
         React.createElement(
           "span",
           { className: "sr-only" },
-          `Open context menu for ${ title }`
+          `Open context menu for ${title}`
         )
       ),
       React.createElement(LinkMenu, {
         dispatch: dispatch,
-        visible: isContextMenuOpen,
-        onUpdate: val => this.setState({ showContextMenu: val }),
+        index: index,
+        onUpdate: this.onMenuUpdate,
+        options: TOP_SITES_CONTEXT_MENU_OPTIONS,
         site: link,
-        index: index,
         source: TOP_SITES_SOURCE,
-        options: TOP_SITES_CONTEXT_MENU_OPTIONS })
+        visible: isContextMenuOpen })
     );
   }
 }
 
 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" })
   ),
   React.createElement(
     "ul",
     { className: "top-sites-list" },
     props.TopSites.rows.map((link, index) => link && React.createElement(TopSite, {
       key: link.guid || link.url,
       dispatch: props.dispatch,
@@ -2013,17 +2159,17 @@ const TopSites = props => React.createEl
   )
 );
 
 module.exports = connect(state => ({ TopSites: state.TopSites }))(TopSites);
 module.exports._unconnected = TopSites;
 module.exports.TopSite = TopSite;
 
 /***/ }),
-/* 20 */
+/* 21 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 const React = __webpack_require__(0);
 
 var _require = __webpack_require__(2);
@@ -2078,17 +2224,17 @@ class Topics extends React.Component {
   }
 }
 
 module.exports = Topics;
 module.exports._unconnected = Topics;
 module.exports.Topic = Topic;
 
 /***/ }),
-/* 21 */
+/* 22 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 var _require = __webpack_require__(1);
 
 const at = _require.actionTypes,
@@ -2189,17 +2335,17 @@ 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);
 
 /***/ }),
-/* 22 */
+/* 23 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 /* globals Services */
 
 
 let usablePerfObj;
 
@@ -2279,32 +2425,32 @@ var _PerfService = function _PerfService
    * @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 }`);
+      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
 };
 
 /***/ }),
-/* 23 */
+/* 24 */
 /***/ (function(module, exports) {
 
 var g;
 
 // This works in non-strict mode
 g = (function() {
 	return this;
 })();
@@ -2321,23 +2467,23 @@ try {
 // g can still be undefined, but nothing to do about it...
 // We return undefined, instead of nothing here, so it's
 // easier to handle this case. if(!global) { ...}
 
 module.exports = g;
 
 
 /***/ }),
-/* 24 */
+/* 25 */
 /***/ (function(module, exports) {
 
 module.exports = Redux;
 
 /***/ }),
-/* 25 */
+/* 26 */
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 const React = __webpack_require__(0);
 const ReactDOM = __webpack_require__(11);
 const Base = __webpack_require__(6);
--- a/browser/extensions/activity-stream/data/content/activity-stream.css
+++ b/browser/extensions/activity-stream/data/content/activity-stream.css
@@ -36,16 +36,18 @@ input {
   .icon.icon-bookmark {
     background-image: url("assets/glyph-bookmark-16.svg"); }
   .icon.icon-bookmark-remove {
     background-image: url("assets/glyph-bookmark-remove-16.svg"); }
   .icon.icon-delete {
     background-image: url("assets/glyph-delete-16.svg"); }
   .icon.icon-dismiss {
     background-image: url("assets/glyph-dismiss-16.svg"); }
+  .icon.icon-info {
+    background-image: url("assets/glyph-info-16.svg"); }
   .icon.icon-new-window {
     background-image: url("assets/glyph-newWindow-16.svg"); }
   .icon.icon-new-window-private {
     background-image: url("assets/glyph-newWindow-private-16.svg"); }
   .icon.icon-settings {
     background-image: url("assets/glyph-settings-16.svg"); }
   .icon.icon-pin {
     background-image: url("assets/glyph-pin-16.svg"); }
@@ -54,16 +56,18 @@ input {
   .icon.icon-pocket {
     background-image: url("assets/glyph-pocket-16.svg"); }
   .icon.icon-historyItem {
     background-image: url("assets/glyph-historyItem-16.svg"); }
   .icon.icon-trending {
     background-image: url("assets/glyph-trending-16.svg"); }
   .icon.icon-now {
     background-image: url("assets/glyph-now-16.svg"); }
+  .icon.icon-topsites {
+    background-image: url("assets/glyph-topsites-16.svg"); }
   .icon.icon-pin-small {
     background-image: url("assets/glyph-pin-12.svg");
     background-size: 12px;
     height: 12px;
     width: 12px; }
   .icon.icon-check {
     background-image: url("chrome://browser/skin/check.svg"); }
 
@@ -339,17 +343,18 @@ main {
   clear: both;
   margin: 0; }
 
 .sections-list .section-empty-state {
   width: 100%;
   height: 266px;
   display: flex;
   border: solid 1px rgba(0, 0, 0, 0.1);
-  border-radius: 3px; }
+  border-radius: 3px;
+  margin-bottom: 16px; }
   .sections-list .section-empty-state .empty-state {
     margin: auto;
     max-width: 350px; }
     .sections-list .section-empty-state .empty-state .empty-state-icon {
       background-size: 50px 50px;
       background-repeat: no-repeat;
       background-position: center;
       fill: rgba(160, 160, 160, 0.4);
@@ -392,17 +397,17 @@ main {
     background-image: url("assets/topic-show-more-12.svg");
     background-repeat: no-repeat;
     background-position-y: 2px; }
 
 .search-wrapper {
   cursor: default;
   display: flex;
   position: relative;
-  margin: 0 0 48px;
+  margin: 0 0 40px;
   width: 100%;
   height: 36px; }
   .search-wrapper input {
     border: 0;
     box-shadow: 0 1px 0 0 rgba(0, 0, 0, 0.1);
     flex-grow: 1;
     margin: 0;
     outline: none;
@@ -752,8 +757,39 @@ main {
     font-size: 13px;
     margin-inline-end: 6px;
     display: block; }
   .card-outer .card-context-label {
     flex-grow: 1;
     overflow: hidden;
     text-overflow: ellipsis;
     white-space: nowrap; }
+
+.manual-migration-container {
+  background: rgba(215, 215, 219, 0.5);
+  font-size: 13px;
+  height: 50px;
+  border-radius: 2px;
+  margin-bottom: 40px;
+  display: flex;
+  justify-content: space-between; }
+  .manual-migration-container p {
+    margin: 0 4px 0 12px;
+    align-self: center;
+    display: flex;
+    justify-content: space-between; }
+  .manual-migration-container .icon {
+    margin: 0 12px 0 0;
+    align-self: center; }
+
+.manual-migration-actions {
+  display: flex;
+  justify-content: space-between;
+  border: none;
+  padding: 0; }
+  .manual-migration-actions button {
+    align-self: center;
+    padding: 0 12px;
+    height: 24px;
+    margin-inline-end: 0;
+    margin-right: 12px;
+    font-size: 13px;
+    width: 106px; }
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/data/content/assets/glyph-info-16.svg
@@ -0,0 +1,6 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+   - License, v. 2.0. If a copy of the MPL was not distributed with this
+   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
+  <path fill="context-fill" d="M8 1a7 7 0 1 0 7 7 7.008 7.008 0 0 0-7-7zm0 13a6 6 0 1 1 6-6 6.007 6.007 0 0 1-6 6zm0-7a1 1 0 0 0-1 1v3a1 1 0 1 0 2 0V8a1 1 0 0 0-1-1zm0-3.188A1.188 1.188 0 1 0 9.188 5 1.188 1.188 0 0 0 8 3.812z"/>
+</svg>
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/data/content/assets/glyph-topsites-16.svg
@@ -0,0 +1,11 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+   - License, v. 2.0. If a copy of the MPL was not distributed with this
+   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
+  <g fill="#4d4d4d">
+    <rect x="1" y="1" width="6" height="6" rx="1" ry="1"/>
+    <rect x="9" y="1" width="6" height="6" rx="1" ry="1"/>
+    <rect x="1" y="9" width="6" height="6" rx="1" ry="1"/>
+    <rect x="9" y="9" width="6" height="6" rx="1" ry="1"/>
+  </g>
+</svg>
--- a/browser/extensions/activity-stream/data/locales.json
+++ b/browser/extensions/activity-stream/data/locales.json
@@ -1,27 +1,29 @@
 {
   "ach": {
     "newtab_page_title": "Dirica matidi manyen",
     "default_label_loading": "Tye ka cano…",
     "header_top_sites": "Kakube maloyo",
-    "header_highlights": "Wiye madito",
+    "header_bookmarks_placeholder": "Pud i pee ki alamabuk.",
     "type_label_visited": "Kilimo",
     "type_label_bookmarked": "Kiketo alamabuk",
     "type_label_synced": "Kiribo ki i nyonyo mukene",
     "type_label_open": "Tye ayaba",
     "type_label_topic": "Lok",
     "menu_action_bookmark": "Alamabuk",
     "menu_action_remove_bookmark": "Kwany alamabuk",
     "menu_action_copy_address": "Lok kabedo",
     "menu_action_email_link": "Kakube me email…",
     "menu_action_open_new_window": "Yab i dirica manyen",
     "menu_action_open_private_window": "Yab i dirica manyen me mung",
     "menu_action_dismiss": "Kwer",
     "menu_action_delete": "Kwany ki ii gin mukato",
+    "menu_action_pin": "Mwon",
+    "menu_action_save_to_pocket": "Gwoki i jaba",
     "search_for_something_with": "Yeny pi {search_term} ki:",
     "search_button": "Yeny",
     "search_header": "Yeny me {search_engine_name}",
     "search_web_placeholder": "Yeny kakube",
     "search_settings": "Lok ter me yeny",
     "welcome_title": "Wajoli i dirica matidi manyen",
     "welcome_body": "Firefox bi tic ki kabedo man me nyuto alamabukke mamegi, coc akwana, vidio, ki potbukke ma ilimo cokcoki ma pi gi tego loyo, wek i dok ii gi ma yot.",
     "welcome_label": "Tye ka kube ki wiye madito mamegi",
@@ -32,51 +34,62 @@
     "settings_pane_button_label": "Yub potbuk me dirica matidi mamegi manyen",
     "settings_pane_header": "Ter me dirica matidi manyen",
     "settings_pane_body": "Yer ngo ma i neno ka i yabo dirica matidi manyen.",
     "settings_pane_search_header": "Yeny",
     "settings_pane_search_body": "Yeny Kakube ki i dirica ni matidi manyen.",
     "settings_pane_topsites_header": "Kakube ma gi loyo",
     "settings_pane_topsites_body": "Nong kakube ma ilimo loyo.",
     "settings_pane_topsites_options_showmore": "Nyut rek ariyo",
-    "settings_pane_highlights_header": "Wiye madito",
-    "settings_pane_highlights_body": "Nen angec i yeny mamegi mukato ki alamabukke ni ma i cweyo manyen.",
+    "settings_pane_bookmarks_header": "Alamabuk ma cocoki",
+    "settings_pane_visit_again_header": "Lim Kidoco",
     "settings_pane_done_button": "Otum",
     "edit_topsites_button_text": "Yubi",
     "edit_topsites_button_label": "Yub bute pi kakubi ni ma giloyo",
     "edit_topsites_showmore_button": "Nyut mukene",
     "edit_topsites_showless_button": "Nyut manok",
     "edit_topsites_done_button": "Otum",
     "edit_topsites_pin_button": "Mwon kakube man",
     "edit_topsites_edit_button": "Yub kakube man",
-    "edit_topsites_dismiss_button": "Kwer kakube man"
+    "edit_topsites_dismiss_button": "Kwer kakube man",
+    "edit_topsites_add_button": "Medi",
+    "topsites_form_edit_header": "Yub Kakube maloyo",
+    "topsites_form_add_button": "Medi",
+    "topsites_form_save_button": "Gwoki",
+    "topsites_form_cancel_button": "Kwer"
   },
   "af": {},
   "an": {},
   "ar": {
     "newtab_page_title": "لسان جديد",
     "default_label_loading": "يُحمّل…",
     "header_top_sites": "المواقع الأكثر زيارة",
-    "header_highlights": "أهم الأحداث",
     "header_stories": "أهم الأخبار",
+    "header_visit_again": "زرها مجددا",
+    "header_bookmarks": "أحدث العلامات",
+    "header_bookmarks_placeholder": "لا علامات لديك بعد.",
     "header_stories_from": "من",
     "type_label_visited": "مُزارة",
     "type_label_bookmarked": "معلّمة",
     "type_label_synced": "مُزامنة من جهاز آخر",
     "type_label_recommended": "مُتداول",
     "type_label_open": "مفتوحة",
     "type_label_topic": "الموضوع",
     "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": "احذف من التأريخ",
+    "menu_action_pin": "ثبّت",
+    "menu_action_unpin": "أزل",
+    "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": "غيّر إعدادات البحث",
     "welcome_title": "مرحبًا في لسان جديد",
     "welcome_body": "سيستخدم فيرفكس هذا المكان لعرض أكثر العلامات، و المقالات، و الفيديوهات والصفحات التي زرتها مؤخرا، ليمكنك العودة إليها بسهولة.",
@@ -88,18 +101,20 @@
     "settings_pane_button_label": "خصص صفحة اللسان الجديد",
     "settings_pane_header": "تفضيلات صفحة اللسان الجديد",
     "settings_pane_body": "اختر ما تراه عند فتح لسان جديد.",
     "settings_pane_search_header": "بحث",
     "settings_pane_search_body": "ابحث في الوِب من اللسان الجديد.",
     "settings_pane_topsites_header": "المواقع الأكثر زيارة",
     "settings_pane_topsites_body": "وصول للمواقع التي تزورها أكثر.",
     "settings_pane_topsites_options_showmore": "اعرض صفّين",
-    "settings_pane_highlights_header": "أهم الأحداث",
-    "settings_pane_highlights_body": "اطّلع على تأريخ التصفح الأحدث، و العلامات المنشأة حديثًا.",
+    "settings_pane_bookmarks_header": "أحدث العلامات",
+    "settings_pane_bookmarks_body": "علاماتك المعلّمة حديثًا في مكان واحد.",
+    "settings_pane_visit_again_header": "زرها مجددا",
+    "settings_pane_visit_again_body": "سيعرض لك فَيَرفُكس بعضًا من تأريخ تصفحك الذي قد تود تذكّره لاحقًا.",
     "settings_pane_pocketstories_header": "أهم المواضيع",
     "settings_pane_pocketstories_body": "يساعدك Pocket –عضو في أسرة موزيلا– على الوصول إلى محتوى عالِ الجودة ربما لم يُكن ليتاح لك بدونه.",
     "settings_pane_done_button": "تمّ",
     "edit_topsites_button_text": "حرِّر",
     "edit_topsites_button_label": "خصص قسم المواقع الأكثر زيارة",
     "edit_topsites_showmore_button": "اعرض المزيد",
     "edit_topsites_showless_button": "اعرض أقل",
     "edit_topsites_done_button": "تمّ",
@@ -491,16 +506,17 @@
     "settings_pane_body": "Trieu què voleu veure quan obriu una pestanya nova.",
     "settings_pane_search_header": "Cerca",
     "settings_pane_search_body": "Cerca al web des de la pestanya nova.",
     "settings_pane_topsites_header": "Llocs principals",
     "settings_pane_topsites_body": "Accediu als llocs web que visiteu més sovint.",
     "settings_pane_topsites_options_showmore": "Mostra dues files",
     "settings_pane_bookmarks_header": "Adreces d'interès recents",
     "settings_pane_bookmarks_body": "Les adreces d'interès que aneu creant, en un lloc còmode.",
+    "settings_pane_visit_again_header": "Torneu a visitar",
     "settings_pane_visit_again_body": "El Firefox us mostrarà parts del vostre historial de navegació que potser us agradaria recordar o tornar a visitar.",
     "settings_pane_pocketstories_header": "Articles populars",
     "settings_pane_pocketstories_body": "El Pocket, membre de la família Mozilla, us permet accedir a contingut d'alta qualitat que d'altra manera potser no trobaríeu.",
     "settings_pane_done_button": "Fet",
     "edit_topsites_button_text": "Edita",
     "edit_topsites_button_label": "Personalitzeu la secció Llocs principals",
     "edit_topsites_showmore_button": "Mostra'n més",
     "edit_topsites_showless_button": "Mostra'n menys",
@@ -595,38 +611,48 @@
     "topsites_form_title_placeholder": "Zadejte název",
     "topsites_form_url_placeholder": "Zadejte nebo vložte URL adresu",
     "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 miliony lidí.",
+    "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"
   },
   "cy": {
     "newtab_page_title": "Tab Newydd",
     "default_label_loading": "Llwytho…",
     "header_top_sites": "Hoff Wefannau",
-    "header_highlights": "Goreuon",
+    "header_stories": "Hoff Straeon",
+    "header_visit_again": "Ymweld Eto",
+    "header_bookmarks": "Nodau Tudalen Diweddar",
+    "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",
     "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",
+    "menu_action_pin": "Pinio",
+    "menu_action_unpin": "Dad-binio",
+    "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",
     "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",
@@ -637,27 +663,46 @@
     "settings_pane_button_label": "Cyfaddasu eich tudalen Tab Newydd",
     "settings_pane_header": "Dewisiadau Tab Newydd",
     "settings_pane_body": "Dewis beth rydych yn ei weld pan fyddwch yn agor tab newydd.",
     "settings_pane_search_header": "Chwilio",
     "settings_pane_search_body": "Chwilio'r We o'ch tab newydd.",
     "settings_pane_topsites_header": "Hoff Wefannau",
     "settings_pane_topsites_body": "Cael mynediad at y gwefannau rydych yn ymweld â nhw amlaf.",
     "settings_pane_topsites_options_showmore": "Dangos dwy res",
-    "settings_pane_highlights_header": "Goreuon",
-    "settings_pane_highlights_body": "Edrych nôl ar eich hanes pori a nodau tudalen diweddar.",
+    "settings_pane_bookmarks_header": "Nodau Tudalen Diweddar",
+    "settings_pane_bookmarks_body": "Eich nodau tudalen diweddaraf mewn un lleoliad hwylus.",
+    "settings_pane_visit_again_header": "Ymweld Eto",
+    "settings_pane_visit_again_body": "Gall Firefox ddangos i chi rannau o'ch hanes pori yr hoffech eu cofio neu fynd nôl atyn nhw.",
+    "settings_pane_pocketstories_header": "Hoff Straeon",
+    "settings_pane_pocketstories_body": "Gall Pocket, sy'n rhan o deulu Mozilla, eich helpu i ganfod cynnwys o ansawdd uchel na fyddech wedi eu canfod fel arall.",
     "settings_pane_done_button": "Gorffen",
     "edit_topsites_button_text": "Golygu",
     "edit_topsites_button_label": "Cyfaddasu eich adran Hoff Wefannau",
     "edit_topsites_showmore_button": "Dangos rhagor",
     "edit_topsites_showless_button": "Dangos llai",
     "edit_topsites_done_button": "Gorffen",
     "edit_topsites_pin_button": "Pinio'r wefan",
+    "edit_topsites_unpin_button": "Dad-binio'r wefan",
     "edit_topsites_edit_button": "Golygu'r wefan",
-    "edit_topsites_dismiss_button": "Dileu'r wefan"
+    "edit_topsites_dismiss_button": "Dileu'r wefan",
+    "edit_topsites_add_button": "Ychwanegu",
+    "topsites_form_add_header": "Hoff Wefan Newydd",
+    "topsites_form_edit_header": "Golygu'r Hoff Wefan",
+    "topsites_form_title_placeholder": "Rhoi teitl",
+    "topsites_form_url_placeholder": "Teipio neu ludo URL",
+    "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"
   },
   "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",
@@ -698,17 +743,19 @@
     "settings_pane_header": "Indstillinger for Nyt faneblad",
     "settings_pane_body": "Vælg, hvad der vises, når du åbner et nyt faneblad.",
     "settings_pane_search_header": "Søgning",
     "settings_pane_search_body": "Søg på nettet fra Nyt faneblad.",
     "settings_pane_topsites_header": "Mest besøgte websider",
     "settings_pane_topsites_body": "Adgang til de websider, du besøger oftest.",
     "settings_pane_topsites_options_showmore": "Vis to rækker",
     "settings_pane_bookmarks_header": "Seneste bogmærker",
+    "settings_pane_bookmarks_body": "Dine seneste bogmærker samlet ét sted.",
     "settings_pane_visit_again_header": "Besøg igen",
+    "settings_pane_visit_again_body": "Firefox viser dig dele af din browserhistorik, som du måske vil huske på eller vende tilbage til.",
     "settings_pane_pocketstories_header": "Tophistorier",
     "settings_pane_pocketstories_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.",
     "settings_pane_done_button": "Færdig",
     "edit_topsites_button_text": "Rediger",
     "edit_topsites_button_label": "Tilpas afsnittet Mest besøgte websider",
     "edit_topsites_showmore_button": "Vis flere",
     "edit_topsites_showless_button": "Vis færre",
     "edit_topsites_done_button": "Færdig",
@@ -967,30 +1014,40 @@
     "pocket_feedback_header": "Τα καλύτερα του διαδικτύου, παρέχονται από πάνω από 25 εκατομμύρια άτομα.",
     "pocket_feedback_body": "Το Pocket, ένα μέλος της οικογένειας Mozilla, θα σάς βοηθήσει να ανακαλύψετε περιεχόμενο υψηλής ποιότητας που ίσως να μην βρίσκατε διαφορετικά.",
     "pocket_send_feedback": "Αποστολή σχολίων"
   },
   "en-GB": {
     "newtab_page_title": "New Tab",
     "default_label_loading": "Loading…",
     "header_top_sites": "Top Sites",
-    "header_highlights": "Highlights",
+    "header_stories": "Top Stories",
+    "header_visit_again": "Visit Again",
+    "header_bookmarks": "Recent Bookmarks",
+    "header_bookmarks_placeholder": "You don’t have any bookmarks yet.",
+    "header_stories_from": "from",
     "type_label_visited": "Visited",
     "type_label_bookmarked": "Bookmarked",
     "type_label_synced": "Synchronised from another device",
+    "type_label_recommended": "Trending",
     "type_label_open": "Open",
     "type_label_topic": "Topic",
     "menu_action_bookmark": "Bookmark",
     "menu_action_remove_bookmark": "Remove Bookmark",
     "menu_action_copy_address": "Copy Address",
     "menu_action_email_link": "Email Link…",
     "menu_action_open_new_window": "Open in a New Window",
     "menu_action_open_private_window": "Open in a New Private Window",
     "menu_action_dismiss": "Dismiss",
     "menu_action_delete": "Delete from History",
+    "menu_action_pin": "Pin",
+    "menu_action_unpin": "Unpin",
+    "confirm_history_delete_p1": "Are you sure you want to delete every instance of this page from your history?",
+    "confirm_history_delete_notice_p2": "This action cannot be undone.",
+    "menu_action_save_to_pocket": "Save to Pocket",
     "search_for_something_with": "Search for {search_term} with:",
     "search_button": "Search",
     "search_header": "{search_engine_name} Search",
     "search_web_placeholder": "Search the Web",
     "search_settings": "Change Search Settings",
     "welcome_title": "Welcome to new tab",
     "welcome_body": "Firefox will use this space to show your most relevant bookmarks, articles, videos, and pages you’ve recently visited, so you can get back to them easily.",
     "welcome_label": "Identifying your Highlights",
@@ -1001,27 +1058,46 @@
     "settings_pane_button_label": "Customise your New Tab page",
     "settings_pane_header": "New Tab Preferences",
     "settings_pane_body": "Choose what you see when you open a new tab.",
     "settings_pane_search_header": "Search",
     "settings_pane_search_body": "Search the Web from your new tab.",
     "settings_pane_topsites_header": "Top Sites",
     "settings_pane_topsites_body": "Access the web sites you visit most.",
     "settings_pane_topsites_options_showmore": "Show two rows",
-    "settings_pane_highlights_header": "Highlights",
-    "settings_pane_highlights_body": "Look back at your recent browsing history and newly created bookmarks.",
+    "settings_pane_bookmarks_header": "Recent Bookmarks",
+    "settings_pane_bookmarks_body": "Your newly created bookmarks in one handy location.",
+    "settings_pane_visit_again_header": "Visit Again",
+    "settings_pane_visit_again_body": "Firefox will show you parts of your browsing history that you might want to remember or get back to.",
+    "settings_pane_pocketstories_header": "Top Stories",
+    "settings_pane_pocketstories_body": "Pocket, a part of the Mozilla family, will help connect you to high-quality content that you may not have found otherwise.",
     "settings_pane_done_button": "Done",
     "edit_topsites_button_text": "Edit",
     "edit_topsites_button_label": "Customise your Top Sites section",
     "edit_topsites_showmore_button": "Show more",
     "edit_topsites_showless_button": "Show less",
     "edit_topsites_done_button": "Done",
     "edit_topsites_pin_button": "Pin this site",
+    "edit_topsites_unpin_button": "Unpin this site",
     "edit_topsites_edit_button": "Edit this site",
-    "edit_topsites_dismiss_button": "Dismiss this site"
+    "edit_topsites_dismiss_button": "Dismiss this site",
+    "edit_topsites_add_button": "Add",
+    "topsites_form_add_header": "Top Sites",
+    "topsites_form_edit_header": "Edit Top Site",
+    "topsites_form_title_placeholder": "Enter a title",
+    "topsites_form_url_placeholder": "Type or paste a URL",
+    "topsites_form_add_button": "Add",
+    "topsites_form_save_button": "Save",
+    "topsites_form_cancel_button": "Cancel",
+    "topsites_form_url_validation": "Valid URL required",
+    "pocket_read_more": "Popular Topics:",
+    "pocket_read_even_more": "View More Stories",
+    "pocket_feedback_header": "The best of the web, curated by over 25 million people.",
+    "pocket_feedback_body": "Pocket, a part of the Mozilla family, will help connect you to high-quality content that you may not have found otherwise.",
+    "pocket_send_feedback": "Send Feedback"
   },
   "en-US": {
     "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",
@@ -1029,16 +1105,17 @@
     "header_bookmarks_placeholder": "You don’t have any bookmarks yet.",
     "header_stories_from": "from",
     "type_label_visited": "Visited",
     "type_label_bookmarked": "Bookmarked",
     "type_label_synced": "Synced from another device",
     "type_label_recommended": "Trending",
     "type_label_open": "Open",
     "type_label_topic": "Topic",
+    "type_label_now": "Now",
     "menu_action_bookmark": "Bookmark",
     "menu_action_remove_bookmark": "Remove Bookmark",
     "menu_action_copy_address": "Copy Address",
     "menu_action_email_link": "Email Link…",
     "menu_action_open_new_window": "Open in a New Window",
     "menu_action_open_private_window": "Open in a New Private Window",
     "menu_action_dismiss": "Dismiss",
     "menu_action_delete": "Delete from History",
@@ -1093,50 +1170,100 @@
     "topsites_form_save_button": "Save",
     "topsites_form_cancel_button": "Cancel",
     "topsites_form_url_validation": "Valid URL required",
     "pocket_read_more": "Popular Topics:",
     "pocket_read_even_more": "View More Stories",
     "pocket_feedback_header": "The best of the web, curated by over 25 million people.",
     "pocket_feedback_body": "Pocket, a part of the Mozilla family, will help connect you to high-quality content that you may not have found otherwise.",
     "pocket_send_feedback": "Send Feedback",
-    "empty_state_topstories": "You’ve caught up. Check back later for more top stories from Pocket. Can’t wait? Select a popular topic to find more great stories from around the web."
+    "topstories_empty_state": "You’ve caught up. Check back later for more top stories from {provider}. Can’t wait? Select a popular topic to find more great stories from around the web.",
+    "manual_migration_explanation": "Try Firefox with your favorite sites and bookmarks from another browser.",
+    "manual_migration_cancel_button": "No Thanks",
+    "manual_migration_import_button": "Import Now"
   },
   "en-ZA": {},
   "eo": {
     "newtab_page_title": "Nova legosigno",
     "default_label_loading": "Ŝargado…",
     "header_top_sites": "Plej vizititaj",
-    "header_highlights": "Elstaraĵoj",
+    "header_stories": "Ĉefaj artikoloj",
+    "header_visit_again": "Viziti denove",
+    "header_bookmarks": "Ĵusaj legosignoj",
+    "header_bookmarks_placeholder": "Vi ankoraŭ ne havas legosignojn.",
+    "header_stories_from": "el",
     "type_label_visited": "Vizititaj",
     "type_label_bookmarked": "Kun legosigno",
     "type_label_synced": "Spegulitaj el alia aparato",
+    "type_label_recommended": "Tendencoj",
     "type_label_open": "Malfermita",
     "type_label_topic": "Temo",
     "menu_action_bookmark": "Aldoni legosignon",
     "menu_action_remove_bookmark": "Forigi legosignon",
     "menu_action_copy_address": "Kopii adreson",
     "menu_action_email_link": "Sendi ligilon retpoŝte…",
     "menu_action_open_new_window": "Malfermi en nova fenestro",
     "menu_action_open_private_window": "Malfermi en nova privata fenestro",
     "menu_action_dismiss": "Ignori",
     "menu_action_delete": "Forigi el historio",
+    "menu_action_pin": "Alpingli",
+    "menu_action_unpin": "Depingli",
+    "confirm_history_delete_p1": "Ĉu vi certe volas forigi ĉiun aperon de tiu ĉi paĝo el via historio?",
+    "confirm_history_delete_notice_p2": "Tiu ĉi ago ne estas malfarebla.",
+    "menu_action_save_to_pocket": "Konservi en Pocket",
     "search_for_something_with": "Serĉi {search_term} per:",
     "search_button": "Serĉi",
     "search_header": "Serĉo de {search_engine_name}",
     "search_web_placeholder": "Serĉi la Teksaĵon",
     "search_settings": "Modifi serĉajn agordojn",
     "welcome_title": "Bonvenon al nova langeto",
     "welcome_body": "Firefox uzos tiun ĉi spacon por montri al vi viaj plej gravajn legosignojn, artikolojn, filmetojn kaj paĝojn, kiujn vi vizitis antaŭ nelonge, tiel ke vi povos reiri al ili facile.",
     "welcome_label": "Elstaraĵoj identigataj",
     "time_label_less_than_minute": "<1m",
     "time_label_minute": "{number}m",
     "time_label_hour": "{number}h",
     "time_label_day": "{number}t",
-    "settings_pane_button_label": "Personecigi la paĝon por novaj langetoj"
+    "settings_pane_button_label": "Personecigi la paĝon por novaj langetoj",
+    "settings_pane_header": "Preferoj pri nova langeto",
+    "settings_pane_body": "Elekti tion, kio estos videbla je malfermo de nova langeto.",
+    "settings_pane_search_header": "Serĉi",
+    "settings_pane_search_body": "Serĉi la Teksaĵon el via nova langeto.",
+    "settings_pane_topsites_header": "Plej vizitaj",
+    "settings_pane_topsites_body": "Aliri la plej ofte vizitajn retejojn.",
+    "settings_pane_topsites_options_showmore": "Montri en du vicoj",
+    "settings_pane_bookmarks_header": "Ĵusaj legosignoj",
+    "settings_pane_bookmarks_body": "Viaj ĵus kreitaj legosignoj, ĉemane.",
+    "settings_pane_visit_again_header": "Viziti denove",
+    "settings_pane_visit_again_body": "Firefoĉ montros al vi partojn de via retuma historio, kiujn vi eble volas memori aŭ viziti denove.",
+    "settings_pane_pocketstories_header": "Ĉefaj artikoloj",
+    "settings_pane_pocketstories_body": "Pocket, parto de la familio de Mozilla, helpos vin trovi altkvalitan enhavon, kiun vi eble ne trovos aliloke.",
+    "settings_pane_done_button": "Farita",
+    "edit_topsites_button_text": "Redakti",
+    "edit_topsites_button_label": "Personecigi la sekcion 'plej vizititaj'",
+    "edit_topsites_showmore_button": "Montri pli",
+    "edit_topsites_showless_button": "Montri malpli",
+    "edit_topsites_done_button": "Farita",
+    "edit_topsites_pin_button": "Alpingli ĉi tiun retejon",
+    "edit_topsites_unpin_button": "Depingli tiun ĉi retejon",
+    "edit_topsites_edit_button": "Redakti ĉi tiun retejon",
+    "edit_topsites_dismiss_button": "Ignori ĉi tiun retejon",
+    "edit_topsites_add_button": "Aldoni",
+    "topsites_form_add_header": "Nova ofta retejo",
+    "topsites_form_edit_header": "Redakti ofta retejo",
+    "topsites_form_title_placeholder": "Tajpu titolon",
+    "topsites_form_url_placeholder": "Tajpu aŭ alguu retadreson",
+    "topsites_form_add_button": "Aldoni",
+    "topsites_form_save_button": "Konservi",
+    "topsites_form_cancel_button": "Nuligi",
+    "topsites_form_url_validation": "Valida retadreso estas postulata",
+    "pocket_read_more": "Ĉefaj temoj:",
+    "pocket_read_even_more": "Montri pli da artikoloj",
+    "pocket_feedback_header": "La plejbono el la Teksaĵo, reviziita de pli ol 25 milionoj da personoj.",
+    "pocket_feedback_body": "Pocket, parto de la familio de Mozilla, helpos vin trovi altkvalitan enhavon, kiun vi eble ne trovos aliloke.",
+    "pocket_send_feedback": "Sendi komentojn"
   },
   "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",
@@ -2022,30 +2149,40 @@
     "time_label_minute": "{number}મિનિટ",
     "time_label_hour": "{number}કલાક",
     "time_label_day": "{number}દિવસ"
   },
   "he": {
     "newtab_page_title": "לשונית חדשה",
     "default_label_loading": "בטעינה…",
     "header_top_sites": "אתרים מובילים",
-    "header_highlights": "המלצות",
+    "header_stories": "סיפורים מובילים",
+    "header_visit_again": "ביקור חוזר",
+    "header_bookmarks": "סימניות אחרונות",
+    "header_bookmarks_placeholder": "אין לך סימניות עדיין.",
+    "header_stories_from": "מאת",
     "type_label_visited": "ביקורים קודמים",
     "type_label_bookmarked": "נוצרה סימניה",
     "type_label_synced": "סונכרן מהתקן אחר",
+    "type_label_recommended": "פופולרי",
     "type_label_open": "פתיחה",
     "type_label_topic": "נושא",
     "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_dismiss": "הסרה",
     "menu_action_delete": "מחיקה מההיסטוריה",
+    "menu_action_pin": "הצמדה",
+    "menu_action_unpin": "ביטול הצמדה",
+    "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": "שינוי הגדרות חיפוש",
     "welcome_title": "ברוכים הבאים לדף הלשונית החדשה",
     "welcome_body": "Firefox ישתמש באזור זה כדי להציג את הסימניות הרלוונטיות ביותר, מאמרים, סרטוני וידאו ודפים שביקרת בהם לאחרונה, כך שניתן יהיה לגשת אליהם שוב בקלות.",
     "welcome_label": "תחומי העניין שלך מזוהים",
@@ -2056,27 +2193,46 @@
     "settings_pane_button_label": "התאמה אישית של דף הלשונית החדשה שלך",
     "settings_pane_header": "העדפות לשונית חדשה",
     "settings_pane_body": "ניתן לבחור מה יופיע בפניך בעת פתיחת לשונית חדשה.",
     "settings_pane_search_header": "חיפוש",
     "settings_pane_search_body": "חיפוש באינטרנט ישירות מהלשונית החדשה שלך.",
     "settings_pane_topsites_header": "אתרים מובילים",
     "settings_pane_topsites_body": "גישה לאתרים בהם ביקרת הכי הרבה.",
     "settings_pane_topsites_options_showmore": "הצגת שתי שורות",
-    "settings_pane_highlights_header": "המלצות",
-    "settings_pane_highlights_body": "ניתן להסתכל על היסטוריית הגלישה העדכנית שלך ועל הסימניות האחרונות שנוצרו.",
+    "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_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": "ביטול הצמדת אתר זה",
     "edit_topsites_edit_button": "עריכת אתר זה",
-    "edit_topsites_dismiss_button": "התעלמות מאתר זה"
+    "edit_topsites_dismiss_button": "התעלמות מאתר זה",
+    "edit_topsites_add_button": "הוספה",
+    "topsites_form_add_header": "אתר מוביל חדש",
+    "topsites_form_edit_header": "עריכת אתר מוביל",
+    "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": "המיטב מרחבי האינטרנט, נאסף על ידי 25 מיליון אנשים.",
+    "pocket_feedback_body": "Pocket, חלק ממשפחת Mozilla, יסייע לך להתחבר לתוכן באיכות גבוהה שיתכן שלא היה מגיע אליך בדרך אחרת.",
+    "pocket_send_feedback": "שליחת משוב"
   },
   "hi-IN": {
     "newtab_page_title": "नया टैब",
     "default_label_loading": "लोड हो रहा है…",
     "header_top_sites": "सर्वोच्च साइटें",
     "header_visit_again": "पुनः पधारें",
     "header_bookmarks": "हाल के पुस्तचिह्न",
     "header_stories_from": "के द्वारा",
@@ -3033,33 +3189,39 @@
     "edit_topsites_pin_button": "Pin ເວັບໄຊທ໌ນີ້",
     "edit_topsites_edit_button": "ແກ້ໄຂເວັບໄຊທ໌ນີ້",
     "edit_topsites_dismiss_button": "ຍົກເລີກເວັບໄຊທ໌ນີ້"
   },
   "lt": {
     "newtab_page_title": "Nauja kortelė",
     "default_label_loading": "Įkeliama…",
     "header_top_sites": "Lankomiausios svetainės",
-    "header_highlights": "Akcentai",
     "header_stories": "Populiariausi straipsniai",
+    "header_visit_again": "Aplankykite vėl",
+    "header_bookmarks": "Paskiausi adresyno įrašai",
+    "header_bookmarks_placeholder": "Jūs dar neturite adresyno įrašų.",
     "header_stories_from": "iš",
     "type_label_visited": "Aplankyti",
     "type_label_bookmarked": "Adresyne",
     "type_label_synced": "Sinchronizuoti iš kito įrenginio",
     "type_label_recommended": "Populiaru",
     "type_label_open": "Atviri",
     "type_label_topic": "Tema",
     "menu_action_bookmark": "Įrašyti į adresyną",
     "menu_action_remove_bookmark": "Pašalinti iš adresyno",
     "menu_action_copy_address": "Kopijuoti adresą",
     "menu_action_email_link": "Siųsti saitą el. paštu…",
     "menu_action_open_new_window": "Atverti naujame lange",
     "menu_action_open_private_window": "Atverti naujame privačiajame lange",
     "menu_action_dismiss": "Paslėpti",
     "menu_action_delete": "Pašalinti iš istorijos",
+    "menu_action_pin": "Įsegti",
+    "menu_action_unpin": "Išsegti",
+    "confirm_history_delete_p1": "Ar tikrai norite pašalinti visus šio tinklalapio įrašus iš savo naršymo žurnalo?",
+    "confirm_history_delete_notice_p2": "Atlikus šį veiksmą, jo atšaukti neįmanoma.",
     "menu_action_save_to_pocket": "Įrašyti į „Pocket“",
     "search_for_something_with": "Ieškoti „{search_term}“ per:",
     "search_button": "Ieškoti",
     "search_header": "{search_engine_name} paieška",
     "search_web_placeholder": "Ieškokite saityne",
     "search_settings": "Keisti paieškos nuostatas",
     "welcome_title": "Sveiki, čia nauja kortelė",
     "welcome_body": "„Firefox“ naudos šią vietą jums aktualiausių adresyno įrašų, straipsnių, vaizdo įrašų bei neseniai lankytų tinklalapių rodymui, kad galėtumėte lengvai į juos sugrįžti.",
@@ -3071,18 +3233,20 @@
     "settings_pane_button_label": "Tinkinkite savo naujos kortelės puslapį",
     "settings_pane_header": "Naujos kortelės nuostatos",
     "settings_pane_body": "Pasirinkite, ką matysite atvėrę naują kortelę.",
     "settings_pane_search_header": "Paieška",
     "settings_pane_search_body": "Ieškokite saityne tiesiai iš naujos kortelės.",
     "settings_pane_topsites_header": "Lankomiausios svetainės",
     "settings_pane_topsites_body": "Pasiekite jūsų dažniausiai lankomas svetaines.",
     "settings_pane_topsites_options_showmore": "Rodyti dvi eilutes",
-    "settings_pane_highlights_header": "Akcentai",
-    "settings_pane_highlights_body": "Pažvelkite į savo naujausią naršymo istoriją bei paskiausiai pridėtus adresyno įrašus.",
+    "settings_pane_bookmarks_header": "Paskiausi adresyno įrašai",
+    "settings_pane_bookmarks_body": "Jūsų naujai sukurti adresyno įrašai vienoje vietoje.",
+    "settings_pane_visit_again_header": "Aplankykite vėl",
+    "settings_pane_visit_again_body": "„Firefox“ pateiks ištraukas iš jūsų naršymo žurnalo, kurias galbūt norėtumėte prisiminti.",
     "settings_pane_pocketstories_header": "Populiariausi straipsniai",
     "settings_pane_pocketstories_body": "„Pocket“, „Mozillos“ šeimos dalis, padės jums atrasti kokybišką turinį, kurio kitaip gal nebūtumėte radę.",
     "settings_pane_done_button": "Atlikta",
     "edit_topsites_button_text": "Keisti",
     "edit_topsites_button_label": "Tinkinkite savo lankomiausių svetainių skiltį",
     "edit_topsites_showmore_button": "Rodyti daugiau",
     "edit_topsites_showless_button": "Rodyti mažiau",
     "edit_topsites_done_button": "Atlikta",
@@ -3841,17 +4005,17 @@
     "type_label_topic": "Tópico",
     "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": "Eliminar do histórico",
+    "menu_action_delete": "Apagar do histórico",
     "menu_action_pin": "Afixar",
     "menu_action_unpin": "Desafixar",
     "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}",
@@ -3860,19 +4024,19 @@
     "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",
-    "settings_pane_header": "Novas preferências de separador",
-    "settings_pane_body": "Escolha o que ver quando abre um novo separador.",
-    "settings_pane_search_header": "Pesquisar",
+    "settings_pane_header": "Preferências de novo separador",
+    "settings_pane_body": "Escolha o que vê quando abre um novo separador.",
+    "settings_pane_search_header": "Pesquisa",
     "settings_pane_search_body": "Pesquise na Web a partir do seu novo separador.",
     "settings_pane_topsites_header": "Sites mais visitados",
     "settings_pane_topsites_body": "Aceda aos websites que mais visita.",
     "settings_pane_topsites_options_showmore": "Mostrar duas linhas",
     "settings_pane_bookmarks_header": "Marcadores recentes",
     "settings_pane_bookmarks_body": "Os seus marcadores recém-criados num único local acessível.",
     "settings_pane_visit_again_header": "Visitar novamente",
     "settings_pane_visit_again_body": "O Firefox irá mostrar-lhe partes do seu histórico de navegação que pode querer relembrar ou voltar a aceder.",
@@ -4994,17 +5158,51 @@
     "topsites_form_cancel_button": "منسوخ کریں",
     "topsites_form_url_validation": "جائز URL درکار ہے",
     "pocket_read_more": "مشہور مضامین:",
     "pocket_read_even_more": "مزید کہانیاں دیکھیں",
     "pocket_feedback_body": "Pocket ایک جصہ ہے Mozilla کے خاندان کا،آپ کو اعلی میعار کے مواد سے جڑنے میں مدد دے گا جو شاید آپ بصورت دیگر نہ ڈھونڈ سکتے۔",
     "pocket_send_feedback": "جواب الجواب ارسال کریں"
   },
   "uz": {},
-  "vi": {},
+  "vi": {
+    "newtab_page_title": "Tab mới",
+    "default_label_loading": "Đang tải…",
+    "header_top_sites": "Trang web hàng đầu",
+    "header_stories": "Câu chuyện hàng đầu",
+    "header_visit_again": "Truy cập lại",
+    "header_bookmarks": "Các bookmark gần đây",
+    "header_bookmarks_placeholder": "Bạn chưa có bookmark nào.",
+    "header_stories_from": "từ",
+    "type_label_visited": "Đã truy cập",
+    "type_label_bookmarked": "Đã được đánh dấu",
+    "type_label_synced": "Đồng bộ từ thiết bị khác",
+    "type_label_recommended": "Xu hướng",
+    "type_label_open": "Mở",
+    "type_label_topic": "Chủ đề",
+    "menu_action_bookmark": "Đánh dấu",
+    "menu_action_remove_bookmark": "Xóa đánh dấu",
+    "menu_action_copy_address": "Chép địa chỉ",
+    "menu_action_email_link": "Liên kết Email...",
+    "menu_action_open_new_window": "Mở trong Cửa Sổ Mới",
+    "menu_action_open_private_window": "Mở trong cửa sổ riêng tư mới",
+    "menu_action_dismiss": "Bỏ qua",
+    "menu_action_delete": "Xóa từ lịch xử",
+    "menu_action_pin": "Ghim",
+    "menu_action_unpin": "Bỏ ghim",
+    "confirm_history_delete_notice_p2": "Hành động này không thể hoàn tác.",
+    "menu_action_save_to_pocket": "Lưu vào Pocket",
+    "search_for_something_with": "Tìm {search_term} với:",
+    "search_button": "Tìm kiếm",
+    "search_header": "Công cụ tìm kiếm {search_engine_name}",
+    "time_label_less_than_minute": "<1phút",
+    "time_label_minute": "{number}phút",
+    "time_label_hour": "{number}giờ",
+    "settings_pane_search_header": "Tìm kiếm"
+  },
   "wo": {},
   "xh": {},
   "zh-CN": {
     "newtab_page_title": "新标签页",
     "default_label_loading": "正在载入…",
     "header_top_sites": "常用网站",
     "header_stories": "热门报道",
     "header_visit_again": "再次造访",
--- a/browser/extensions/activity-stream/lib/ActivityStream.jsm
+++ b/browser/extensions/activity-stream/lib/ActivityStream.jsm
@@ -5,16 +5,17 @@
 
 const {utils: Cu} = Components;
 
 // 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", {});
 const {PlacesFeed} = Cu.import("resource://activity-stream/lib/PlacesFeed.jsm", {});
 const {PrefsFeed} = Cu.import("resource://activity-stream/lib/PrefsFeed.jsm", {});
 const {Store} = Cu.import("resource://activity-stream/lib/Store.jsm", {});
 const {SnippetsFeed} = Cu.import("resource://activity-stream/lib/SnippetsFeed.jsm", {});
 const {SystemTickFeed} = Cu.import("resource://activity-stream/lib/SystemTickFeed.jsm", {});
 const {TelemetryFeed} = Cu.import("resource://activity-stream/lib/TelemetryFeed.jsm", {});
 const {TopSitesFeed} = Cu.import("resource://activity-stream/lib/TopSitesFeed.jsm", {});
@@ -76,16 +77,28 @@ const PREFS_CONFIG = new Map([
       "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"
     }`
+  }],
+  ["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",
+    value: 4
+  }],
+  ["migrationLastShownDate", {
+    title: "Timestamp when migration message was last shown. In seconds.",
+    value: 0
   }]
 ]);
 
 const FEEDS_CONFIG = new Map();
 for (const {name, factory, title, value} of SECTION_FEEDS_CONFIG.concat([
   {
     name: "localization",
     factory: () => new LocalizationFeed(),
@@ -128,16 +141,22 @@ for (const {name, factory, title, value}
     title: "Relays telemetry-related actions to TelemetrySender",
     value: true
   },
   {
     name: "topsites",
     factory: () => new TopSitesFeed(),
     title: "Queries places and gets metadata for Top Sites section",
     value: true
+  },
+  {
+    name: "migration",
+    factory: () => new ManualMigration(),
+    title: "Manual migration wizard",
+    value: true
   }
 ])) {
   const pref = `feeds.${name}`;
   FEEDS_CONFIG.set(pref, factory);
   PREFS_CONFIG.set(pref, {title, value});
 }
 
 this.ActivityStream = class ActivityStream {
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/lib/ManualMigration.jsm
@@ -0,0 +1,89 @@
+/* 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;
+const {actionCreators: ac, actionTypes: at} = Cu.import("resource://activity-stream/common/Actions.jsm", {});
+const {Prefs} = Cu.import("resource://activity-stream/lib/ActivityStreamPrefs.jsm", {});
+const MIGRATION_ENDED_EVENT = "Migration:Ended";
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+
+XPCOMUtils.defineLazyModuleGetter(this, "MigrationUtils", "resource:///modules/MigrationUtils.jsm");
+
+this.ManualMigration = class ManualMigration {
+  constructor() {
+    Services.obs.addObserver(this, MIGRATION_ENDED_EVENT);
+    this._prefs = new Prefs();
+  }
+
+  uninit() {
+    Services.obs.removeObserver(this, MIGRATION_ENDED_EVENT);
+  }
+
+  isMigrationMessageExpired() {
+    let migrationLastShownDate = new Date(this._prefs.get("migrationLastShownDate") * 1000);
+    let today = new Date();
+    // Round down to midnight.
+    today = new Date(today.getFullYear(), today.getMonth(), today.getDate());
+
+    if (migrationLastShownDate < today) {
+      let migrationRemainingDays = this._prefs.get("migrationRemainingDays") - 1;
+
+      this._prefs.set("migrationRemainingDays", migrationRemainingDays);
+      // .valueOf returns a value that is too large to store so we need to divide by 1000.
+      this._prefs.set("migrationLastShownDate", today.valueOf() / 1000);
+
+      if (migrationRemainingDays <= 0) {
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+  /**
+   * While alreadyExpired is false the migration message is displayed and we also
+   * keep checking if we should expire it. Broadcast expiration to store.
+   *
+   * @param {bool} alreadyExpired Pref flag that is false for the first 3 active days,
+   *                              time in which we display the migration message to the user.
+   */
+  expireIfNecessary(alreadyExpired) {
+    if (!alreadyExpired && this.isMigrationMessageExpired()) {
+      this.expireMigration();
+    }
+  }
+
+  expireMigration() {
+    this.store.dispatch(ac.SetPref("migrationExpired", true));
+  }
+
+  /**
+   * Event listener for migration wizard completion event.
+   */
+  observe() {
+    this.expireMigration();
+  }
+
+  onAction(action) {
+    switch (action.type) {
+      case at.PREFS_INITIAL_VALUES:
+        this.expireIfNecessary(action.data.migrationExpired);
+        break;
+      case at.MIGRATION_START:
+        MigrationUtils.showMigrationWizard(action._target.browser.ownerGlobal, [MigrationUtils.MIGRATION_ENTRYPOINT_NEWTAB]);
+        break;
+      case at.MIGRATION_CANCEL:
+        this.expireMigration();
+        break;
+      case at.UNINIT:
+        this.uninit();
+        break;
+    }
+  }
+};
+
+this.EXPORTED_SYMBOLS = ["ManualMigration"];
--- a/browser/extensions/activity-stream/lib/TopStoriesFeed.jsm
+++ b/browser/extensions/activity-stream/lib/TopStoriesFeed.jsm
@@ -9,16 +9,17 @@ Cu.import("resource://gre/modules/Servic
 Cu.import("resource://gre/modules/NewTabUtils.jsm");
 Cu.importGlobalProperties(["fetch"]);
 
 const {actionCreators: ac, actionTypes: at} = Cu.import("resource://activity-stream/common/Actions.jsm", {});
 const {Prefs} = Cu.import("resource://activity-stream/lib/ActivityStreamPrefs.jsm", {});
 
 const STORIES_UPDATE_TIME = 30 * 60 * 1000; // 30 minutes
 const TOPICS_UPDATE_TIME = 3 * 60 * 60 * 1000; // 3 hours
+const STORIES_NOW_THRESHOLD = 24 * 60 * 60 * 1000; // 24 hours
 const SECTION_ID = "TopStories";
 
 this.TopStoriesFeed = class TopStoriesFeed {
   constructor() {
     this.storiesLastUpdated = 0;
     this.topicsLastUpdated = 0;
   }
 
@@ -33,27 +34,27 @@ this.TopStoriesFeed = class TopStoriesFe
 
       // TODO https://github.com/mozilla/activity-stream/issues/2902
       const sectionOptions = {
         id: SECTION_ID,
         icon: options.provider_icon,
         title: {id: "header_recommended_by", values: {provider: options.provider_name}},
         rows: [],
         maxCards: 3,
-        contextMenuOptions: ["SaveToPocket", "Separator", "CheckBookmark", "Separator", "OpenInNewWindow", "OpenInPrivateWindow", "Separator", "BlockUrl"],
+        contextMenuOptions: ["CheckBookmark", "SaveToPocket", "Separator", "OpenInNewWindow", "OpenInPrivateWindow", "Separator", "BlockUrl"],
         infoOption: {
           header: {id: "pocket_feedback_header"},
           body: {id: "pocket_feedback_body"},
           link: {
             href: options.survey_link,
             id: "pocket_send_feedback"
           }
         },
         emptyState: {
-          message: {id: "empty_state_topstories"},
+          message: {id: "topstories_empty_state", values: {provider: options.provider_name}},
           icon: "check"
         }
       };
       this.store.dispatch(ac.BroadcastToContent({type: at.SECTION_REGISTER, data: sectionOptions}));
 
       this.fetchStories();
       this.fetchTopics();
     } catch (e) {
@@ -72,25 +73,24 @@ this.TopStoriesFeed = class TopStoriesFe
           if (response.ok) {
             return response.text();
           }
           throw new Error(`Stories endpoint returned unexpected status: ${response.status}`);
         })
         .then(body => {
           let items = JSON.parse(body).list;
           items = items
-            .filter(s => !NewTabUtils.blockedLinks.isBlocked(s.dedupe_url))
+            .filter(s => !NewTabUtils.blockedLinks.isBlocked({"url": s.dedupe_url}))
             .map(s => ({
               "guid": s.id,
-              "type": "trending",
+              "type": (Date.now() - (s.published_timestamp * 1000)) <= STORIES_NOW_THRESHOLD ? "now" : "trending",
               "title": s.title,
               "description": s.excerpt,
               "image": this._normalizeUrl(s.image_src),
-              "url": s.dedupe_url,
-              "lastVisitDate": s.published_timestamp
+              "url": s.dedupe_url
             }));
           return items;
         })
         .catch(error => Cu.reportError(`Failed to fetch content: ${error.message}`));
 
       if (stories) {
         this.dispatchUpdateEvent(this.storiesLastUpdated,
           {"type": at.SECTION_ROWS_UPDATE, "data": {"id": SECTION_ID, "rows": stories}});
--- a/browser/extensions/activity-stream/test/.eslintrc.js
+++ b/browser/extensions/activity-stream/test/.eslintrc.js
@@ -3,10 +3,13 @@ module.exports = {
     "node": true,
     "es6": true,
     "mocha": true
   },
   "globals": {
     "assert": true,
     "sinon": true,
     "chai": true
+  },
+  "rules": {
+    "react/jsx-no-bind": 0
   }
 };
--- a/browser/extensions/activity-stream/test/unit/common/Reducers.test.js
+++ b/browser/extensions/activity-stream/test/unit/common/Reducers.test.js
@@ -246,16 +246,76 @@ describe("Reducers", () => {
       const blockAction = {type: at.PLACES_LINK_BLOCKED, data: {url: "www.foo.bar"}};
       const deleteAction = {type: at.PLACES_LINK_DELETED, data: {url: "www.foo.bar"}};
       const newBlockState = Sections(oldState, blockAction);
       const newDeleteState = Sections(oldState, deleteAction);
       newBlockState.concat(newDeleteState).forEach(section => {
         assert.deepEqual(section.rows, [{url: "www.other.url"}]);
       });
     });
+    it("should not update state for empty action.data on PLACES_BOOKMARK_ADDED", () => {
+      const nextState = Sections(undefined, {type: at.PLACES_BOOKMARK_ADDED});
+      assert.equal(nextState, INITIAL_STATE.Sections);
+    });
+    it("should bookmark an item when PLACES_BOOKMARK_ADDED is received", () => {
+      const action = {
+        type: at.PLACES_BOOKMARK_ADDED,
+        data: {
+          url: "www.foo.bar",
+          bookmarkGuid: "bookmark123",
+          bookmarkTitle: "Title for bar.com",
+          lastModified: 1234567
+        }
+      };
+      const nextState = Sections(oldState, action);
+      // check a section to ensure the correct url was bookmarked
+      const newRow = nextState[0].rows[0];
+      const oldRow = nextState[0].rows[1];
+
+      // new row has bookmark data
+      assert.equal(newRow.url, action.data.url);
+      assert.equal(newRow.bookmarkGuid, action.data.bookmarkGuid);
+      assert.equal(newRow.bookmarkTitle, action.data.bookmarkTitle);
+      assert.equal(newRow.bookmarkDateCreated, action.data.lastModified);
+
+      // old row is unchanged
+      assert.equal(oldRow, oldState[0].rows[1]);
+    });
+    it("should not update state for empty action.data on PLACES_BOOKMARK_REMOVED", () => {
+      const nextState = Sections(undefined, {type: at.PLACES_BOOKMARK_REMOVED});
+      assert.equal(nextState, INITIAL_STATE.Sections);
+    });
+    it("should remove the bookmark when PLACES_BOOKMARK_REMOVED is received", () => {
+      const action = {
+        type: at.PLACES_BOOKMARK_REMOVED,
+        data: {
+          url: "www.foo.bar",
+          bookmarkGuid: "bookmark123"
+        }
+      };
+      // add some bookmark data for the first url in rows
+      oldState.forEach(item => {
+        item.rows[0].bookmarkGuid = "bookmark123";
+        item.rows[0].bookmarkTitle = "Title for bar.com";
+        item.rows[0].bookmarkDateCreated = 1234567;
+      });
+      const nextState = Sections(oldState, action);
+      // check a section to ensure the correct bookmark was removed
+      const newRow = nextState[0].rows[0];
+      const oldRow = nextState[0].rows[1];
+
+      // new row has bookmark data
+      assert.equal(newRow.url, action.data.url);
+      assert.isUndefined(newRow.bookmarkGuid);
+      assert.isUndefined(newRow.bookmarkTitle);
+      assert.isUndefined(newRow.bookmarkDateCreated);
+
+      // old row is unchanged
+      assert.equal(oldRow, oldState[0].rows[1]);
+    });
   });
   describe("#insertPinned", () => {
     let links;
 
     beforeEach(() => {
       links =  new Array(12).fill(null).map((v, i) => ({url: `site${i}.com`}));
     });
 
--- a/browser/extensions/activity-stream/test/unit/lib/ActivityStream.test.js
+++ b/browser/extensions/activity-stream/test/unit/lib/ActivityStream.test.js
@@ -8,24 +8,25 @@ describe("ActivityStream", () => {
   let ActivityStream;
   let SECTIONS;
   function Fake() {}
 
   beforeEach(() => {
     sandbox = sinon.sandbox.create();
     ({ActivityStream, SECTIONS} = injector({
       "lib/LocalizationFeed.jsm": {LocalizationFeed: Fake},
+      "lib/ManualMigration.jsm": {ManualMigration: Fake},
       "lib/NewTabInit.jsm": {NewTabInit: Fake},
       "lib/PlacesFeed.jsm": {PlacesFeed: Fake},
+      "lib/PrefsFeed.jsm": {PrefsFeed: Fake},
+      "lib/SnippetsFeed.jsm": {SnippetsFeed: Fake},
+      "lib/SystemTickFeed.jsm": {SystemTickFeed: Fake},
       "lib/TelemetryFeed.jsm": {TelemetryFeed: Fake},
       "lib/TopSitesFeed.jsm": {TopSitesFeed: Fake},
-      "lib/PrefsFeed.jsm": {PrefsFeed: Fake},
-      "lib/SnippetsFeed.jsm": {SnippetsFeed: Fake},
-      "lib/TopStoriesFeed.jsm": {TopStoriesFeed: Fake},
-      "lib/SystemTickFeed.jsm": {SystemTickFeed: Fake}
+      "lib/TopStoriesFeed.jsm": {TopStoriesFeed: Fake}
     }));
     as = new ActivityStream();
     sandbox.stub(as.store, "init");
     sandbox.stub(as.store, "uninit");
     sandbox.stub(as._defaultPrefs, "init");
     sandbox.stub(as._defaultPrefs, "reset");
   });
 
@@ -113,16 +114,20 @@ describe("ActivityStream", () => {
     it("should create a section feed for each section in SECTIONS", () => {
       // If new sections are added, their feeds will have to be added to the
       // list of injected feeds above for this test to pass
       SECTIONS.forEach((value, key) => {
         const feed = as.feeds.get(`feeds.section.${key}`)();
         assert.instanceOf(feed, Fake);
       });
     });
+    it("should create a ManualMigration feed", () => {
+      const feed = as.feeds.get("feeds.migration")();
+      assert.instanceOf(feed, Fake);
+    });
     it("should create a Snippets feed", () => {
       const feed = as.feeds.get("feeds.snippets")();
       assert.instanceOf(feed, Fake);
     });
     it("should create a SystemTick feed", () => {
       const feed = as.feeds.get("feeds.systemtick")();
       assert.instanceOf(feed, Fake);
     });
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/test/unit/lib/ManualMigration.test.js
@@ -0,0 +1,207 @@
+const injector = require("inject!lib/ManualMigration.jsm");
+const {actionCreators: ac, actionTypes: at} = require("common/Actions.jsm");
+const {GlobalOverrider} = require("test/unit/utils");
+
+describe("ManualMigration", () => {
+  let dispatch;
+  let store;
+  let instance;
+  let globals;
+
+  let migrationWizardStub;
+  let fakeServices;
+  let fakePrefs;
+
+  beforeEach(() => {
+    migrationWizardStub = sinon.stub();
+    let fakeMigrationUtils = {
+      showMigrationWizard: migrationWizardStub,
+      MIGRATION_ENTRYPOINT_NEWTAB: "MIGRATION_ENTRYPOINT_NEWTAB"
+    };
+    fakeServices = {
+      obs: {
+        addObserver: sinon.stub(),
+        removeObserver: sinon.stub()
+      }
+    };
+    fakePrefs = function() {};
+    fakePrefs.get = sinon.stub();
+    fakePrefs.set = sinon.stub();
+
+    const {ManualMigration} = injector({"lib/ActivityStreamPrefs.jsm": {Prefs: fakePrefs}});
+
+    globals = new GlobalOverrider();
+    globals.set("Services", fakeServices);
+    globals.set("MigrationUtils", fakeMigrationUtils);
+
+    dispatch = sinon.stub();
+    store = {dispatch};
+    instance = new ManualMigration();
+    instance.store = store;
+  });
+
+  afterEach(() => {
+    globals.restore();
+  });
+
+  it("should set an event listener for Migration:Ended", () => {
+    assert.calledOnce(fakeServices.obs.addObserver);
+    assert.calledWith(fakeServices.obs.addObserver, instance, "Migration:Ended");
+  });
+
+  describe("onAction", () => {
+    it("should call expireIfNecessary on PREFS_INITIAL_VALUE", () => {
+      const action = {
+        type: at.PREFS_INITIAL_VALUES,
+        data: {migrationExpired: true}
+      };
+
+      const expireStub = sinon.stub(instance, "expireIfNecessary");
+      instance.onAction(action);
+
+      assert.calledOnce(expireStub);
+      assert.calledWithExactly(expireStub, action.data.migrationExpired);
+    });
+    it("should call launch the migration wizard on MIGRATION_START", () => {
+      const action = {
+        type: at.MIGRATION_START,
+        _target: {browser: {ownerGlobal: "browser.xul"}},
+        data: {migrationExpired: false}
+      };
+
+      instance.onAction(action);
+
+      assert.calledOnce(migrationWizardStub);
+      assert.calledWithExactly(migrationWizardStub, action._target.browser.ownerGlobal, ["MIGRATION_ENTRYPOINT_NEWTAB"]);
+    });
+    it("should set migrationStatus to true on MIGRATION_CANCEL", () => {
+      const action = {type: at.MIGRATION_CANCEL};
+
+      const setStatusStub = sinon.spy(instance, "expireMigration");
+      instance.onAction(action);
+
+      assert.calledOnce(setStatusStub);
+      assert.calledOnce(dispatch);
+      assert.calledWithExactly(dispatch, ac.SetPref("migrationExpired", true));
+    });
+    it("should set migrationStatus when isMigrationMessageExpired is true", () => {
+      const setStatusStub = sinon.stub(instance, "expireMigration");
+      const isExpiredStub = sinon.stub(instance, "isMigrationMessageExpired");
+      isExpiredStub.returns(true);
+
+      instance.expireIfNecessary(false);
+      assert.calledOnce(setStatusStub);
+    });
+    it("should call isMigrationMessageExpired if migrationExpired is false", () => {
+      const action = {
+        type: at.PREFS_INITIAL_VALUES,
+        data: {migrationExpired: false}
+      };
+
+      const stub = sinon.stub(instance, "isMigrationMessageExpired");
+      instance.onAction(action);
+
+      assert.calledOnce(stub);
+    });
+    describe("isMigrationMessageExpired", () => {
+      beforeEach(() => {
+        instance._prefs = fakePrefs;
+      });
+      it("should check migrationLastShownDate (case: today)", () => {
+        const action = {
+          type: at.PREFS_INITIAL_VALUES,
+          data: {migrationExpired: false}
+        };
+        let today = new Date();
+        today = new Date(today.getFullYear(), today.getMonth(), today.getDate());
+
+        const migrationSpy = sinon.spy(instance, "isMigrationMessageExpired");
+        fakePrefs.get.returns(today);
+        instance.onAction(action);
+
+        assert.calledOnce(migrationSpy);
+        assert.calledOnce(fakePrefs.get);
+        assert.calledWithExactly(fakePrefs.get, "migrationLastShownDate");
+      });
+      it("should return false if lastShownDate is today", () => {
+        let today = new Date();
+        today = new Date(today.getFullYear(), today.getMonth(), today.getDate());
+
+        const migrationSpy = sinon.spy(instance, "isMigrationMessageExpired");
+        fakePrefs.get.returns(today);
+        const ret = instance.isMigrationMessageExpired();
+
+        assert.calledOnce(migrationSpy);
+        assert.calledOnce(fakePrefs.get);
+        assert.equal(ret, false);
+      });
+      it("should check migrationLastShownDate (case: yesterday)", () => {
+        const action = {
+          type: at.PREFS_INITIAL_VALUES,
+          data: {migrationExpired: false}
+        };
+        let today = new Date();
+        let yesterday = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 1);
+
+        const migrationSpy = sinon.spy(instance, "isMigrationMessageExpired");
+        fakePrefs.get.withArgs("migrationLastShownDate").returns(yesterday.valueOf() / 1000);
+        fakePrefs.get.withArgs("migrationRemainingDays").returns(4);
+        instance.onAction(action);
+
+        assert.calledOnce(migrationSpy);
+        assert.calledTwice(fakePrefs.get);
+        assert.calledWithExactly(fakePrefs.get, "migrationLastShownDate");
+        assert.calledWithExactly(fakePrefs.get, "migrationRemainingDays");
+      });
+      it("should update the migration prefs", () => {
+        const action = {
+          type: at.PREFS_INITIAL_VALUES,
+          data: {migrationExpired: false}
+        };
+        let today = new Date();
+        let yesterday = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 1);
+        today = new Date(today.getFullYear(), today.getMonth(), today.getDate());
+
+        const migrationSpy = sinon.spy(instance, "isMigrationMessageExpired");
+        fakePrefs.get.withArgs("migrationLastShownDate").returns(yesterday.valueOf() / 1000);
+        fakePrefs.get.withArgs("migrationRemainingDays").returns(4);
+        instance.onAction(action);
+
+        assert.calledOnce(migrationSpy);
+        assert.calledTwice(fakePrefs.set);
+        assert.calledWithExactly(fakePrefs.set, "migrationRemainingDays", 3);
+        assert.calledWithExactly(fakePrefs.set, "migrationLastShownDate", today.valueOf() / 1000);
+      });
+      it("should return true if remainingDays reaches 0", () => {
+        let today = new Date();
+        let yesterday = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 1);
+
+        const migrationSpy = sinon.spy(instance, "isMigrationMessageExpired");
+        fakePrefs.get.withArgs("migrationLastShownDate").returns(yesterday.valueOf() / 1000);
+        fakePrefs.get.withArgs("migrationRemainingDays").returns(1);
+        const ret = instance.isMigrationMessageExpired();
+
+        assert.calledOnce(migrationSpy);
+        assert.calledTwice(fakePrefs.set);
+        assert.calledWithExactly(fakePrefs.set, "migrationRemainingDays", 0);
+        assert.equal(ret, true);
+      });
+    });
+  });
+  it("should have observe as a proxy for setMigrationStatus", () => {
+    const setStatusStub = sinon.stub(instance, "expireMigration");
+    instance.observe();
+
+    assert.calledOnce(setStatusStub);
+  });
+  it("should remove observer at uninit", () => {
+    const uninitSpy = sinon.spy(instance, "uninit");
+    const action = {type: at.UNINIT};
+
+    instance.onAction(action);
+
+    assert.calledOnce(uninitSpy);
+    assert.calledOnce(fakeServices.obs.removeObserver);
+    assert.calledWith(fakeServices.obs.removeObserver, instance, "Migration:Ended");
+  });
+});
--- a/browser/extensions/activity-stream/test/unit/lib/TopStoriesFeed.test.js
+++ b/browser/extensions/activity-stream/test/unit/lib/TopStoriesFeed.test.js
@@ -46,27 +46,27 @@ describe("Top Stories Feed", () => {
     });
     it("should register section", () => {
       const expectedSectionOptions = {
         id: SECTION_ID,
         icon: "provider-icon",
         title: {id: "header_recommended_by", values: {provider: "test-provider"}},
         rows: [],
         maxCards: 3,
-        contextMenuOptions: ["SaveToPocket", "Separator", "CheckBookmark", "Separator", "OpenInNewWindow", "OpenInPrivateWindow", "Separator", "BlockUrl"],
+        contextMenuOptions: ["CheckBookmark", "SaveToPocket", "Separator", "OpenInNewWindow", "OpenInPrivateWindow", "Separator", "BlockUrl"],
         infoOption: {
           header: {id: "pocket_feedback_header"},
           body: {id: "pocket_feedback_body"},
           link: {
             href: "https://www.surveymonkey.com/r/newtabffx",
             id: "pocket_send_feedback"
           }
         },
         emptyState: {
-          message: {id: "empty_state_topstories"},
+          message: {id: "topstories_empty_state", values: {provider: "test-provider"}},
           icon: "check"
         }
       };
 
       instance.onAction({type: at.INIT});
       assert.calledOnce(instance.store.dispatch);
       assert.propertyVal(instance.store.dispatch.firstCall.args[0], "type", at.SECTION_REGISTER);
       assert.calledWith(instance.store.dispatch, ac.BroadcastToContent({
@@ -136,22 +136,21 @@ describe("Top Stories Feed", () => {
         "title": "title",
         "excerpt": "description",
         "image_src": "image-url",
         "dedupe_url": "rec-url",
         "published_timestamp" : "123"
       }]}`;
       const stories = [{
         "guid": "1",
-        "type": "trending",
+        "type": "now",
         "title": "title",
         "description": "description",
         "image": "image-url",
-        "url": "rec-url",
-        "lastVisitDate": "123"
+        "url": "rec-url"
       }];
 
       instance.stories_endpoint = "stories-endpoint";
       fetchStub.resolves({ok: true, status: 200, text: () => response});
       await instance.fetchStories();
 
       assert.calledOnce(fetchStub);
       assert.calledWithExactly(fetchStub, instance.stories_endpoint);
@@ -176,28 +175,52 @@ describe("Top Stories Feed", () => {
       assert.calledOnce(fetchStub);
       assert.calledWithExactly(fetchStub, instance.stories_endpoint);
       assert.notCalled(instance.store.dispatch);
       assert.called(Components.utils.reportError);
     });
     it("should exclude blocked (dismissed) URLs", async () => {
       let fetchStub = globals.sandbox.stub();
       globals.set("fetch", fetchStub);
-      globals.set("NewTabUtils", {blockedLinks: {isBlocked: url => url === "blocked"}});
+      globals.set("NewTabUtils", {blockedLinks: {isBlocked: site => site.url === "blocked"}});
 
       const response = `{"list": [{"dedupe_url" : "blocked"}, {"dedupe_url" : "not_blocked"}]}`;
       instance.stories_endpoint = "stories-endpoint";
       fetchStub.resolves({ok: true, status: 200, text: () => response});
       await instance.fetchStories();
 
       assert.calledOnce(instance.store.dispatch);
       assert.propertyVal(instance.store.dispatch.firstCall.args[0], "type", at.SECTION_ROWS_UPDATE);
       assert.equal(instance.store.dispatch.firstCall.args[0].data.rows.length, 1);
       assert.equal(instance.store.dispatch.firstCall.args[0].data.rows[0].url, "not_blocked");
     });
+    it("should mark stories as new", async () => {
+      let fetchStub = globals.sandbox.stub();
+      globals.set("fetch", fetchStub);
+      globals.set("NewTabUtils", {blockedLinks: {isBlocked: globals.sandbox.spy()}});
+      clock.restore();
+      const response = JSON.stringify({
+        "list": [
+          {"published_timestamp": Date.now() / 1000},
+          {"published_timestamp": "0"},
+          {"published_timestamp": (Date.now() - 2 * 24 * 60 * 60 * 1000) / 1000}
+        ]
+      });
+
+      instance.stories_endpoint = "stories-endpoint";
+      fetchStub.resolves({ok: true, status: 200, text: () => response});
+
+      await instance.fetchStories();
+      assert.calledOnce(instance.store.dispatch);
+      assert.propertyVal(instance.store.dispatch.firstCall.args[0], "type", at.SECTION_ROWS_UPDATE);
+      assert.equal(instance.store.dispatch.firstCall.args[0].data.rows.length, 3);
+      assert.equal(instance.store.dispatch.firstCall.args[0].data.rows[0].type, "now");
+      assert.equal(instance.store.dispatch.firstCall.args[0].data.rows[1].type, "trending");
+      assert.equal(instance.store.dispatch.firstCall.args[0].data.rows[2].type, "trending");
+    });
     it("should fetch topics and send event", async () => {
       let fetchStub = globals.sandbox.stub();
       globals.set("fetch", fetchStub);
 
       const response = `{"topics": [{"name" : "topic1", "url" : "url-topic1"}, {"name" : "topic2", "url" : "url-topic2"}]}`;
       const topics = [{
         "name": "topic1",
         "url": "url-topic1"
--- a/browser/extensions/e10srollout/bootstrap.js
+++ b/browser/extensions/e10srollout/bootstrap.js
@@ -69,16 +69,17 @@ const PREF_E10S_OPTED_IN       = "browse
 const PREF_E10S_FORCE_ENABLED  = "browser.tabs.remote.force-enable";
 const PREF_E10S_FORCE_DISABLED = "browser.tabs.remote.force-disable";
 const PREF_TOGGLE_E10S         = "browser.tabs.remote.autostart.2";
 const PREF_E10S_ADDON_POLICY   = "extensions.e10s.rollout.policy";
 const PREF_E10S_ADDON_BLOCKLIST = "extensions.e10s.rollout.blocklist";
 const PREF_E10S_HAS_NONEXEMPT_ADDON = "extensions.e10s.rollout.hasAddon";
 const PREF_E10S_MULTI_OPTOUT   = "dom.ipc.multiOptOut";
 const PREF_E10S_PROCESSCOUNT   = "dom.ipc.processCount";
+const PREF_USE_DEFAULT_PERF_SETTINGS = "browser.preferences.defaultPerformanceSettings.enabled";
 const PREF_E10S_MULTI_ADDON_BLOCKS = "extensions.e10sMultiBlocksEnabling";
 const PREF_E10S_MULTI_BLOCKED_BY_ADDONS = "extensions.e10sMultiBlockedByAddons";
 
 function startup() {
   // In theory we only need to run this once (on install()), but
   // it's better to also run it on every startup. If the user has
   // made manual changes to the prefs, this will keep the data
   // reported more accurate.
@@ -254,17 +255,18 @@ function setCohort(cohortName) {
       Services.appinfo.QueryInterface(Ci.nsICrashReporter).annotateCrashReport("E10SCohort", cohortName);
     }
   } catch (e) {}
 }
 
 function optedIn() {
   let e10s = Preferences.get(PREF_E10S_OPTED_IN, false) ||
              Preferences.get(PREF_E10S_FORCE_ENABLED, false);
-  let multi = Preferences.isSet(PREF_E10S_PROCESSCOUNT);
+  let multi = Preferences.isSet(PREF_E10S_PROCESSCOUNT) ||
+             !Preferences.get(PREF_USE_DEFAULT_PERF_SETTINGS, true);
   return { e10s, multi };
 }
 
 function optedOut() {
   // Users can also opt-out by toggling back the pref to false.
   // If they reset the pref instead they might be re-enabled if
   // they are still part of the threshold.
   let e10s = Preferences.get(PREF_E10S_FORCE_DISABLED, false) ||
--- a/browser/extensions/formautofill/FormAutofillContent.jsm
+++ b/browser/extensions/formautofill/FormAutofillContent.jsm
@@ -14,17 +14,19 @@ this.EXPORTED_SYMBOLS = ["FormAutofillCo
 
 const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr, manager: Cm} = Components;
 
 Cu.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://formautofill/FormAutofillUtils.jsm");
 
-XPCOMUtils.defineLazyModuleGetter(this, "ProfileAutoCompleteResult",
+XPCOMUtils.defineLazyModuleGetter(this, "AddressResult",
+                                  "resource://formautofill/ProfileAutoCompleteResult.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "CreditCardResult",
                                   "resource://formautofill/ProfileAutoCompleteResult.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "FormAutofillHandler",
                                   "resource://formautofill/FormAutofillHandler.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "FormLikeFactory",
                                   "resource://gre/modules/FormLikeFactory.jsm");
 
 const formFillController = Cc["@mozilla.org/satchel/form-fill-controller;1"]
                              .getService(Ci.nsIFormFillController);
@@ -114,22 +116,30 @@ AutofillProfileAutoCompleteSearch.protot
       }
       // Sort addresses by timeLastUsed for showing the lastest used address at top.
       records.sort((a, b) => b.timeLastUsed - a.timeLastUsed);
 
       let handler = FormAutofillContent.getFormHandler(focusedInput);
       let adaptedRecords = handler.getAdaptedProfiles(records);
 
       let allFieldNames = FormAutofillContent.getAllFieldNames(focusedInput);
-      let result = new ProfileAutoCompleteResult(searchString,
-                                                 info.fieldName,
-                                                 allFieldNames,
-                                                 adaptedRecords,
-                                                 {});
-
+      let result = null;
+      if (collectionName == "addresses") {
+        result = new AddressResult(searchString,
+                                   info.fieldName,
+                                   allFieldNames,
+                                   adaptedRecords,
+                                   {});
+      } else {
+        result = new CreditCardResult(searchString,
+                                      info.fieldName,
+                                      allFieldNames,
+                                      adaptedRecords,
+                                      {});
+      }
       listener.onSearchResult(this, result);
       ProfileAutocomplete.setProfileAutoCompleteResult(result);
     });
   },
 
   /**
    * Stops an asynchronous search that is in progress
    */
--- a/browser/extensions/formautofill/ProfileAutoCompleteResult.jsm
+++ b/browser/extensions/formautofill/ProfileAutoCompleteResult.jsm
@@ -1,105 +1,171 @@
 /* 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";
 
-this.EXPORTED_SYMBOLS = ["ProfileAutoCompleteResult"];
+this.EXPORTED_SYMBOLS = ["AddressResult", "CreditCardResult"]; /* exported AddressResult, CreditCardResult */
 
 const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://formautofill/FormAutofillUtils.jsm");
 
 this.log = null;
 FormAutofillUtils.defineLazyLogGetter(this, this.EXPORTED_SYMBOLS[0]);
 
+class ProfileAutoCompleteResult {
+  constructor(searchString, focusedFieldName, allFieldNames, matchingProfiles, {resultCode = null}) {
+    log.debug("Constructing new ProfileAutoCompleteResult:", [...arguments]);
 
-this.ProfileAutoCompleteResult = function(searchString,
-                                          focusedFieldName,
-                                          allFieldNames,
-                                          matchingProfiles,
-                                          {resultCode = null}) {
-  log.debug("Constructing new ProfileAutoCompleteResult:", [...arguments]);
-  this.searchString = searchString;
-  this._focusedFieldName = focusedFieldName;
-  this._allFieldNames = allFieldNames;
-  this._matchingProfiles = matchingProfiles;
-
-  if (resultCode) {
-    this.searchResult = resultCode;
-  } else if (matchingProfiles.length > 0) {
-    this.searchResult = Ci.nsIAutoCompleteResult.RESULT_SUCCESS;
-  } else {
-    this.searchResult = Ci.nsIAutoCompleteResult.RESULT_NOMATCH;
-  }
+    // nsISupports
+    this.QueryInterface = XPCOMUtils.generateQI([Ci.nsIAutoCompleteResult]);
 
-  this._popupLabels = this._generateLabels(this._focusedFieldName,
-                                           this._allFieldNames,
-                                           this._matchingProfiles);
-  // Add an empty result entry for footer. Its content will come from
-  // the footer binding, so don't assign any value to it.
-  this._popupLabels.push({
-    primary: "",
-    secondary: "",
-    categories: FormAutofillUtils.getCategoriesFromFieldNames(allFieldNames),
-    focusedCategory: FormAutofillUtils.getCategoryFromFieldName(focusedFieldName),
-  });
-};
-
-ProfileAutoCompleteResult.prototype = {
-
-  // The user's query string
-  searchString: "",
+    // The user's query string
+    this.searchString = searchString;
+    // The field name of the focused input.
+    this._focusedFieldName = focusedFieldName;
+    // All field names in the form which contains the focused input.
+    this._allFieldNames = allFieldNames;
+    // The matching profiles contains the information for filling forms.
+    this._matchingProfiles = matchingProfiles;
+    // The default item that should be entered if none is selected
+    this.defaultIndex = 0;
+    // The reason the search failed
+    this.errorDescription = "";
 
-  // The default item that should be entered if none is selected
-  defaultIndex: 0,
-
-  // The reason the search failed
-  errorDescription: "",
-
-  // The result code of this result object.
-  searchResult: null,
+    // The result code of this result object.
+    if (resultCode) {
+      this.searchResult = resultCode;
+    } else if (matchingProfiles.length > 0) {
+      this.searchResult = Ci.nsIAutoCompleteResult.RESULT_SUCCESS;
+    } else {
+      this.searchResult = Ci.nsIAutoCompleteResult.RESULT_NOMATCH;
+    }
 
-  // The field name of the focused input.
-  _focusedFieldName: "",
-
-  // All field names in the form which contains the focused input.
-  _allFieldNames: null,
-
-  // The matching profiles contains the information for filling forms.
-  _matchingProfiles: null,
-
-  // An array of primary and secondary labels for each profiles.
-  _popupLabels: null,
+    // An array of primary and secondary labels for each profile.
+    this._popupLabels = this._generateLabels(this._focusedFieldName,
+                                             this._allFieldNames,
+                                             this._matchingProfiles);
+  }
 
   /**
    * @returns {number} The number of results
    */
   get matchCount() {
     return this._popupLabels.length;
-  },
+  }
 
   _checkIndexBounds(index) {
     if (index < 0 || index >= this._popupLabels.length) {
       throw Components.Exception("Index out of range.", Cr.NS_ERROR_ILLEGAL_VALUE);
     }
-  },
+  }
 
   /**
    * Get the secondary label based on the focused field name and related field names
    * in the same form.
    * @param   {string} focusedFieldName The field name of the focused input
    * @param   {Array<Object>} allFieldNames The field names in the same section
    * @param   {object} profile The profile providing the labels to show.
    * @returns {string} The secondary label
    */
   _getSecondaryLabel(focusedFieldName, allFieldNames, profile) {
+    return "";
+  }
+
+  _generateLabels(focusedFieldName, allFieldNames, profiles) {}
+
+  /**
+   * Retrieves a result
+   * @param   {number} index The index of the result requested
+   * @returns {string} The result at the specified index
+   */
+  getValueAt(index) {
+    this._checkIndexBounds(index);
+    return this._popupLabels[index].primary;
+  }
+
+  getLabelAt(index) {
+    this._checkIndexBounds(index);
+    return JSON.stringify(this._popupLabels[index]);
+  }
+
+  /**
+   * Retrieves a comment (metadata instance)
+   * @param   {number} index The index of the comment requested
+   * @returns {string} The comment at the specified index
+   */
+  getCommentAt(index) {
+    this._checkIndexBounds(index);
+    return JSON.stringify(this._matchingProfiles[index]);
+  }
+
+  /**
+   * Retrieves a style hint specific to a particular index.
+   * @param   {number} index The index of the style hint requested
+   * @returns {string} The style hint at the specified index
+   */
+  getStyleAt(index) {
+    this._checkIndexBounds(index);
+    if (index == this.matchCount - 1) {
+      return "autofill-footer";
+    }
+    return "autofill-profile";
+  }
+
+  /**
+   * Retrieves an image url.
+   * @param   {number} index The index of the image url requested
+   * @returns {string} The image url at the specified index
+   */
+  getImageAt(index) {
+    this._checkIndexBounds(index);
+    return "";
+  }
+
+  /**
+   * Retrieves a result
+   * @param   {number} index The index of the result requested
+   * @returns {string} The result at the specified index
+   */
+  getFinalCompleteValueAt(index) {
+    return this.getValueAt(index);
+  }
+
+  /**
+   * Removes a result from the resultset
+   * @param {number} index The index of the result to remove
+   * @param {boolean} removeFromDatabase TRUE for removing data from DataBase
+   *                                     as well.
+   */
+  removeValueAt(index, removeFromDatabase) {
+    // There is no plan to support removing profiles via autocomplete.
+  }
+}
+
+class AddressResult extends ProfileAutoCompleteResult {
+  constructor(...args) {
+    super(...args);
+
+    // Add an empty result entry for footer. Its content will come from
+    // the footer binding, so don't assign any value to it.
+    // The additional properties: categories and focusedCategory are required of
+    // the popup to generate autofill hint on the footer.
+    this._popupLabels.push({
+      primary: "",
+      secondary: "",
+      categories: FormAutofillUtils.getCategoriesFromFieldNames(this._allFieldNames),
+      focusedCategory: FormAutofillUtils.getCategoryFromFieldName(this._focusedFieldName),
+    });
+  }
+
+  _getSecondaryLabel(focusedFieldName, allFieldNames, profile) {
     // We group similar fields into the same field name so we won't pick another
     // field in the same group as the secondary label.
     const GROUP_FIELDS = {
       "name": [
         "name",
         "given-name",
         "additional-name",
         "family-name",
@@ -149,17 +215,17 @@ ProfileAutoCompleteResult.prototype = {
             profile["-moz-street-address-one-line"]) {
           return profile["-moz-street-address-one-line"];
         }
         return profile[currentFieldName];
       }
     }
 
     return ""; // Nothing matched.
-  },
+  }
 
   _generateLabels(focusedFieldName, allFieldNames, profiles) {
     // Skip results without a primary label.
     return profiles.filter(profile => {
       return !!profile[focusedFieldName];
     }).map(profile => {
       let primaryLabel = profile[focusedFieldName];
       if (focusedFieldName == "street-address" &&
@@ -168,80 +234,88 @@ ProfileAutoCompleteResult.prototype = {
       }
       return {
         primary: primaryLabel,
         secondary: this._getSecondaryLabel(focusedFieldName,
                                            allFieldNames,
                                            profile),
       };
     });
-  },
+  }
+
+
+}
+
+class CreditCardResult extends ProfileAutoCompleteResult {
+  constructor(...args) {
+    super(...args);
+
+    // Add an empty result entry for footer.
+    this._popupLabels.push({primary: "", secondary: ""});
+  }
+
+  _getSecondaryLabel(focusedFieldName, allFieldNames, profile) {
+    const GROUP_FIELDS = {
+      "cc-name": [
+        "cc-name",
+        "cc-given-name",
+        "cc-additional-name",
+        "cc-family-name",
+      ],
+      "cc-exp": [
+        "cc-exp",
+        "cc-exp-month",
+        "cc-exp-year",
+      ],
+    };
+
+    const secondaryLabelOrder = [
+      "cc-number",       // Credit card number
+      "cc-name",         // Full name
+      "cc-exp",          // Expiration date
+    ];
 
-  /**
-   * Retrieves a result
-   * @param   {number} index The index of the result requested
-   * @returns {string} The result at the specified index
-   */
+    for (let field in GROUP_FIELDS) {
+      if (GROUP_FIELDS[field].includes(focusedFieldName)) {
+        focusedFieldName = field;
+        break;
+      }
+    }
+
+    for (const currentFieldName of secondaryLabelOrder) {
+      if (focusedFieldName == currentFieldName || !profile[currentFieldName]) {
+        continue;
+      }
+
+      let matching = GROUP_FIELDS[currentFieldName] ?
+        allFieldNames.some(fieldName => GROUP_FIELDS[currentFieldName].includes(fieldName)) :
+        allFieldNames.includes(currentFieldName);
+
+      if (matching) {
+        return profile[currentFieldName];
+      }
+    }
+
+    return ""; // Nothing matched.
+  }
+
+  _generateLabels(focusedFieldName, allFieldNames, profiles) {
+    // Skip results without a primary label.
+    return profiles.filter(profile => {
+      return !!profile[focusedFieldName];
+    }).map(profile => {
+      return {
+        primary: profile[focusedFieldName],
+        secondary: this._getSecondaryLabel(focusedFieldName,
+                                           allFieldNames,
+                                           profile),
+      };
+    });
+  }
+
+  // Always return empty string for credit card result. Since the decryption might
+  // be required of users' input, we have to to suppress AutoCompleteController
+  // from filling encrypted data directly.
   getValueAt(index) {
     this._checkIndexBounds(index);
-    return this._popupLabels[index].primary;
-  },
-
-  getLabelAt(index) {
-    this._checkIndexBounds(index);
-    return JSON.stringify(this._popupLabels[index]);
-  },
-
-  /**
-   * Retrieves a comment (metadata instance)
-   * @param   {number} index The index of the comment requested
-   * @returns {string} The comment at the specified index
-   */
-  getCommentAt(index) {
-    this._checkIndexBounds(index);
-    return JSON.stringify(this._matchingProfiles[index]);
-  },
-
-  /**
-   * Retrieves a style hint specific to a particular index.
-   * @param   {number} index The index of the style hint requested
-   * @returns {string} The style hint at the specified index
-   */
-  getStyleAt(index) {
-    this._checkIndexBounds(index);
-    if (index == this.matchCount - 1) {
-      return "autofill-footer";
-    }
-    return "autofill-profile";
-  },
-
-  /**
-   * Retrieves an image url.
-   * @param   {number} index The index of the image url requested
-   * @returns {string} The image url at the specified index
-   */
-  getImageAt(index) {
-    this._checkIndexBounds(index);
     return "";
-  },
-
-  /**
-   * Retrieves a result
-   * @param   {number} index The index of the result requested
-   * @returns {string} The result at the specified index
-   */
-  getFinalCompleteValueAt(index) {
-    return this.getValueAt(index);
-  },
-
-  /**
-   * Removes a result from the resultset
-   * @param {number} index The index of the result to remove
-   * @param {boolean} removeFromDatabase TRUE for removing data from DataBase
-   *                                     as well.
-   */
-  removeValueAt(index, removeFromDatabase) {
-    // There is no plan to support removing profiles via autocomplete.
-  },
-
-  // nsISupports
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIAutoCompleteResult]),
-};
+  }
+}
--- a/browser/extensions/formautofill/ProfileStorage.jsm
+++ b/browser/extensions/formautofill/ProfileStorage.jsm
@@ -53,18 +53,18 @@
  *   ],
  *   creditCards: [
  *     {
  *       guid,                 // 12 characters
  *       version,              // schema version in integer
  *
  *       // credit card fields
  *       cc-name,
+ *       cc-number,            // e.g. ************1234
  *       cc-number-encrypted,
- *       cc-number-masked,     // e.g. ************1234
  *       cc-exp-month,
  *       cc-exp-year,          // 2-digit year will be converted to 4 digits
  *                             // upon saving
  *
  *       // computed fields (These fields are computed based on the above fields
  *       // and are not allowed to be modified directly.)
  *       cc-given-name,
  *       cc-additional-name,
@@ -173,18 +173,18 @@ const TEL_COMPONENTS = [
 
 const VALID_ADDRESS_COMPUTED_FIELDS = [
   "name",
   "country-name",
 ].concat(STREET_ADDRESS_COMPONENTS, TEL_COMPONENTS);
 
 const VALID_CREDIT_CARD_FIELDS = [
   "cc-name",
+  "cc-number",
   "cc-number-encrypted",
-  "cc-number-masked",
   "cc-exp-month",
   "cc-exp-year",
 ];
 
 const VALID_CREDIT_CARD_COMPUTED_FIELDS = [
   "cc-given-name",
   "cc-additional-name",
   "cc-family-name",
@@ -1458,34 +1458,33 @@ class CreditCards extends AutofillRecord
     }
 
     return hasNewComputedFields;
   }
 
   _normalizeFields(creditCard) {
     // Fields that should not be set by content.
     delete creditCard["cc-number-encrypted"];
-    delete creditCard["cc-number-masked"];
 
     // Validate and encrypt credit card numbers, and calculate the masked numbers
     if (creditCard["cc-number"]) {
       let ccNumber = creditCard["cc-number"].replace(/\s/g, "");
       delete creditCard["cc-number"];
 
       if (!/^\d+$/.test(ccNumber)) {
         throw new Error("Credit card number contains invalid characters.");
       }
 
       // TODO: Encrypt cc-number here (bug 1337314).
       // e.g. creditCard["cc-number-encrypted"] = Encrypt(creditCard["cc-number"]);
 
       if (ccNumber.length > 4) {
-        creditCard["cc-number-masked"] = "*".repeat(ccNumber.length - 4) + ccNumber.substr(-4);
+        creditCard["cc-number"] = "*".repeat(ccNumber.length - 4) + ccNumber.substr(-4);
       } else {
-        creditCard["cc-number-masked"] = ccNumber;
+        creditCard["cc-number"] = ccNumber;
       }
     }
 
     // Normalize name
     if (creditCard["cc-given-name"] || creditCard["cc-additional-name"] || creditCard["cc-family-name"]) {
       if (!creditCard["cc-name"]) {
         creditCard["cc-name"] = FormAutofillNameUtils.joinNameParts({
           given: creditCard["cc-given-name"],
--- a/browser/extensions/formautofill/content/formautofill.xml
+++ b/browser/extensions/formautofill/content/formautofill.xml
@@ -164,36 +164,34 @@
           );
           this._optionButton = document.getAnonymousElementByAttribute(
             this, "anonid", "autofill-option-button"
           );
           this._warningTextBox = document.getAnonymousElementByAttribute(
             this, "anonid", "autofill-warning"
           );
 
-          let {categories: allFieldCategories, focusedCategory} = JSON.parse(this.getAttribute("ac-value"));
-
           /**
            * Update the text on the footer.
            *
            * @private
            * @param {string|string[]} categories
            *        A list of categories that used to generate the message.
            * @param {boolean} hasExtraCategories
            *        Used to determine if it has the extra categories other than the focued category. If
            *        the value is true, we show "Also fill ...", otherwise, show "Fill ..." only.
            */
-          this._updateText = (categories = allFieldCategories, hasExtraCategories = true) => {
+          this._updateText = (categories = this._allFieldCategories, hasExtraCategories = true) => {
             let warningTextTmplKey = hasExtraCategories ? "phishingWarningMessage" : "phishingWarningMessage2";
             let sep = this._stringBundle.GetStringFromName("fieldNameSeparator");
             // Show the categories in certain order to conform with the spec.
             let orderedCategoryList = ["address", "name", "organization", "tel", "email"];
             let showCategories = hasExtraCategories ?
-              orderedCategoryList.filter(category => categories.includes(category) && category != focusedCategory) :
-              [focusedCategory];
+              orderedCategoryList.filter(category => categories.includes(category) && category != this._focusedCategory) :
+              [this._focusedCategory];
             let categoriesText = showCategories.map(this._stringBundle.GetStringFromName).join(sep);
 
             this._warningTextBox.textContent = this._stringBundle.formatStringFromName(warningTextTmplKey,
               [categoriesText], 1);
             this.parentNode.parentNode.adjustHeight();
           };
 
           /**
@@ -205,39 +203,42 @@
            * 3. An address was selected, but the focused category is the same as the only all categories: Only show
            * the exact category that we're going to fill in.
            *
            * @private
            * @param {string[]} categories
            *        The categories of all the fields contained in the selected address.
            */
           this._updateWarningMsgHandler = ({data: {categories}} = {data: {}}) => {
-            let hasSelectedAddress = focusedCategory && categories;
+            let hasSelectedAddress = this._focusedCategory && categories;
             // If the length of categories is 1, that means all the fillable fields are in the same
             // category. We will change the way to inform user according to this flag.
             let hasExtraCategories = hasSelectedAddress && categories.length > 1;
             if (!hasSelectedAddress) {
               this._updateText();
               return;
             }
 
             this._updateText(categories, hasExtraCategories);
           };
 
           this._adjustAcItem();
-          this._updateText();
         ]]>
       </constructor>
 
       <method name="_onCollapse">
         <body>
         <![CDATA[
           /* global messageManager */
 
-          messageManager.removeMessageListener("FormAutofill:UpdateWarningMessage", this._updateWarningMsgHandler);
+          if (this.showWarningText) {
+            messageManager.removeMessageListener("FormAutofill:UpdateWarningMessage", this._updateWarningMsgHandler);
+          }
+
+          this._itemBox.removeAttribute("no-warning");
         ]]>
         </body>
       </method>
 
       <method name="_adjustAcItem">
         <body>
         <![CDATA[
           /* global Cu */
@@ -250,16 +251,28 @@
           // If the popup shows up with small layout, we should use short string to
           // have a better fit in the box.
           if (this._itemBox.getAttribute("size") == "small") {
             buttonTextBundleKey += "Short";
           }
           let buttonText = this._stringBundle.GetStringFromName(buttonTextBundleKey);
           this._optionButton.textContent = buttonText;
 
-          messageManager.addMessageListener("FormAutofill:UpdateWarningMessage", this._updateWarningMsgHandler);
+          let value = JSON.parse(this.getAttribute("ac-value"));
+
+          this._allFieldCategories = value.categories;
+          this._focusedCategory = value.focusedCategory;
+          this.showWarningText = this._allFieldCategories && this._focusedCategory;
+
+          if (this.showWarningText) {
+            messageManager.addMessageListener("FormAutofill:UpdateWarningMessage", this._updateWarningMsgHandler);
+
+            this._updateText();
+          } else {
+            this._itemBox.setAttribute("no-warning", "true");
+          }
         ]]>
         </body>
       </method>
     </implementation>
   </binding>
 
 </bindings>
--- a/browser/extensions/formautofill/skin/shared/autocomplete-item.css
+++ b/browser/extensions/formautofill/skin/shared/autocomplete-item.css
@@ -100,8 +100,12 @@ xul|richlistitem[originaltype="autofill-
   background-color: rgba(248,232,28,.2);
   border-bottom: 1px solid rgba(38,38,38,.15);
 }
 
 .autofill-footer > .autofill-option-button {
   height: 41px;
   background-color: #EDEDED;
 }
+
+.autofill-footer[no-warning="true"] > .autofill-warning {
+  display: none;
+}
--- a/browser/extensions/formautofill/test/unit/test_creditCardRecords.js
+++ b/browser/extensions/formautofill/test/unit/test_creditCardRecords.js
@@ -68,23 +68,21 @@ let prepareTestCreditCards = async funct
   await profileStorage._saveImmediately();
 };
 
 let reCCNumber = /^(\*+)(.{4})$/;
 
 let do_check_credit_card_matches = (creditCardWithMeta, creditCard) => {
   for (let key in creditCard) {
     if (key == "cc-number") {
-      do_check_eq(creditCardWithMeta["cc-number"], undefined);
-
       // check "cc-number-encrypted" after encryption lands (bug 1337314).
 
-      let matches = reCCNumber.exec(creditCardWithMeta["cc-number-masked"]);
+      let matches = reCCNumber.exec(creditCardWithMeta["cc-number"]);
       do_check_neq(matches, null);
-      do_check_eq(creditCardWithMeta["cc-number-masked"].length, creditCard["cc-number"].length);
+      do_check_eq(creditCardWithMeta["cc-number"].length, creditCard["cc-number"].length);
       do_check_eq(creditCard["cc-number"].endsWith(matches[2]), true);
     } else {
       do_check_eq(creditCardWithMeta[key], creditCard[key]);
     }
   }
 };
 
 add_task(async function test_initialize() {
@@ -251,17 +249,17 @@ add_task(async function test_validate() 
 
   do_check_eq(creditCards[0]["cc-exp-month"], undefined);
   do_check_eq(creditCards[0]["cc-exp-year"], undefined);
 
   do_check_eq(creditCards[1]["cc-exp-month"], TEST_CREDIT_CARD_WITH_2_DIGITS_YEAR["cc-exp-month"]);
   do_check_eq(creditCards[1]["cc-exp-year"],
     parseInt(TEST_CREDIT_CARD_WITH_2_DIGITS_YEAR["cc-exp-year"], 10) + 2000);
 
-  do_check_eq(creditCards[2]["cc-number-masked"].length, 16);
+  do_check_eq(creditCards[2]["cc-number"].length, 16);
   // TODO: Check the decrypted numbers should not contain spaces after
   //       decryption lands (bug 1337314).
 
   Assert.throws(() => profileStorage.creditCards.add(TEST_CREDIT_CARD_WITH_INVALID_NUMBERS),
     /Credit card number contains invalid characters\./);
 });
 
 add_task(async function test_notifyUsed() {
--- a/browser/extensions/formautofill/test/unit/test_profileAutocompleteResult.js
+++ b/browser/extensions/formautofill/test/unit/test_profileAutocompleteResult.js
@@ -1,10 +1,11 @@
 "use strict";
 
+/* global AddressResult, CreditCardResult */
 Cu.import("resource://formautofill/ProfileAutoCompleteResult.jsm");
 
 let matchingProfiles = [{
   guid: "test-guid-1",
   "given-name": "Timothy",
   "family-name": "Berners-Lee",
   name: "Timothy Berners-Lee",
   organization: "Sesame Street",
@@ -37,17 +38,17 @@ let allFieldNames = [
   "street-address",
   "address-line1",
   "address-line2",
   "address-line3",
   "organization",
   "tel",
 ];
 
-let testCases = [{
+let addressTestCases = [{
   description: "Focus on an `organization` field",
   options: {},
   matchingProfiles,
   allFieldNames,
   searchString: "",
   fieldName: "organization",
   expected: {
     searchResult: Ci.nsIAutoCompleteResult.RESULT_SUCCESS,
@@ -210,47 +211,178 @@ let testCases = [{
   fieldName: "",
   expected: {
     searchResult: Ci.nsIAutoCompleteResult.RESULT_FAILURE,
     defaultIndex: 0,
     items: [],
   },
 }];
 
-add_task(async function test_all_patterns() {
-  testCases.forEach(testCase => {
-    do_print("Starting testcase: " + testCase.description);
-    let actual = new ProfileAutoCompleteResult(testCase.searchString,
-                                               testCase.fieldName,
-                                               testCase.allFieldNames,
-                                               testCase.matchingProfiles,
-                                               testCase.options);
-    let expectedValue = testCase.expected;
-    let expectedItemLength = expectedValue.items.length;
-    // If the last item shows up as a footer, we expect one more item
-    // than expected.
-    if (actual.getStyleAt(actual.matchCount - 1) == "autofill-footer") {
-      expectedItemLength++;
-    }
+matchingProfiles = [{
+  guid: "test-guid-1",
+  "cc-name": "Timothy Berners-Lee",
+  "cc-number": "************6785",
+  "cc-exp-month": 12,
+  "cc-exp-year": 2014,
+}, {
+  guid: "test-guid-2",
+  "cc-name": "John Doe",
+  "cc-number": "************1234",
+  "cc-exp-month": 4,
+  "cc-exp-year": 2014,
+}, {
+  guid: "test-guid-3",
+  "cc-number": "************5678",
+  "cc-exp-month": 8,
+  "cc-exp-year": 2018,
+}];
+
+allFieldNames = [
+  "cc-name",
+  "cc-number",
+  "cc-exp-month",
+  "cc-exp-year",
+];
 
-    equal(actual.searchResult, expectedValue.searchResult);
-    equal(actual.defaultIndex, expectedValue.defaultIndex);
-    equal(actual.matchCount, expectedItemLength);
-    expectedValue.items.forEach((item, index) => {
-      equal(actual.getValueAt(index), item.value);
-      equal(actual.getCommentAt(index), item.comment);
-      equal(actual.getLabelAt(index), item.label);
-      equal(actual.getStyleAt(index), item.style);
-      equal(actual.getImageAt(index), item.image);
-    });
+let creditCardTestCases = [{
+  description: "Focus on a `cc-name` field",
+  options: {},
+  matchingProfiles,
+  allFieldNames,
+  searchString: "",
+  fieldName: "cc-name",
+  expected: {
+    searchResult: Ci.nsIAutoCompleteResult.RESULT_SUCCESS,
+    defaultIndex: 0,
+    items: [{
+      value: "",
+      style: "autofill-profile",
+      comment: JSON.stringify(matchingProfiles[0]),
+      label: JSON.stringify({
+        primary: "Timothy Berners-Lee",
+        secondary: "************6785",
+      }),
+      image: "",
+    }, {
+      value: "",
+      style: "autofill-profile",
+      comment: JSON.stringify(matchingProfiles[1]),
+      label: JSON.stringify({
+        primary: "John Doe",
+        secondary: "************1234",
+      }),
+      image: "",
+    }],
+  },
+}, {
+  description: "Focus on a `cc-number` field",
+  options: {},
+  matchingProfiles,
+  allFieldNames,
+  searchString: "",
+  fieldName: "cc-number",
+  expected: {
+    searchResult: Ci.nsIAutoCompleteResult.RESULT_SUCCESS,
+    defaultIndex: 0,
+    items: [{
+      value: "",
+      style: "autofill-profile",
+      comment: JSON.stringify(matchingProfiles[0]),
+      label: JSON.stringify({
+        primary: "************6785",
+        secondary: "Timothy Berners-Lee",
+      }),
+      image: "",
+    }, {
+      value: "",
+      style: "autofill-profile",
+      comment: JSON.stringify(matchingProfiles[1]),
+      label: JSON.stringify({
+        primary: "************1234",
+        secondary: "John Doe",
+      }),
+      image: "",
+    }, {
+      value: "",
+      style: "autofill-profile",
+      comment: JSON.stringify(matchingProfiles[2]),
+      label: JSON.stringify({
+        primary: "************5678",
+        secondary: "",
+      }),
+      image: "",
+    }],
+  },
+}, {
+  description: "No matching profiles",
+  options: {},
+  matchingProfiles: [],
+  allFieldNames,
+  searchString: "",
+  fieldName: "",
+  expected: {
+    searchResult: Ci.nsIAutoCompleteResult.RESULT_NOMATCH,
+    defaultIndex: 0,
+    items: [],
+  },
+}, {
+  description: "Search with failure",
+  options: {resultCode: Ci.nsIAutoCompleteResult.RESULT_FAILURE},
+  matchingProfiles: [],
+  allFieldNames,
+  searchString: "",
+  fieldName: "",
+  expected: {
+    searchResult: Ci.nsIAutoCompleteResult.RESULT_FAILURE,
+    defaultIndex: 0,
+    items: [],
+  },
+}];
 
-    if (expectedValue.items.length != 0) {
-      Assert.throws(() => actual.getValueAt(expectedItemLength),
-        /Index out of range\./);
+let testSets = [{
+  collectionConstructor: AddressResult,
+  testCases: addressTestCases,
+}, {
+  collectionConstructor: CreditCardResult,
+  testCases: creditCardTestCases,
+}];
 
-      Assert.throws(() => actual.getLabelAt(expectedItemLength),
-        /Index out of range\./);
+add_task(async function test_all_patterns() {
+  testSets.forEach(({collectionConstructor, testCases}) => {
+    testCases.forEach(testCase => {
+      do_print("Starting testcase: " + testCase.description);
+      let actual = new collectionConstructor(testCase.searchString,
+                                             testCase.fieldName,
+                                             testCase.allFieldNames,
+                                             testCase.matchingProfiles,
+                                             testCase.options);
+      let expectedValue = testCase.expected;
+      let expectedItemLength = expectedValue.items.length;
+      // If the last item shows up as a footer, we expect one more item
+      // than expected.
+      if (actual.getStyleAt(actual.matchCount - 1) == "autofill-footer") {
+        expectedItemLength++;
+      }
 
-      Assert.throws(() => actual.getCommentAt(expectedItemLength),
-        /Index out of range\./);
-    }
+      equal(actual.searchResult, expectedValue.searchResult);
+      equal(actual.defaultIndex, expectedValue.defaultIndex);
+      equal(actual.matchCount, expectedItemLength);
+      expectedValue.items.forEach((item, index) => {
+        equal(actual.getValueAt(index), item.value);
+        equal(actual.getCommentAt(index), item.comment);
+        equal(actual.getLabelAt(index), item.label);
+        equal(actual.getStyleAt(index), item.style);
+        equal(actual.getImageAt(index), item.image);
+      });
+
+      if (expectedValue.items.length != 0) {
+        Assert.throws(() => actual.getValueAt(expectedItemLength),
+          /Index out of range\./);
+
+        Assert.throws(() => actual.getLabelAt(expectedItemLength),
+          /Index out of range\./);
+
+        Assert.throws(() => actual.getCommentAt(expectedItemLength),
+          /Index out of range\./);
+      }
+    });
   });
 });
--- a/browser/extensions/pocket/content/Pocket.jsm
+++ b/browser/extensions/pocket/content/Pocket.jsm
@@ -1,9 +1,9 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
+  /* 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 {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 
 this.EXPORTED_SYMBOLS = ["Pocket"];
 
@@ -29,17 +29,19 @@ var Pocket = {
   },
 
   onPanelViewShowing(event) {
     let document = event.target.ownerDocument;
     let window = document.defaultView;
     let iframe = window.pktUI.getPanelFrame();
 
     let libraryButton = document.getElementById("library-button");
-    BrowserUtils.setToolbarButtonHeightProperty(libraryButton);
+    if (libraryButton) {
+      BrowserUtils.setToolbarButtonHeightProperty(libraryButton);
+    }
 
     let urlToSave = Pocket._urlToSave;
     let titleToSave = Pocket._titleToSave;
     Pocket._urlToSave = null;
     Pocket._titleToSave = null;
     // ViewShowing fires immediately before it creates the contents,
     // in lieu of an AfterViewShowing event, just spin the event loop.
     window.setTimeout(function() {
--- a/browser/extensions/pocket/content/main.js
+++ b/browser/extensions/pocket/content/main.js
@@ -92,18 +92,17 @@ var pktUI = (function() {
         getPanelFrame().setAttribute("src", "about:blank");
 
         if (_lastAddSucceeded) {
             var libraryButton = document.getElementById("library-button");
             if (!Services.prefs.getBoolPref("toolkit.cosmeticAnimations.enabled") ||
                 !libraryButton ||
                 libraryButton.getAttribute("cui-areatype") == "menu-panel" ||
                 libraryButton.getAttribute("overflowedItem") == "true" ||
-                !libraryButton.closest("toolbar") ||
-                libraryButton.closest("toolbar").id != "nav-bar") {
+                !libraryButton.closest("#nav-bar")) {
                 return;
             }
             libraryButton.removeAttribute("fade");
             libraryButton.setAttribute("animate", "pocket");
             libraryButton.addEventListener("animationend", onLibraryButtonAnimationEnd);
         }
     }
 
@@ -482,16 +481,17 @@ var pktUI = (function() {
 
         // Based on clicking "remove page" CTA, and passed unique item id, remove the item
         var _deleteItemMessageId = "deleteItem";
         pktUIMessaging.addMessageListener(iframe, _deleteItemMessageId, function(panelId, data) {
             pktApi.deleteItem(data.itemId, {
                 success(data, response) {
                     var successResponse = {status: "success"};
                     pktUIMessaging.sendResponseMessageToPanel(panelId, _deleteItemMessageId, successResponse);
+                    _lastAddSucceeded = false;
                 },
                 error(error, response) {
                     pktUIMessaging.sendErrorResponseMessageToPanel(panelId, _deleteItemMessageId, error);
                 }
             })
         });
 
         var _initL10NMessageId = "initL10N";
--- a/browser/extensions/webcompat-reporter/moz.build
+++ b/browser/extensions/webcompat-reporter/moz.build
@@ -17,9 +17,9 @@ FINAL_TARGET_PP_FILES.features['webcompa
   'install.rdf.in'
 ]
 
 JAR_MANIFESTS += ['jar.mn']
 
 BROWSER_CHROME_MANIFESTS += ['test/browser/browser.ini']
 
 with Files('**'):
-    BUG_COMPONENT = ('Web Compatibility', 'General')
+    BUG_COMPONENT = ('Web Compatibility Tools', 'General')
--- a/browser/extensions/webcompat/moz.build
+++ b/browser/extensions/webcompat/moz.build
@@ -14,9 +14,9 @@ FINAL_TARGET_FILES.features['webcompat@m
 FINAL_TARGET_PP_FILES.features['webcompat@mozilla.org'] += [
   'install.rdf.in'
 ]
 
 BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
 JAR_MANIFESTS += ['jar.mn']
 
 with Files('**'):
-  BUG_COMPONENT = ('Web Compatibility', 'Go Faster')
+  BUG_COMPONENT = ('Web Compatibility Tools', 'Go Faster')
--- a/browser/installer/windows/nsis/stub.nsi
+++ b/browser/installer/windows/nsis/stub.nsi
@@ -830,26 +830,26 @@ Function createInstall
   Pop $LabelBlurb
   SendMessage $LabelBlurb ${WM_SETFONT} $FontBlurb 0
   SetCtlColors $LabelBlurb ${INSTALL_BLURB_TEXT_COLOR} transparent
 
   StrCpy $CurrentBlurbIdx "0"
 
   ; In some locales, the footer message may be too long to fit on one line.
   ; Figure out how much height it needs and give it that much.
-  ${GetTextWidthHeight} "$(STUB_BLURB_FOOTER)" $FontFooter \
+  ${GetTextWidthHeight} "$(STUB_BLURB_FOOTER2)" $FontFooter \
     ${INSTALL_FOOTER_WIDTH_DU} $R1 $R2
   !ifdef ${AB_CD}_rtl
     nsDialogs::CreateControl STATIC ${DEFAULT_STYLES}|${SS_NOTIFY} \
       ${WS_EX_TRANSPARENT} 30u ${INSTALL_FOOTER_TOP_DU} ${INSTALL_FOOTER_WIDTH_DU} "$R2u" \
-      "$(STUB_BLURB_FOOTER)"
+      "$(STUB_BLURB_FOOTER2)"
   !else
     nsDialogs::CreateControl STATIC ${DEFAULT_STYLES}|${SS_NOTIFY}|${SS_RIGHT} \
       ${WS_EX_TRANSPARENT} 175u ${INSTALL_FOOTER_TOP_DU} ${INSTALL_FOOTER_WIDTH_DU} "$R2u" \
-      "$(STUB_BLURB_FOOTER)"
+      "$(STUB_BLURB_FOOTER2)"
   !endif
   Pop $0
   SendMessage $0 ${WM_SETFONT} $FontFooter 0
   SetCtlColors $0 ${INSTALL_BLURB_TEXT_COLOR} transparent
 
   ${NSD_CreateProgressBar} 20% ${PROGRESS_BAR_TOP_DU} 60% 12u ""
   Pop $Progressbar
   ${NSD_AddStyle} $Progressbar ${PBS_MARQUEE}
--- a/browser/locales/en-US/installer/nsisstrings.properties
+++ b/browser/locales/en-US/installer/nsisstrings.properties
@@ -19,17 +19,17 @@
 # from en-US contains a \n.
 
 INSTALLER_WIN_CAPTION=$BrandShortName Installer
 
 STUB_INSTALLING_LABEL=Now installing
 STUB_BLURB1=Fast, responsive online experiences
 STUB_BLURB2=Compatibility with more of your favorite sites
 STUB_BLURB3=Built-in privacy tools for safer browsing
-STUB_BLURB_FOOTER=The only browser built for people, not profit
+STUB_BLURB_FOOTER2=Built for people, not for profit
 
 WARN_MIN_SUPPORTED_OSVER_MSG=Sorry, $BrandShortName can't be installed. This version of $BrandShortName requires ${MinSupportedVer} or newer. Please click the OK button for additional information.
 WARN_MIN_SUPPORTED_CPU_MSG=Sorry, $BrandShortName can't be installed. This version of $BrandShortName requires a processor with ${MinSupportedCPU} support. Please click the OK button for additional information.
 WARN_MIN_SUPPORTED_OSVER_CPU_MSG=Sorry, $BrandShortName can't be installed. This version of $BrandShortName requires ${MinSupportedVer} or newer and a processor with ${MinSupportedCPU} support. Please click the OK button for additional information.
 WARN_WRITE_ACCESS_QUIT=You don't have access to write to the installation directory
 WARN_DISK_SPACE_QUIT=You don't have sufficient disk space to install.
 WARN_MANUALLY_CLOSE_APP_LAUNCH=$BrandShortName is already running.\n\nPlease close $BrandShortName prior to launching the version you have just installed.
 
--- a/browser/locales/searchplugins/wikipedia-is.xml
+++ b/browser/locales/searchplugins/wikipedia-is.xml
@@ -2,18 +2,16 @@
    - 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/. -->
 
 <SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
 <ShortName>Wikipedia (is)</ShortName>
 <Description>Wikipedia, the free encyclopedia</Description>
 <InputEncoding>UTF-8</InputEncoding>
 <Image width="16" height="16">resource://search-plugins/images/wikipedia.ico</Image>
-<Image width="65" height="26">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEEAAAAaCAYAAADovjFxAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyNpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NDkxMSwgMjAxMy8xMC8yOS0xMTo0NzoxNiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChNYWNpbnRvc2gpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjA3MkMyRDY5QjUyNTExRTNCNzdEOTU4N0NCMjI3MEFDIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjA3MkMyRDZBQjUyNTExRTNCNzdEOTU4N0NCMjI3MEFDIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MDcyQzJENjdCNTI1MTFFM0I3N0Q5NTg3Q0IyMjcwQUMiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MDcyQzJENjhCNTI1MTFFM0I3N0Q5NTg3Q0IyMjcwQUMiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7lkNGzAAAELklEQVR42uyYa4hUZRjHn3Nm13X2Mu6urtqutrTeVjRUQikoKUoQLIy8hybiBcVMRdFASPwgQTczsCiMvFYGffBDeANFUDEydc31viheat2dyVndmdmdy57+7/I/+HCcKaX1Q3Re+LHnOe9z3sv/PM/znlnLcRz5vzdb/OaL4Ivgi3C/WV01UCAQkNraWqmpGSCVVVWSl5cnZaXl4jgZaWpugp0viURcwpGIJJMpSba1SY+yUlmy5B3ZuGGDXGlokJKSYkmn0pJOp6UDBbsl2iJFRYVi25bEYjFpwzOtra3S3t4umUxGuqqo53WVCGZR9fX1nZgWDAaxgWIJhUpASGyIFLBtSWKDhcFCScTjuE5JXV2dhMNhSaVS2Kwt0WgUYiU6hTCiRSLNGM2BnYF4yccWCWPB6yAC9oGzYC2Iga/pNx/kg/fBs2AcSICvQOMjT2pZD7xFE0kFBd0lHo89zsiv5d8L3o4nwW+dcotUMDo+p11Jn3YKY/qeY9900P0/lv5hUJ+rswc3Nlnd6wDvgmHgR3V/GfgyS0RZf1NrrEeoR/ZD1rDAPzzrHX8wuEYhcr68E6BV2W9RGJMiI9T9wxzwFfAd+AyUgeFgK/iG9ovgAMcpAIvB92AVNzCJ9hoKu4LjjwabmYrGdwtYyb45nPM98DbYyHW4bSr7Pwb9PPszqTwGnGdUZ22DuekX1L074JSy3wC7eV1C/53clFHXVLEz7Hc3UsG38gz9x7O/F+25oC+vPzI1FVwGN0FP8Dz4gmO4fvPYN5X2LI5ZSvsTT9F/iveEgkZyhc8lTrxd3TPhM1LZ08C3vL7HxRplM6AN/AqOgVGgjhts5sKugyi4qvKzhaKZ4voHGMKCe5oF2qHfIj7TyDGucSM/sH5tY7/p+x1cBGm17vmMgikUsxw8kSv/ZoBqqjiCm7zLsBQ+vMuTl/nKbuTJcdIjpmnduIBuKmfNmfcy570BlrMvzpSap+Z2GG2WZ869nr3Ynn7TngZ7wACKbIRdl+s74QgddlPphVzgh6A/c1g8xbND2b24qD/BLVDk8XWUv8MIKuTCTNinVFjfBh+oY82mv+OZs1SNJ1n6ZzLi1nvWsgksyFUbXuVAO5RQjppENxNynyq7AfzE6xsMyyDtfhxDF1mHkZCtSJ9T9mLWIPeZibzuyejb5hlztVr7ZaaBtzlu5GU7Zi7xW8BU0CaqZt7wfnBI+b0GhvIb4iBD7SWOuYfKr+Px+zN4k3loJj/KojYIFINfmALu6TCW0dGbp0gNj+nZLHI203YCOA6WqtNhEF/OWc45ki/kHOuWzW+cgYyyK//mw8MtLEU8AkMqbIMeP5OjfWj3oU9flUL63C5XZ7zZaJXq66+eGajmdJvrG2LkuHNUco1uLapWdarC8v+z5P+U9kXwRfBF8EXwRfBFyNH+EmAA/FQ613UCCjYAAAAASUVORK5CYII=</Image>
-<Image width="130" height="52">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIIAAAA0CAYAAABGkOCVAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyNpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NDkxMSwgMjAxMy8xMC8yOS0xMTo0NzoxNiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChNYWNpbnRvc2gpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjg5QzlEREIwQjUyNjExRTNCNzdEOTU4N0NCMjI3MEFDIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjg5QzlEREIxQjUyNjExRTNCNzdEOTU4N0NCMjI3MEFDIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6ODlDOUREQUVCNTI2MTFFM0I3N0Q5NTg3Q0IyMjcwQUMiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6ODlDOUREQUZCNTI2MTFFM0I3N0Q5NTg3Q0IyMjcwQUMiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz41D9uwAAAJWElEQVR42uxcCWxURRj+t3t029IiVCyXLSpo0ERFLVAvNJ4oBRUVL7Se4IUXeOIVjaKmgkHxthweiKJGY/HAKxqwaiwYBBESwQtpgdCWtns//6nfi7/je7v72kI0mS/5s7vvn5n3Zuab/3pNfZZlkYFBjlkCA0MEA0MEA0MEA0MEA0MEA0MEA0MEA0MEA0MEA0MEg87B919+OL/fT4FAgELBIF0zZQqVl5dTSZ8SWr1mHY2oqKBYtIWSiSSlLB81bN5EkUiU4ok4BYMBSqZ8FItEqCmVoBhf6xvOJx+PY6VSRHi/krJS5PP5OiTB4+SFcymVTFI797N4TFJ6foatjVsoNxyi3sW7U3t7hOKxCB+hHGppbqFgfh7ts+cgamlvofy8fIrHk+Tj4ROxKK1Y+S21trbRgvnz+NkilOSxU+r+hghdw+DBg6msbBDV1X1FY8ZUUmtbS8fG+nw5VFVVRUWFPamppYlCoSAlkooI7dTMmxlnMvTzSAS1oe1trdSjqIiJsJWJEKRevYs7iBCLMhH8OfwZo2Zus7R2CcWYHIq0hw4fQX5+nveX1FJ9/bfGIuxqDBgwgPLy8ngD4x0bq7baSllUstcgGj9hAoWjfJ03yrIkESwQgU9wIkXh3FAHESLRKBUV7UZlpaW0dt2PFGlro8WLX6eGhoaOE93xxpb7qL7qpDfydRuKDIlkgsi81P0PBkI53kOhIUOG0LRptzAhijrV//8YIwxluZMlxtJCf3HZz1LM8hbLQpYDWe5gaWJhu0ghliBLNctqlqksB7NsYwmz9GCZw/IFy0Uso9E3ylLIkg/dbEPTnY5TWTawfJ+p4R4sN7GsAgmUtLHczXKYaDNb6JVMB1kUjmd5R+hU2z2hG8HyIMa09U+hj8HOhdo3FZ2+7qVTL5bN2KiVLm1mQd/OMlDTjYPuXpe+86EfZvZnl+EWcbD7e+l4jzi1Zzjo+7I0Ql+j6epYfoFbcSKZcjsLzN7sMoQ0Kz/FS+dSllZ0/MSlzf3Qq3b74dpxuHaOS5/roD/Q7M8uwyU4nPZ+feN1gGfRMc5S4WIVtqPNQ7imXMkacq9UbmJZJgLUXBcGO323ERTfA3rtSViioIM+IPr7tbFshNOsScDlmdImK2nmEfRwqp36+7PoW4cAvzcCfLVfI9NNUMfTLBfiIa5kWa7p/0AwOB2s246TPgaBiY7TQZ7r8VtZkWcwmQQ+fSDTVWgzE1lICqI2aS0yELUQL7H0YymCy1Exy40s37FczTIeYybFfdS8XmE5gOVhlgKM7cMixbR4Rrox5SavweYmsW5JCIHYPVmWIINSGAT3aY+fg+dox3xS+P0uywuwsDqRVFZ2CO5jZ3Mq87qV5es0JBjOUs5yLjK5z1hOhMX+0gub38ON1U33colGG4X/eSPNWJ/hYWzkY5NrRP8rVOou03g8tK1fxLK/sCiVQnctAtACu7bEMoplI/Q/sBzK0gd61e4gkMkeYxzIfBRMqLr2srBcfbCwddD9zjKR5TSWsSw3i+vSwgwDqe37TMJ91PzPxLqp6+vgXvXUfjDLWaL/QvQtzLB/i7DuNiah/88gbNY4Udx8hkub6aLNyS5t9oX+dgfdKOh+cnEVhBOu2hytXVfj/cpSlmYOj2vuS8dY6Fdo13uKOOlUlyj8SZf5qHx9d+36kejzmyCrbjHtTKw8wzqcksXe9YO1kfGaSvObMcZYNz/mhA+ECbkUfkbHAuEK3HzPZfic46ArEM9Q5KCXfl+eAHUSb8MmbczCv7qRLE/cR6JJFF+GuMQRuS6Wb6bDXDLN8024gDDis5DLWtjWNBOuByFfFde2ilrC+V6IQKLqpxhe5aAfIPpPhrvQF2AyxtnexQg4IU7X04gDVu7k1IsQf6R7HsIhuRzfH4OF84q5+FQu69guPHcAcdRH9O+3HfPxWYm9y5oIb7OsFz5GN2vVqBsov1iCTZc4Dye5O8rIO2B1aumvcvj8btx0PcBVzzwU35elKb6Voah2l2aGO/O66Xe4OoVjujCX0dgLZS3fRwngUwSxDwhLeK4XIuxAdG/7+tOErhIbczFMG+GUFos2KnVZikCoq3gB2UthmvpGZ1GAoEwFhHsjiAyhuLbGpc8RMOM1qJH80cVniCCGIK8VQA1Xw/o+D/em4p96ZFy1SALIiQiZoMz9ZoeCRD0iUBkMKZmGa8dmEdycgjYbRUSv+8Xv0eZhTE59X410NBOeQftZLvoJ0Dchyp6LhVqG9NkJd4vovT9M7HQtQtdxEvpsQiDnBBVzfI52zzvo7XU4M819hqLNJWnaVIhUtMIrGarFRg9DXqs/1MdiU1Xa8yICFuomItjvJz7E7+UZCkBeiLAClmyYS6rsRIRntYh8YheJ0EPM9Z5OEuEJkLogQ5HLTo8fzdY1yKDRLrY8CllF/3yjNVOUqFWGcAJOcXfBfsE1Hq5mJAKz7oAfUXW9h0DPr0XkC8R6FnbiGQpFhrK0k+7tKtQ+WjPEQ2+LtezphQgb4DftQGYU/L/EhyKKn4xCVE2WmUBKVOgkZOUuis9mpD9tKEJNTTN+Uvt003sJ7uLap44bHNxKMsM8CUWjIAI7pwDVcshW9JRR4bks5rAQNYtSFNA8YTgmYptlp9L0JOFCbs5izLPRdrtD6mlHt5vQZoKmu0Dc64I01TULgaYTqqBf72Ed5qBPrYPucJYGnDSJcaJKW+pQPZwI/VqntA6HdQPaOKXx+4EgjR7mUY/xvszgShzxCTpXuujzUUqO07//VkGiP8z6L2Izl+OE24tzKU6GJchyB/3zZc0XQl8rgh/lkxcLnYrI54miVxnihs2izTLc3+1vOEeCWAm0Vyf7LQSYNUjPLByWElF/mYENlvO8DylwNSzpr3AtJQ4EqBLxl4XsZBbWdyCqp1uEfgkOYaGL+1AW6zURMFqoWt4X8EAE9VJH1ezfcdG3IS3JFTmxW8CyDRNqwuIP1MxtApOai8XtiwmHRLtb8TxRBJs+4b9XIZJvBUF3E1YsgFStGic4DIsUyfDM67GQTfjdQyxmLsj0IwhmP4edgm/D8/Whv1+0qXavYKM3uNzT/nOARZh3Ma4HMZ6axyNYmyDIF3ex2DlYq3qszQ6sZzE5vyw0MDAwMDAwMDAwQKpm/uGmgZ1SGBgYIhgYIhgYIhgYIhgYIhgYIhgYIhgYIhgYIhh4w58CDAAL8AVXFSeKUgAAAABJRU5ErkJggg==</Image>
 <Url type="application/x-suggestions+json" method="GET" template="https://is.wikipedia.org/w/api.php">
   <Param name="action" value="opensearch"/>
   <Param name="search" value="{searchTerms}"/>
 </Url>
 <Url type="text/html" method="GET" template="https://is.wikipedia.org/wiki/Kerfissíða:Leit"
      resultdomain="wikipedia.org" rel="searchform">
   <Param name="search" value="{searchTerms}"/>
   <Param name="sourceid" value="Mozilla-search"/>
--- a/browser/modules/ZoomUI.jsm
+++ b/browser/modules/ZoomUI.jsm
@@ -39,16 +39,22 @@ function onEndSwapDocShells(event) {
 
 function onZoomChange(event) {
   let browser;
   if (event.target.nodeType == event.target.DOCUMENT_NODE) {
     // In non-e10s, the event is dispatched on the contentDocument
     // so we need to jump through some hoops to get to the <xul:browser>.
     let gBrowser = event.currentTarget.gBrowser;
     let topDoc = event.target.defaultView.top.document;
+    if (!topDoc.documentElement) {
+      // In some events, such as loading synthetic documents, the
+      // documentElement will be null and getBrowserForDocument will
+      // return null.
+      return;
+    }
     browser = gBrowser.getBrowserForDocument(topDoc);
   } else {
     browser = event.originalTarget;
   }
   updateZoomUI(browser, true);
 }
 
 /**
new file mode 100644
--- /dev/null
+++ b/browser/themes/shared/icons/bookmark-animation.svg
@@ -0,0 +1,542 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+   - License, v. 2.0. If a copy of the MPL was not distributed with this
+   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<svg xmlns="http://www.w3.org/2000/svg" width="660" height="33">
+  <svg>
+    <defs>
+      <mask id="b" mask-type="alpha">
+        <path fill="#0a84ff" d="M0 0h320v240h-320z" transform="matrix(0 0 0 0 16.352 17.593)"/>
+      </mask>
+      <mask id="a" mask-type="alpha">
+        <path fill="#0a84ff" d="M0 0h320v240h-320z" transform="matrix(0 0 0 0 16.463 17.517)"/>
+      </mask>
+    </defs>
+    <path fill="none" stroke="context-fill" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.584" d="M16.457 9.307l1.71 3.363 0.722 1.422 1.57 0.267 3.653 0.624 -2.66 2.897 -1.03 1.12 0.23 1.506 0.587 3.824 -3.32 -1.762 -1.496 -0.792 -1.49 0.8 -3.225 1.73 0.584 -3.798 0.233 -1.514 -1.043 -1.124 -2.676 -2.882 3.718 -0.624 1.613 -0.272 0.713 -1.472 1.606 -3.31"/>
+    <g mask="url(#a)">
+      <path fill="#FFF" d="M16.456 9.271l1.716 3.376 0.725 1.427 1.577 0.269 3.666 0.626 -2.67 2.907 -1.033 1.125 0.23 1.512 0.589 3.838 -3.333 -1.768 -1.5 -0.796 -1.496 0.803 -3.238 1.737 0.586 -3.813 0.234 -1.52 -1.047 -1.128 -2.686 -2.892 3.732 -0.627 1.619 -0.273 0.716 -1.477 1.612 -3.324"/>
+      <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.59" d="M16.456 9.271l1.716 3.376 0.725 1.427 1.577 0.269 3.666 0.626 -2.67 2.907 -1.033 1.125 0.23 1.512 0.589 3.838 -3.333 -1.768 -1.5 -0.796 -1.496 0.803 -3.238 1.737 0.586 -3.813 0.234 -1.52 -1.047 -1.128 -2.686 -2.892 3.732 -0.627 1.619 -0.273 0.716 -1.477 1.612 -3.324"/>
+    </g>
+    <g mask="url(#b)" opacity=".08">
+      <path fill="context-fill" d="M16.502 10.083l2.255 4.57 5.044 0.734 -3.65 3.557 0.862 5.023 -4.511 -2.371 -4.512 2.371 0.862 -5.023 -3.65 -3.557 5.044 -0.733 2.256 -4.57z"/>
+      <path fill="none" d="M16.502 10.083l2.255 4.57 5.044 0.734 -3.65 3.557 0.862 5.023 -4.511 -2.371 -4.512 2.371 0.862 -5.023 -3.65 -3.557 5.044 -0.733 2.256 -4.57z"/>
+    </g>
+  </svg>
+  <svg x="33">
+    <defs>
+      <mask id="d" mask-type="alpha">
+        <path fill="#0a84ff" d="M0 0h320v240h-320z" transform="matrix(.04 0 0 .04 9.957 11.594)"/>
+      </mask>
+      <mask id="c" mask-type="alpha">
+        <path fill="#0a84ff" d="M0 0h320v240h-320z" transform="matrix(.04 0 0 .04 10.127 12.218)"/>
+      </mask>
+    </defs>
+    <path fill="none" stroke="context-fill" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.584" d="M16.457 9.307l1.71 3.363 0.722 1.422 1.57 0.267 3.653 0.624 -2.66 2.897 -1.03 1.12 0.23 1.506 0.587 3.824 -3.32 -1.762 -1.496 -0.792 -1.49 0.8 -3.225 1.73 0.584 -3.798 0.233 -1.514 -1.043 -1.124 -2.676 -2.882 3.718 -0.624 1.613 -0.272 0.713 -1.472 1.606 -3.31"/>
+    <g mask="url(#c)">
+      <path fill="#FFF" d="M16.457 9.283l1.712 3.37 0.724 1.425 1.575 0.268 3.66 0.626 -2.665 2.902 -1.032 1.124 0.23 1.509 0.588 3.831 -3.328 -1.765 -1.498 -0.794 -1.493 0.802 -3.233 1.734 0.585 -3.807 0.233 -1.517 -1.045 -1.127 -2.681 -2.887 3.726 -0.626 1.616 -0.272 0.715 -1.476 1.609 -3.318"/>
+      <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.587" d="M16.457 9.283l1.712 3.37 0.724 1.425 1.575 0.268 3.66 0.626 -2.665 2.902 -1.032 1.124 0.23 1.509 0.588 3.831 -3.328 -1.765 -1.498 -0.794 -1.493 0.802 -3.233 1.734 0.585 -3.807 0.233 -1.517 -1.045 -1.127 -2.681 -2.887 3.726 -0.626 1.616 -0.272 0.715 -1.476 1.609 -3.318"/>
+    </g>
+    <g mask="url(#d)" opacity=".08">
+      <path fill="#2A9EFF" d="M16.502 10.094l2.252 4.563 5.036 0.732 -3.644 3.552 0.86 5.015 -4.504 -2.368 -4.504 2.368 0.86 -5.015 -3.644 -3.552 5.036 -0.732 2.252 -4.563z"/>
+      <path fill="none" d="M16.502 10.094l2.252 4.563 5.036 0.732 -3.644 3.552 0.86 5.015 -4.504 -2.368 -4.504 2.368 0.86 -5.015 -3.644 -3.552 5.036 -0.732 2.252 -4.563z"/>
+    </g>
+  </svg>
+  <svg x="66">
+    <defs>
+      <mask id="f" mask-type="alpha">
+        <path fill="#0a84ff" d="M0 0h320v240h-320z" transform="matrix(.08 0 0 .08 3.562 5.594)"/>
+      </mask>
+      <mask id="e" mask-type="alpha">
+        <path fill="#0a84ff" d="M0 0h320v240h-320z" transform="matrix(.08 0 0 .08 3.791 6.92)"/>
+      </mask>
+    </defs>
+    <path fill="none" stroke="context-fill" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.584" d="M16.457 9.307l1.71 3.363 0.722 1.422 1.57 0.267 3.653 0.624 -2.66 2.897 -1.03 1.12 0.23 1.506 0.587 3.824 -3.32 -1.762 -1.496 -0.792 -1.49 0.8 -3.225 1.73 0.584 -3.798 0.233 -1.514 -1.043 -1.124 -2.676 -2.882 3.718 -0.624 1.613 -0.272 0.713 -1.472 1.606 -3.31"/>
+    <g mask="url(#e)">
+      <path fill="#FFF" d="M16.457 9.308l1.708 3.359 0.721 1.42 1.569 0.267 3.649 0.624 -2.657 2.892 -1.029 1.12 0.23 1.504 0.585 3.819 -3.316 -1.76 -1.493 -0.791 -1.488 0.799 -3.223 1.729 0.584 -3.794 0.232 -1.513 -1.041 -1.123 -2.673 -2.878 3.714 -0.624 1.61 -0.27 0.713 -1.471 1.604 -3.307"/>
+      <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.582" d="M16.457 9.308l1.708 3.359 0.721 1.42 1.569 0.267 3.649 0.624 -2.657 2.892 -1.029 1.12 0.23 1.504 0.585 3.819 -3.316 -1.76 -1.493 -0.791 -1.488 0.799 -3.223 1.729 0.584 -3.794 0.232 -1.513 -1.041 -1.123 -2.673 -2.878 3.714 -0.624 1.61 -0.27 0.713 -1.471 1.604 -3.307"/>
+    </g>
+    <g mask="url(#f)" opacity=".387">
+      <path fill="#2399FF" d="M16.502 10.116l2.245 4.548 5.019 0.729 -3.632 3.54 0.858 4.999 -4.49 -2.36 -4.489 2.36 0.858 -4.999 -3.632 -3.54 5.019 -0.73 2.244 -4.547z"/>
+      <path fill="none" d="M16.502 10.116l2.245 4.548 5.019 0.729 -3.632 3.54 0.858 4.999 -4.49 -2.36 -4.489 2.36 0.858 -4.999 -3.632 -3.54 5.019 -0.73 2.244 -4.547z"/>
+    </g>
+  </svg>
+  <svg x="99">
+    <defs>
+      <mask id="h" mask-type="alpha">
+        <path fill="#0a84ff" d="M0 0h320v240h-320z" transform="matrix(.12 0 0 .12 -2.833 -.405)"/>
+      </mask>
+      <mask id="g" mask-type="alpha">
+        <path fill="#0a84ff" d="M0 0h320v240h-320z" transform="matrix(.12 0 0 .12 -2.545 1.62)"/>
+      </mask>
+    </defs>
+    <path fill="none" stroke="context-fill" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.584" d="M16.457 9.307l1.71 3.363 0.722 1.422 1.57 0.267 3.653 0.624 -2.66 2.897 -1.03 1.12 0.23 1.506 0.587 3.824 -3.32 -1.762 -1.496 -0.792 -1.49 0.8 -3.225 1.73 0.584 -3.798 0.233 -1.514 -1.043 -1.124 -2.676 -2.882 3.718 -0.624 1.613 -0.272 0.713 -1.472 1.606 -3.31"/>
+    <g mask="url(#g)">
+      <path fill="#FFF" d="M16.458 9.336l1.7 3.347 0.72 1.414 1.562 0.266 3.635 0.621 -2.646 2.882 -1.025 1.115 0.229 1.498 0.583 3.804 -3.304 -1.752 -1.487 -0.789 -1.482 0.796 -3.21 1.722 0.58 -3.78 0.233 -1.506 -1.038 -1.118 -2.662 -2.867 3.699 -0.622 1.604 -0.27 0.71 -1.464 1.598 -3.295"/>
+      <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.576" d="M16.458 9.336l1.7 3.347 0.72 1.414 1.562 0.266 3.635 0.621 -2.646 2.882 -1.025 1.115 0.229 1.498 0.583 3.804 -3.304 -1.752 -1.487 -0.789 -1.482 0.796 -3.21 1.722 0.58 -3.78 0.233 -1.506 -1.038 -1.118 -2.662 -2.867 3.699 -0.622 1.604 -0.27 0.71 -1.464 1.598 -3.295"/>
+    </g>
+    <g mask="url(#h)" opacity=".693">
+      <path fill="#1D93FF" d="M16.503 10.141l2.236 4.53 5 0.727 -3.618 3.526 0.854 4.98 -4.472 -2.351 -4.471 2.35 0.854 -4.979 -3.618 -3.526 5 -0.726 2.235 -4.53z"/>
+      <path fill="none" d="M16.503 10.141l2.236 4.53 5 0.727 -3.618 3.526 0.854 4.98 -4.472 -2.351 -4.471 2.35 0.854 -4.979 -3.618 -3.526 5 -0.726 2.235 -4.53z"/>
+    </g>
+  </svg>
+  <svg x="132">
+    <defs>
+      <mask id="j" mask-type="alpha">
+        <path fill="#0a84ff" d="M0 0h320v240h-320z" transform="matrix(.16 0 0 .16 -9.228 -6.404)"/>
+      </mask>
+      <mask id="i" mask-type="alpha">
+        <path fill="#0a84ff" d="M0 0h320v240h-320z" transform="matrix(.16 0 0 .16 -8.88 -3.678)"/>
+      </mask>
+    </defs>
+    <g mask="url(#i)">
+      <path fill="#FFF" d="M16.459 9.355l1.696 3.338 0.717 1.41 1.559 0.266 3.625 0.62 -2.64 2.874 -1.022 1.112 0.229 1.495 0.581 3.794 -3.295 -1.748 -1.484 -0.787 -1.478 0.794 -3.201 1.718 0.58 -3.77 0.23 -1.503 -1.035 -1.115 -2.655 -2.86 3.69 -0.62 1.6 -0.269 0.708 -1.46 1.593 -3.287"/>
+      <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.572" d="M16.459 9.355l1.696 3.338 0.717 1.41 1.559 0.266 3.625 0.62 -2.64 2.874 -1.022 1.112 0.229 1.495 0.581 3.794 -3.295 -1.748 -1.484 -0.787 -1.478 0.794 -3.201 1.718 0.58 -3.77 0.23 -1.503 -1.035 -1.115 -2.655 -2.86 3.69 -0.62 1.6 -0.269 0.708 -1.46 1.593 -3.287"/>
+    </g>
+    <g mask="url(#j)">
+      <path fill="#168EFF" d="M16.504 10.158l2.23 4.519 4.986 0.724 -3.608 3.518 0.852 4.966 -4.46 -2.345 -4.46 2.345 0.851 -4.966 -3.608 -3.518 4.987 -0.724 2.23 -4.519z"/>
+      <path fill="none" d="M16.504 10.158l2.23 4.519 4.986 0.724 -3.608 3.518 0.852 4.966 -4.46 -2.345 -4.46 2.345 0.851 -4.966 -3.608 -3.518 4.987 -0.724 2.23 -4.519z"/>
+    </g>
+  </svg>
+  <svg x="165">
+    <defs>
+      <mask id="l" mask-type="alpha">
+        <path fill="#0a84ff" d="M0 0h320v240h-320z" transform="matrix(.2 0 0 .2 -15.623 -12.404)"/>
+      </mask>
+      <mask id="k" mask-type="alpha">
+        <path fill="#0a84ff" d="M0 0h320v240h-320z" transform="matrix(.2 0 0 .2 -15.216 -8.977)"/>
+      </mask>
+    </defs>
+    <g mask="url(#k)">
+      <path fill="#FFF" d="M16.46 9.4l1.686 3.318 0.712 1.402 1.55 0.264 3.602 0.615 -2.623 2.856 -1.016 1.106 0.227 1.485 0.578 3.77 -3.275 -1.737 -1.474 -0.781 -1.469 0.789 -3.181 1.707 0.575 -3.746 0.23 -1.494 -1.028 -1.109 -2.639 -2.841 3.667 -0.616 1.59 -0.268 0.703 -1.452 1.584 -3.265"/>
+      <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.562" d="M16.46 9.4l1.686 3.318 0.712 1.402 1.55 0.264 3.602 0.615 -2.623 2.856 -1.016 1.106 0.227 1.485 0.578 3.77 -3.275 -1.737 -1.474 -0.781 -1.469 0.789 -3.181 1.707 0.575 -3.746 0.23 -1.494 -1.028 -1.109 -2.639 -2.841 3.667 -0.616 1.59 -0.268 0.703 -1.452 1.584 -3.265"/>
+    </g>
+    <g mask="url(#l)">
+      <path fill="#1089FF" d="M16.505 10.199l2.216 4.49 4.956 0.72 -3.586 3.496 0.846 4.935 -4.432 -2.33 -4.432 2.33 0.846 -4.935 -3.586 -3.496 4.956 -0.72 2.216 -4.49z"/>
+      <path fill="none" d="M16.505 10.199l2.216 4.49 4.956 0.72 -3.586 3.496 0.846 4.935 -4.432 -2.33 -4.432 2.33 0.846 -4.935 -3.586 -3.496 4.956 -0.72 2.216 -4.49z"/>
+    </g>
+  </svg>
+  <svg x="198">
+    <defs>
+      <mask id="n" mask-type="alpha">
+        <path fill="#0a84ff" d="M0 0h320v240h-320z" transform="matrix(.2 0 0 .2 -15.623 -12.404)"/>
+      </mask>
+      <mask id="m" mask-type="alpha">
+        <path fill="#0a84ff" d="M0 0h320v240h-320z" transform="matrix(.2 0 0 .2 -15.216 -8.977)"/>
+      </mask>
+    </defs>
+    <g mask="url(#m)">
+      <path fill="#FFF" d="M16.457 9.299l1.71 3.363 0.722 1.422 1.57 0.267 3.653 0.625 -2.66 2.896 -1.03 1.12 0.23 1.506 0.587 3.824 -3.32 -1.762 -1.496 -0.792 -1.49 0.8 -3.225 1.73 0.584 -3.798 0.233 -1.514 -1.043 -1.124 -2.676 -2.882 3.718 -0.624 1.613 -0.272 0.713 -1.472 1.606 -3.31"/>
+      <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.584" d="M16.457 9.299l1.71 3.363 0.722 1.422 1.57 0.267 3.653 0.625 -2.66 2.896 -1.03 1.12 0.23 1.506 0.587 3.824 -3.32 -1.762 -1.496 -0.792 -1.49 0.8 -3.225 1.73 0.584 -3.798 0.233 -1.514 -1.043 -1.124 -2.676 -2.882 3.718 -0.624 1.613 -0.272 0.713 -1.472 1.606 -3.31"/>
+    </g>
+    <g mask="url(#n)">
+      <path fill="#0A84FF" d="M16.502 10.108l2.247 4.553 5.025 0.73 -3.636 3.545 0.858 5.004 -4.494 -2.363 -4.494 2.363 0.858 -5.004 -3.636 -3.545 5.025 -0.73 2.247 -4.553z"/>
+      <path fill="none" d="M16.502 10.108l2.247 4.553 5.025 0.73 -3.636 3.545 0.858 5.004 -4.494 -2.363 -4.494 2.363 0.858 -5.004 -3.636 -3.545 5.025 -0.73 2.247 -4.553z"/>
+    </g>
+    <path fill="#000" d="M4.273 14.274l-0.235 -0.115"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M4.273 14.274l-0.235 -0.115"/>
+    <path fill="#000" d="M28.738 14.306l0.234 -0.115"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M28.738 14.306l0.234 -0.115"/>
+    <path fill="#000" d="M24.168 28.806l0.168 0.2"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M24.168 28.806l0.168 0.2"/>
+    <path fill="#000" d="M8.816 28.826l-0.168 0.2"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M8.816 28.826l-0.168 0.2"/>
+    <path fill="#000" d="M16.559 4.97v-0.26"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M16.559 4.97v-0.26"/>
+  </svg>
+  <svg x="231">
+    <defs>
+      <mask id="p" mask-type="alpha">
+        <path fill="#0a84ff" d="M0 0h320v240h-320z" transform="matrix(.2 0 0 .2 -15.623 -12.404)"/>
+      </mask>
+      <mask id="o" mask-type="alpha">
+        <path fill="#0a84ff" d="M0 0h320v240h-320z" transform="matrix(.2 0 0 .2 -15.216 -8.977)"/>
+      </mask>
+    </defs>
+    <g mask="url(#o)">
+      <path fill="#FFF" d="M16.448 9.017l1.774 3.492 0.75 1.475 1.63 0.278 3.792 0.648 -2.76 3.007 -1.07 1.163 0.24 1.563 0.608 3.97 -3.447 -1.83 -1.552 -0.822 -1.546 0.83 -3.35 1.797 0.607 -3.943 0.241 -1.572 -1.082 -1.167 -2.777 -2.99 3.859 -0.65 1.674 -0.281 0.74 -1.528 1.667 -3.437"/>
+      <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.644" d="M16.448 9.017l1.774 3.492 0.75 1.475 1.63 0.278 3.792 0.648 -2.76 3.007 -1.07 1.163 0.24 1.563 0.608 3.97 -3.447 -1.83 -1.552 -0.822 -1.546 0.83 -3.35 1.797 0.607 -3.943 0.241 -1.572 -1.082 -1.167 -2.777 -2.99 3.859 -0.65 1.674 -0.281 0.74 -1.528 1.667 -3.437"/>
+    </g>
+    <g mask="url(#p)">
+      <path fill="#0A84FF" d="M16.495 9.857l2.332 4.727 5.217 0.758 -3.775 3.68 0.891 5.194 -4.665 -2.453 -4.666 2.453 0.891 -5.195 -3.774 -3.68 5.216 -0.757 2.333 -4.727z"/>
+      <path fill="none" d="M16.495 9.857l2.332 4.727 5.217 0.758 -3.775 3.68 0.891 5.194 -4.665 -2.453 -4.666 2.453 0.891 -5.195 -3.774 -3.68 5.216 -0.757 2.333 -4.727z"/>
+    </g>
+    <path fill="#000" d="M4.273 14.274l-0.772 -0.377"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M4.273 14.274l-0.772 -0.377"/>
+    <path fill="#000" d="M28.738 14.306s0.33 -0.16 0.772 -0.377"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M28.738 14.306s0.33 -0.16 0.772 -0.377"/>
+    <path fill="#000" d="M24.168 28.806l0.552 0.658"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M24.168 28.806l0.552 0.658"/>
+    <path fill="#000" d="M8.816 28.826l-0.552 0.657"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M8.816 28.826l-0.552 0.657"/>
+    <path fill="#000" d="M16.559 4.97v-0.859"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M16.559 4.97v-0.859"/>
+  </svg>
+  <svg x="264">
+    <defs>
+      <mask id="r" mask-type="alpha">
+        <path fill="#0a84ff" d="M0 0h320v240h-320z" transform="matrix(.2 0 0 .2 -15.623 -12.404)"/>
+      </mask>
+      <mask id="q" mask-type="alpha">
+        <path fill="#0a84ff" d="M0 0h320v240h-320z" transform="matrix(.2 0 0 .2 -15.216 -8.977)"/>
+      </mask>
+    </defs>
+    <g mask="url(#q)">
+      <path fill="#FFF" d="M16.437 8.692l1.85 3.64 0.781 1.538 1.7 0.29 3.953 0.675 -2.878 3.133 -1.115 1.213 0.25 1.63 0.633 4.137 -3.593 -1.906 -1.617 -0.858 -1.612 0.866 -3.491 1.873 0.632 -4.11 0.252 -1.639 -1.129 -1.216 -2.895 -3.118 4.023 -0.676 1.745 -0.294 0.772 -1.593 1.737 -3.583"/>
+      <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.714" d="M16.437 8.692l1.85 3.64 0.781 1.538 1.7 0.29 3.953 0.675 -2.878 3.133 -1.115 1.213 0.25 1.63 0.633 4.137 -3.593 -1.906 -1.617 -0.858 -1.612 0.866 -3.491 1.873 0.632 -4.11 0.252 -1.639 -1.129 -1.216 -2.895 -3.118 4.023 -0.676 1.745 -0.294 0.772 -1.593 1.737 -3.583"/>
+    </g>
+    <g mask="url(#r)">
+      <path fill="#0A84FF" d="M16.486 9.568l2.432 4.927 5.437 0.79 -3.935 3.835 0.93 5.415 -4.864 -2.557 -4.863 2.557 0.929 -5.415 -3.935 -3.835 5.437 -0.79 2.432 -4.927z"/>
+      <path fill="none" d="M16.486 9.568l2.432 4.927 5.437 0.79 -3.935 3.835 0.93 5.415 -4.864 -2.557 -4.863 2.557 0.929 -5.415 -3.935 -3.835 5.437 -0.79 2.432 -4.927z"/>
+    </g>
+    <path fill="#000" d="M4.273 14.274l-1.48 -0.722"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M4.273 14.274l-1.48 -0.722"/>
+    <path fill="#000" d="M28.738 14.306l1.48 -0.722"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M28.738 14.306l1.48 -0.722"/>
+    <path fill="#000" d="M24.168 28.806l1.058 1.26"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M24.168 28.806l1.058 1.26"/>
+    <path fill="#000" d="M8.816 28.826l-1.059 1.26"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M8.816 28.826l-1.059 1.26"/>
+    <path fill="#000" d="M16.559 4.97v-1.646"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M16.559 4.97v-1.646"/>
+  </svg>
+  <svg x="297">
+    <defs>
+      <mask id="t" mask-type="alpha">
+        <path fill="#0a84ff" d="M0 0h320v240h-320z" transform="matrix(.2 0 0 .2 -15.623 -12.404)"/>
+      </mask>
+      <mask id="s" mask-type="alpha">
+        <path fill="#0a84ff" d="M0 0h320v240h-320z" transform="matrix(.2 0 0 .2 -15.216 -8.977)"/>
+      </mask>
+    </defs>
+    <g mask="url(#s)">
+      <path fill="#FFF" d="M16.426 8.351l1.928 3.795 0.815 1.603 1.772 0.302 4.121 0.705 -3 3.267 -1.162 1.264 0.26 1.7 0.66 4.313 -3.746 -1.987 -1.686 -0.895 -1.68 0.903 -3.64 1.952 0.659 -4.285 0.262 -1.708 -1.176 -1.268 -3.018 -3.251 4.194 -0.705 1.819 -0.306 0.805 -1.66 1.811 -3.736"/>
+      <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.787" d="M16.426 8.351l1.928 3.795 0.815 1.603 1.772 0.302 4.121 0.705 -3 3.267 -1.162 1.264 0.26 1.7 0.66 4.313 -3.746 -1.987 -1.686 -0.895 -1.68 0.903 -3.64 1.952 0.659 -4.285 0.262 -1.708 -1.176 -1.268 -3.018 -3.251 4.194 -0.705 1.819 -0.306 0.805 -1.66 1.811 -3.736"/>
+    </g>
+    <g mask="url(#t)">
+      <path fill="#0A84FF" d="M16.477 9.264l2.535 5.137 5.669 0.824 -4.102 3.998 0.968 5.646 -5.07 -2.666 -5.07 2.666 0.968 -5.646 -4.102 -3.998 5.669 -0.824 2.535 -5.137z"/>
+      <path fill="none" d="M16.477 9.264l2.535 5.137 5.669 0.824 -4.102 3.998 0.968 5.646 -5.07 -2.666 -5.07 2.666 0.968 -5.646 -4.102 -3.998 5.669 -0.824 2.535 -5.137z"/>
+    </g>
+    <path fill="#000" d="M4.273 14.274l-2.281 -1.113"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M4.273 14.274l-2.281 -1.113"/>
+    <path fill="#000" d="M28.738 14.306l2.28 -1.112"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M28.738 14.306l2.28 -1.112"/>
+    <path fill="#000" d="M24.168 28.806l1.631 1.944"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M24.168 28.806l1.631 1.944"/>
+    <path fill="#000" d="M8.816 28.826l-1.631 1.943"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M8.816 28.826l-1.631 1.943"/>
+    <path fill="#000" d="M16.559 4.97v-2.537"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M16.559 4.97v-2.537"/>
+  </svg>
+  <svg x="330">
+    <defs>
+      <mask id="v" mask-type="alpha">
+        <g clip-path="url(#f10_BkV3WrqkR1)" transform="matrix(.2 0 0 .2 -15.623 -12.404)">
+          <path fill="#0a84ff" d="M0 0h320v240h-320z"/>
+        </g>
+      </mask>
+      <mask id="u" mask-type="alpha">
+        <g clip-path="url(#f10_4P5xKEAlF3)" transform="matrix(.2 0 0 .2 -15.216 -8.977)">
+          <path fill="#0a84ff" d="M0 0h320v240h-320z"/>
+        </g>
+      </mask>
+    </defs>
+    <g mask="url(#u)">
+      <path fill="#FFF" d="M16.415 8.021l2.005 3.945 0.847 1.667 1.842 0.314 4.284 0.732 -3.119 3.397 -1.208 1.314 0.27 1.766 0.687 4.484 -3.894 -2.065 -1.753 -0.93 -1.747 0.938 -3.784 2.03 0.685 -4.455 0.273 -1.776 -1.223 -1.318 -3.138 -3.38 4.36 -0.732 1.891 -0.318 0.837 -1.727 1.883 -3.883"/>
+      <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.858" d="M16.415 8.021l2.005 3.945 0.847 1.667 1.842 0.314 4.284 0.732 -3.119 3.397 -1.208 1.314 0.27 1.766 0.687 4.484 -3.894 -2.065 -1.753 -0.93 -1.747 0.938 -3.784 2.03 0.685 -4.455 0.273 -1.776 -1.223 -1.318 -3.138 -3.38 4.36 -0.732 1.891 -0.318 0.837 -1.727 1.883 -3.883"/>
+    </g>
+    <g mask="url(#v)">
+      <path fill="#0A84FF" d="M16.468 8.97l2.636 5.34 5.893 0.857 -4.265 4.156 1.007 5.87 -5.27 -2.771 -5.272 2.77 1.007 -5.869 -4.265 -4.156 5.894 -0.857 2.635 -5.34z"/>
+      <path fill="none" d="M16.468 8.97l2.636 5.34 5.893 0.857 -4.265 4.156 1.007 5.87 -5.27 -2.771 -5.272 2.77 1.007 -5.869 -4.265 -4.156 5.894 -0.857 2.635 -5.34z"/>
+    </g>
+    <path fill="#000" d="M4.273 14.274l-3.056 -1.49"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M4.273 14.274l-3.056 -1.49"/>
+    <path fill="#000" d="M28.738 14.306l3.056 -1.49"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M28.738 14.306l3.056 -1.49"/>
+    <path fill="#000" d="M24.168 28.806l2.186 2.605"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M24.168 28.806l2.186 2.605"/>
+    <path fill="#000" d="M8.816 28.826l-2.186 2.604"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M8.816 28.826l-2.186 2.604"/>
+    <path fill="#000" d="M16.559 4.97v-3.4"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M16.559 4.97v-3.4"/>
+  </svg>
+  <svg x="363">
+    <defs>
+      <mask id="x" mask-type="alpha">
+        <g clip-path="url(#f11_BkV3WrqkR1)" transform="matrix(.2 0 0 .2 -15.623 -12.404)">
+          <path fill="#0a84ff" d="M0 0h320v240h-320z"/>
+        </g>
+      </mask>
+      <mask id="w" mask-type="alpha">
+        <g clip-path="url(#f11_4P5xKEAlF3)" transform="matrix(.2 0 0 .2 -15.216 -8.977)">
+          <path fill="#0a84ff" d="M0 0h320v240h-320z"/>
+        </g>
+      </mask>
+    </defs>
+    <g mask="url(#w)">
+      <path fill="#FFF" d="M16.406 7.738l2.07 4.074 0.875 1.721 1.902 0.324 4.424 0.756 -3.221 3.508 -1.248 1.357 0.28 1.824 0.709 4.63 -4.022 -2.133 -1.81 -0.96 -1.804 0.97 -3.907 2.095 0.707 -4.6 0.282 -1.834 -1.263 -1.361 -3.24 -3.49 4.502 -0.757 1.953 -0.328 0.864 -1.783 1.945 -4.01"/>
+      <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.918" d="M16.406 7.738l2.07 4.074 0.875 1.721 1.902 0.324 4.424 0.756 -3.221 3.508 -1.248 1.357 0.28 1.824 0.709 4.63 -4.022 -2.133 -1.81 -0.96 -1.804 0.97 -3.907 2.095 0.707 -4.6 0.282 -1.834 -1.263 -1.361 -3.24 -3.49 4.502 -0.757 1.953 -0.328 0.864 -1.783 1.945 -4.01"/>
+    </g>
+    <g mask="url(#x)">
+      <path fill="#0A84FF" d="M16.46 8.718l2.722 5.515 6.086 0.884 -4.404 4.292 1.04 6.061 -5.443 -2.861 -5.444 2.861 1.04 -6.06 -4.404 -4.293 6.086 -0.884 2.722 -5.515z"/>
+      <path fill="none" d="M16.46 8.718l2.722 5.515 6.086 0.884 -4.404 4.292 1.04 6.061 -5.443 -2.861 -5.444 2.861 1.04 -6.06 -4.404 -4.293 6.086 -0.884 2.722 -5.515z"/>
+    </g>
+    <path fill="#000" d="M4.145 14.211l-2.928 -1.428"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M4.145 14.211l-2.928 -1.428"/>
+    <path fill="#000" d="M28.866 14.243l2.928 -1.428"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M28.866 14.243l2.928 -1.428"/>
+    <path fill="#000" d="M24.26 28.915l2.094 2.496"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M24.26 28.915l2.094 2.496"/>
+    <path fill="#000" d="M8.724 28.935l-2.094 2.495"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M8.724 28.935l-2.094 2.495"/>
+    <path fill="#000" d="M16.559 4.828v-3.258"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M16.559 4.828v-3.258"/>
+  </svg>
+  <svg x="396">
+    <defs>
+      <mask id="z" mask-type="alpha">
+        <g clip-path="url(#f12_BkV3WrqkR1)" transform="matrix(.2 0 0 .2 -15.623 -12.404)">
+          <path fill="#0a84ff" d="M0 0h320v240h-320z"/>
+        </g>
+      </mask>
+      <mask id="y" mask-type="alpha">
+        <g clip-path="url(#f12_4P5xKEAlF3)" transform="matrix(.2 0 0 .2 -15.216 -8.977)">
+          <path fill="#0a84ff" d="M0 0h320v240h-320z"/>
+        </g>
+      </mask>
+    </defs>
+    <g mask="url(#y)">
+      <path fill="#FFF" d="M16.401 7.59l2.104 4.141 0.89 1.75 1.933 0.33 4.497 0.768 -3.274 3.565 -1.269 1.38 0.284 1.854 0.721 4.707 -4.087 -2.169 -1.84 -0.975 -1.834 0.984 -3.972 2.131 0.72 -4.676 0.286 -1.864 -1.284 -1.384 -3.293 -3.547 4.576 -0.77 1.985 -0.333 0.878 -1.812 1.977 -4.077"/>
+      <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.95" d="M16.401 7.59l2.104 4.141 0.89 1.75 1.933 0.33 4.497 0.768 -3.274 3.565 -1.269 1.38 0.284 1.854 0.721 4.707 -4.087 -2.169 -1.84 -0.975 -1.834 0.984 -3.972 2.131 0.72 -4.676 0.286 -1.864 -1.284 -1.384 -3.293 -3.547 4.576 -0.77 1.985 -0.333 0.878 -1.812 1.977 -4.077"/>
+    </g>
+    <g mask="url(#z)">
+      <path fill="#0A84FF" d="M16.457 8.587l2.766 5.605 6.186 0.899 -4.476 4.363 1.056 6.16 -5.532 -2.908 -5.533 2.909 1.057 -6.161 -4.476 -4.363 6.185 -0.899 2.767 -5.605z"/>
+      <path fill="none" d="M16.457 8.587l2.766 5.605 6.186 0.899 -4.476 4.363 1.056 6.16 -5.532 -2.908 -5.533 2.909 1.057 -6.161 -4.476 -4.363 6.185 -0.899 2.767 -5.605z"/>
+    </g>
+    <path fill="#000" d="M3.835 14.06l-2.618 -1.277"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M3.835 14.06l-2.618 -1.277"/>
+    <path fill="#000" d="M29.176 14.092l2.618 -1.277"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M29.176 14.092l2.618 -1.277"/>
+    <path fill="#000" d="M24.481 29.18l1.873 2.23"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M24.481 29.18l1.873 2.23"/>
+    <path fill="#000" d="M8.502 29.199l-1.872 2.231"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M8.502 29.199l-1.872 2.231"/>
+    <path fill="#000" d="M16.559 4.483v-2.913"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M16.559 4.483v-2.913"/>
+  </svg>
+  <svg x="429">
+    <defs>
+      <mask id="B" mask-type="alpha">
+        <g clip-path="url(#f13_BkV3WrqkR1)" transform="matrix(.2 0 0 .2 -15.623 -12.404)">
+          <path fill="#0a84ff" d="M0 0h320v240h-320z"/>
+        </g>
+      </mask>
+      <mask id="A" mask-type="alpha">
+        <g clip-path="url(#f13_4P5xKEAlF3)" transform="matrix(.2 0 0 .2 -15.216 -8.977)">
+          <path fill="#0a84ff" d="M0 0h320v240h-320z"/>
+        </g>
+      </mask>
+    </defs>
+    <g mask="url(#A)">
+      <path fill="#FFF" d="M16.406 7.738l2.07 4.074 0.875 1.721 1.902 0.324 4.424 0.756 -3.221 3.508 -1.248 1.357 0.28 1.824 0.709 4.63 -4.022 -2.133 -1.81 -0.96 -1.804 0.97 -3.907 2.096 0.707 -4.6 0.282 -1.835 -1.263 -1.361 -3.24 -3.49 4.502 -0.757 1.953 -0.328 0.864 -1.783 1.945 -4.01"/>
+      <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.918" d="M16.406 7.738l2.07 4.074 0.875 1.721 1.902 0.324 4.424 0.756 -3.221 3.508 -1.248 1.357 0.28 1.824 0.709 4.63 -4.022 -2.133 -1.81 -0.96 -1.804 0.97 -3.907 2.096 0.707 -4.6 0.282 -1.835 -1.263 -1.361 -3.24 -3.49 4.502 -0.757 1.953 -0.328 0.864 -1.783 1.945 -4.01"/>
+    </g>
+    <g mask="url(#B)">
+      <path fill="#0A84FF" d="M16.46 8.718l2.722 5.515 6.086 0.884 -4.404 4.292 1.04 6.061 -5.444 -2.861 -5.443 2.861 1.04 -6.06 -4.404 -4.293 6.086 -0.884 2.721 -5.515z"/>
+      <path fill="none" d="M16.46 8.718l2.722 5.515 6.086 0.884 -4.404 4.292 1.04 6.061 -5.444 -2.861 -5.443 2.861 1.04 -6.06 -4.404 -4.293 6.086 -0.884 2.721 -5.515z"/>
+    </g>
+    <path fill="#000" d="M3.408 13.852l-2.191 -1.069"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M3.408 13.852l-2.191 -1.069"/>
+    <path fill="#000" d="M29.602 13.884l2.192 -1.069"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M29.602 13.884l2.192 -1.069"/>
+    <path fill="#000" d="M24.786 29.543l1.568 1.868"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M24.786 29.543l1.568 1.868"/>
+    <path fill="#000" d="M8.197 29.563l-1.567 1.867"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M8.197 29.563l-1.567 1.867"/>
+    <path fill="#000" d="M16.559 4.008v-2.438"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M16.559 4.008v-2.438"/>
+  </svg>
+  <svg x="462">
+    <defs>
+      <mask id="D" mask-type="alpha">
+        <g clip-path="url(#f14_BkV3WrqkR1)" transform="matrix(.2 0 0 .2 -15.623 -12.404)">
+          <path fill="#0a84ff" d="M0 0h320v240h-320z"/>
+        </g>
+      </mask>
+      <mask id="C" mask-type="alpha">
+        <g clip-path="url(#f14_4P5xKEAlF3)" transform="matrix(.2 0 0 .2 -15.216 -8.977)">
+          <path fill="#0a84ff" d="M0 0h320v240h-320z"/>
+        </g>
+      </mask>
+    </defs>
+    <g mask="url(#C)">
+      <path fill="#FFF" d="M16.413 7.97l2.017 3.968 0.852 1.677 1.853 0.316 4.31 0.736 -3.138 3.417 -1.216 1.322 0.272 1.777 0.691 4.51 -3.917 -2.078 -1.763 -0.935 -1.758 0.944 -3.805 2.042 0.688 -4.482 0.275 -1.786 -1.23 -1.326 -3.156 -3.4 4.386 -0.736 1.902 -0.32 0.841 -1.737 1.895 -3.906"/>
+      <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.869" d="M16.413 7.97l2.017 3.968 0.852 1.677 1.853 0.316 4.31 0.736 -3.138 3.417 -1.216 1.322 0.272 1.777 0.691 4.51 -3.917 -2.078 -1.763 -0.935 -1.758 0.944 -3.805 2.042 0.688 -4.482 0.275 -1.786 -1.23 -1.326 -3.156 -3.4 4.386 -0.736 1.902 -0.32 0.841 -1.737 1.895 -3.906"/>
+    </g>
+    <g mask="url(#D)">
+      <path fill="#0A84FF" d="M16.467 8.925l2.65 5.371 5.928 0.862 -4.289 4.18 1.013 5.905 -5.302 -2.788 -5.302 2.788 1.012 -5.904 -4.289 -4.181 5.928 -0.862 2.65 -5.371z"/>
+      <path fill="none" d="M16.467 8.925l2.65 5.371 5.928 0.862 -4.289 4.18 1.013 5.905 -5.302 -2.788 -5.302 2.788 1.012 -5.904 -4.289 -4.181 5.928 -0.862 2.65 -5.371z"/>
+    </g>
+    <path fill="#000" d="M2.901 13.605l-1.684 -0.822"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M2.901 13.605l-1.684 -0.822"/>
+    <path fill="#000" d="M30.109 13.637l1.685 -0.822"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M30.109 13.637l1.685 -0.822"/>
+    <path fill="#000" d="M25.149 29.975l1.205 1.436"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M25.149 29.975l1.205 1.436"/>
+    <path fill="#000" d="M7.835 29.994l-1.205 1.436"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M7.835 29.994l-1.205 1.436"/>
+    <path fill="#000" d="M16.559 3.445v-1.875"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M16.559 3.445v-1.875"/>
+  </svg>
+  <svg x="495">
+    <defs>
+      <mask id="F" mask-type="alpha">
+        <g clip-path="url(#f15_BkV3WrqkR1)" transform="matrix(.2 0 0 .2 -15.623 -12.404)">
+          <path fill="#0a84ff" d="M0 0h320v240h-320z"/>
+        </g>
+      </mask>
+      <mask id="E" mask-type="alpha">
+        <g clip-path="url(#f15_4P5xKEAlF3)" transform="matrix(.2 0 0 .2 -15.216 -8.977)">
+          <path fill="#0a84ff" d="M0 0h320v240h-320z"/>
+        </g>
+      </mask>
+    </defs>
+    <g mask="url(#E)">
+      <path fill="#FFF" d="M16.422 8.223l1.958 3.853 0.827 1.628 1.8 0.307 4.184 0.715 -3.047 3.317 -1.18 1.284 0.264 1.725 0.671 4.38 -3.804 -2.018 -1.712 -0.908 -1.706 0.917 -3.696 1.982 0.67 -4.35 0.266 -1.736 -1.195 -1.287 -3.064 -3.3 4.258 -0.716 1.848 -0.311 0.817 -1.686 1.839 -3.793"/>
+      <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.814" d="M16.422 8.223l1.958 3.853 0.827 1.628 1.8 0.307 4.184 0.715 -3.047 3.317 -1.18 1.284 0.264 1.725 0.671 4.38 -3.804 -2.018 -1.712 -0.908 -1.706 0.917 -3.696 1.982 0.67 -4.35 0.266 -1.736 -1.195 -1.287 -3.064 -3.3 4.258 -0.716 1.848 -0.311 0.817 -1.686 1.839 -3.793"/>
+    </g>
+    <g mask="url(#F)">
+      <path fill="#0A84FF" d="M16.473 9.15l2.575 5.216 5.755 0.836 -4.165 4.06 0.984 5.733 -5.149 -2.707 -5.148 2.707 0.984 -5.733 -4.165 -4.06 5.755 -0.836 2.574 -5.216z"/>
+      <path fill="none" d="M16.473 9.15l2.575 5.216 5.755 0.836 -4.165 4.06 0.984 5.733 -5.149 -2.707 -5.148 2.707 0.984 -5.733 -4.165 -4.06 5.755 -0.836 2.574 -5.216z"/>
+    </g>
+    <path fill="#000" d="M2.342 13.332l-1.125 -0.549"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M2.342 13.332l-1.125 -0.549"/>
+    <path fill="#000" d="M30.668 13.364l1.126 -0.549"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M30.668 13.364l1.126 -0.549"/>
+    <path fill="#000" d="M25.549 30.451l0.805 0.96"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M25.549 30.451l0.805 0.96"/>
+    <path fill="#000" d="M7.435 30.47l-0.805 0.96"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M7.435 30.47l-0.805 0.96"/>
+    <path fill="#000" d="M16.559 2.822v-1.252"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M16.559 2.822v-1.252"/>
+  </svg>
+  <svg x="528">
+    <defs>
+      <mask id="H" mask-type="alpha">
+        <g clip-path="url(#f16_BkV3WrqkR1)" transform="matrix(.2 0 0 .2 -15.623 -12.404)">
+          <path fill="#0a84ff" d="M0 0h320v240h-320z"/>
+        </g>
+      </mask>
+      <mask id="G" mask-type="alpha">
+        <g clip-path="url(#f16_4P5xKEAlF3)" transform="matrix(.2 0 0 .2 -15.216 -8.977)">
+          <path fill="#0a84ff" d="M0 0h320v240h-320z"/>
+        </g>
+      </mask>
+    </defs>
+    <g mask="url(#G)">
+      <path fill="#FFF" d="M16.43 8.48l1.899 3.736 0.802 1.579 1.745 0.297 4.057 0.693 -2.954 3.217 -1.144 1.245 0.255 1.673 0.651 4.247 -3.688 -1.957 -1.66 -0.88 -1.655 0.888 -3.583 1.923 0.649 -4.22 0.258 -1.681 -1.158 -1.249 -2.972 -3.2 4.13 -0.694 1.79 -0.301 0.793 -1.636 1.783 -3.677"/>
+      <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.759" d="M16.43 8.48l1.899 3.736 0.802 1.579 1.745 0.297 4.057 0.693 -2.954 3.217 -1.144 1.245 0.255 1.673 0.651 4.247 -3.688 -1.957 -1.66 -0.88 -1.655 0.888 -3.583 1.923 0.649 -4.22 0.258 -1.681 -1.158 -1.249 -2.972 -3.2 4.13 -0.694 1.79 -0.301 0.793 -1.636 1.783 -3.677"/>
+    </g>
+    <g mask="url(#H)">
+      <path fill="#0A84FF" d="M16.48 9.38l2.496 5.056 5.581 0.811 -4.038 3.937 0.953 5.559 -4.992 -2.625 -4.992 2.625 0.954 -5.559 -4.039 -3.937 5.581 -0.81 2.496 -5.058z"/>
+      <path fill="none" d="M16.48 9.38l2.496 5.056 5.581 0.811 -4.038 3.937 0.953 5.559 -4.992 -2.625 -4.992 2.625 0.954 -5.559 -4.039 -3.937 5.581 -0.81 2.496 -5.058z"/>
+    </g>
+    <path fill="#000" d="M1.758 13.047l-0.541 -0.264"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M1.758 13.047l-0.541 -0.264"/>
+    <path fill="#000" d="M31.253 13.08l0.54 -0.265"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M31.253 13.08l0.54 -0.265"/>
+    <path fill="#000" d="M25.967 30.95l0.387 0.46"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M25.967 30.95l0.387 0.46"/>
+    <path fill="#000" d="M7.017 30.97l-0.387 0.46"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M7.017 30.97l-0.387 0.46"/>
+    <path fill="#000" d="M16.559 2.172v-0.602"/>
+    <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-width="1.6" d="M16.559 2.172v-0.602"/>
+  </svg>
+  <svg x="561">
+    <defs>
+      <mask id="J" mask-type="alpha">
+        <g clip-path="url(#f17_BkV3WrqkR1)" transform="matrix(.2 0 0 .2 -15.623 -12.404)">
+          <path fill="#0a84ff" d="M0 0h320v240h-320z"/>
+        </g>
+      </mask>
+      <mask id="I" mask-type="alpha">
+        <g clip-path="url(#f17_4P5xKEAlF3)" transform="matrix(.2 0 0 .2 -15.216 -8.977)">
+          <path fill="#0a84ff" d="M0 0h320v240h-320z"/>
+        </g>
+      </mask>
+    </defs>
+    <g mask="url(#I)">
+      <path fill="#FFF" d="M16.438 8.731l1.84 3.622 0.779 1.53 1.69 0.289 3.934 0.672 -2.864 3.118 -1.109 1.207 0.248 1.622 0.631 4.116 -3.575 -1.896 -1.61 -0.854 -1.604 0.862 -3.473 1.863 0.628 -4.09 0.251 -1.63 -1.123 -1.21 -2.88 -3.103 4.002 -0.673 1.737 -0.292 0.768 -1.585 1.729 -3.565"/>
+      <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.706" d="M16.438 8.731l1.84 3.622 0.779 1.53 1.69 0.289 3.934 0.672 -2.864 3.118 -1.109 1.207 0.248 1.622 0.631 4.116 -3.575 -1.896 -1.61 -0.854 -1.604 0.862 -3.473 1.863 0.628 -4.09 0.251 -1.63 -1.123 -1.21 -2.88 -3.103 4.002 -0.673 1.737 -0.292 0.768 -1.585 1.729 -3.565"/>
+    </g>
+    <g mask="url(#J)">
+      <path fill="#0A84FF" d="M16.487 9.603l2.42 4.902 5.41 0.787 -3.915 3.816 0.924 5.388 -4.839 -2.544 -4.84 2.544 0.925 -5.388 -3.915 -3.816 5.41 -0.787 2.42 -4.902z"/>
+      <path fill="none" d="M16.487 9.603l2.42 4.902 5.41 0.787 -3.915 3.816 0.924 5.388 -4.839 -2.544 -4.84 2.544 0.925 -5.388 -3.915 -3.816 5.41 -0.787 2.42 -4.902z"/>
+    </g>
+  </svg>
+  <svg x="594">
+    <defs>
+      <mask id="L" mask-type="alpha">
+        <g clip-path="url(#f18_BkV3WrqkR1)" transform="matrix(.2 0 0 .2 -15.623 -12.404)">
+          <path fill="#0a84ff" d="M0 0h320v240h-320z"/>
+        </g>
+      </mask>
+      <mask id="K" mask-type="alpha">
+        <g clip-path="url(#f18_4P5xKEAlF3)" transform="matrix(.2 0 0 .2 -15.216 -8.977)">
+          <path fill="#0a84ff" d="M0 0h320v240h-320z"/>
+        </g>
+      </mask>
+    </defs>
+    <g mask="url(#K)">
+      <path fill="#FFF" d="M16.446 8.966l1.786 3.515 0.755 1.485 1.642 0.28 3.817 0.652 -2.78 3.027 -1.076 1.171 0.24 1.574 0.613 3.996 -3.47 -1.841 -1.562 -0.828 -1.557 0.836 -3.371 1.808 0.61 -3.97 0.243 -1.582 -1.09 -1.175 -2.795 -3.01 3.885 -0.654 1.685 -0.283 0.745 -1.539 1.679 -3.46"/>
+      <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.655" d="M16.446 8.966l1.786 3.515 0.755 1.485 1.642 0.28 3.817 0.652 -2.78 3.027 -1.076 1.171 0.24 1.574 0.613 3.996 -3.47 -1.841 -1.562 -0.828 -1.557 0.836 -3.371 1.808 0.61 -3.97 0.243 -1.582 -1.09 -1.175 -2.795 -3.01 3.885 -0.654 1.685 -0.283 0.745 -1.539 1.679 -3.46"/>
+    </g>
+    <g mask="url(#L)">
+      <path fill="#0A84FF" d="M16.493 9.811l2.349 4.759 5.25 0.763 -3.799 3.704 0.897 5.23 -4.697 -2.47 -4.696 2.47 0.897 -5.23 -3.8 -3.704 5.25 -0.763 2.35 -4.759z"/>
+      <path fill="none" d="M16.493 9.811l2.349 4.759 5.25 0.763 -3.799 3.704 0.897 5.23 -4.697 -2.47 -4.696 2.47 0.897 -5.23 -3.8 -3.704 5.25 -0.763 2.35 -4.759z"/>
+    </g>
+  </svg>
+  <svg x="627">
+    <defs>
+      <mask id="N" mask-type="alpha">
+        <g clip-path="url(#f19_BkV3WrqkR1)" transform="matrix(.2 0 0 .2 -15.623 -12.404)">
+          <path fill="#0a84ff" d="M0 0h320v240h-320z"/>
+        </g>
+      </mask>
+      <mask id="M" mask-type="alpha">
+        <g clip-path="url(#f19_4P5xKEAlF3)" transform="matrix(.2 0 0 .2 -15.216 -8.977)">
+          <path fill="#0a84ff" d="M0 0h320v240h-320z"/>
+        </g>
+      </mask>
+    </defs>
+    <g mask="url(#M)">
+      <path fill="#FFF" d="M16.453 9.164l1.74 3.425 0.735 1.447 1.6 0.273 3.719 0.635 -2.708 2.95 -1.049 1.14 0.235 1.534 0.596 3.893 -3.38 -1.794 -1.523 -0.807 -1.516 0.815 -3.285 1.762 0.595 -3.868 0.237 -1.542 -1.062 -1.144 -2.724 -2.934 3.785 -0.636 1.642 -0.276 0.726 -1.499 1.635 -3.371"/>
+      <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.613" d="M16.453 9.164l1.74 3.425 0.735 1.447 1.6 0.273 3.719 0.635 -2.708 2.95 -1.049 1.14 0.235 1.534 0.596 3.893 -3.38 -1.794 -1.523 -0.807 -1.516 0.815 -3.285 1.762 0.595 -3.868 0.237 -1.542 -1.062 -1.144 -2.724 -2.934 3.785 -0.636 1.642 -0.276 0.726 -1.499 1.635 -3.371"/>
+    </g>
+    <g mask="url(#N)">
+      <path fill="#0A84FF" d="M16.499 9.988l2.288 4.636 5.116 0.744 -3.702 3.608 0.874 5.096 -4.576 -2.406 -4.576 2.406 0.874 -5.096 -3.702 -3.608 5.116 -0.744 2.288 -4.636z"/>
+      <path fill="none" d="M16.499 9.988l2.288 4.636 5.116 0.744 -3.702 3.608 0.874 5.096 -4.576 -2.406 -4.576 2.406 0.874 -5.096 -3.702 -3.608 5.116 -0.744 2.288 -4.636z"/>
+    </g>
+  </svg>
+  <svg x="660">
+    <defs>
+      <mask id="P" mask-type="alpha">
+        <g clip-path="url(#f20_BkV3WrqkR1)" transform="matrix(0 0 0 0 16.352 17.593)">
+          <path fill="#0a84ff" d="M0 0h320v240h-320z"/>
+        </g>
+      </mask>
+      <mask id="O" mask-type="alpha">
+        <g clip-path="url(#f20_4P5xKEAlF3)" transform="matrix(0 0 0 0 16.463 17.517)">
+          <path fill="#0a84ff" d="M0 0h320v240h-320z"/>
+        </g>
+      </mask>
+    </defs>
+    <path fill="none" stroke="context-fill" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.584" d="M16.457 9.307l1.71 3.363 0.722 1.422 1.57 0.267 3.653 0.624 -2.66 2.897 -1.03 1.12 0.23 1.506 0.587 3.824 -3.32 -1.762 -1.496 -0.792 -1.49 0.8 -3.225 1.73 0.584 -3.798 0.233 -1.514 -1.043 -1.124 -2.676 -2.882 3.718 -0.624 1.613 -0.272 0.713 -1.472 1.606 -3.31" display="block"/>
+    <g mask="url(#O)">
+      <path fill="#FFF" d="M16.456 9.271l1.716 3.376 0.725 1.427 1.577 0.269 3.666 0.626 -2.67 2.907 -1.033 1.125 0.23 1.512 0.589 3.838 -3.333 -1.768 -1.5 -0.796 -1.496 0.803 -3.238 1.737 0.586 -3.813 0.234 -1.52 -1.047 -1.128 -2.686 -2.892 3.732 -0.627 1.619 -0.273 0.716 -1.477 1.612 -3.324"/>
+      <path fill="none" stroke="#0A84FF" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.59" d="M16.456 9.271l1.716 3.376 0.725 1.427 1.577 0.269 3.666 0.626 -2.67 2.907 -1.033 1.125 0.23 1.512 0.589 3.838 -3.333 -1.768 -1.5 -0.796 -1.496 0.803 -3.238 1.737 0.586 -3.813 0.234 -1.52 -1.047 -1.128 -2.686 -2.892 3.732 -0.627 1.619 -0.273 0.716 -1.477 1.612 -3.324"/>
+    </g>
+    <g mask="url(#P)" opacity=".08">
+      <path fill="context-fill" d="M16.502 10.083l2.255 4.57 5.044 0.734 -3.65 3.557 0.862 5.023 -4.511 -2.371 -4.512 2.371 0.862 -5.023 -3.65 -3.557 5.044 -0.733 2.256 -4.57z"/>
+      <path fill="none" d="M16.502 10.083l2.255 4.57 5.044 0.734 -3.65 3.557 0.862 5.023 -4.511 -2.371 -4.512 2.371 0.862 -5.023 -3.65 -3.557 5.044 -0.733 2.256 -4.57z"/>
+    </g>
+  </svg>
+</svg>
new file mode 100644
--- /dev/null
+++ b/browser/themes/shared/icons/library-bookmark-animation.svg
@@ -0,0 +1,635 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+   - License, v. 2.0. If a copy of the MPL was not distributed with this
+   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<svg xmlns="http://www.w3.org/2000/svg" width="1078" height="54" fill="context-fill">
+  <svg>
+    <path d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z"/>
+  </svg>
+  <svg x="22">
+    <defs>
+      <mask id="a" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.108 28.313)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-1.454 -10.124l-7.75 24.312 10.687 6 2.75 -0.375 1.5 -0.125 1.125 2.32 2.75 0.055 0.375 -1.07 1.625 -0.008 3.393 0.005 4.67 12.7 2.062 -19.564 3 -12.625 -0.375 -11.125 -25.813 -0.5z"/>
+      </mask>
+    </defs>
+    <path d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z"/>
+    <g mask="url(#a)" opacity=".043">
+      <path fill="rgb(48,163,255)" d="M13.593 1.683l0.46 3.355 0.193 1.418 1.254 0.69 2.914 1.604 -3.108 1.673 -1.204 0.647 -0.247 1.345 -0.628 3.414 -2.298 -2.47 -1.034 -1.113 -1.498 0.24 -3.246 0.519 1.614 -3.05 0.643 -1.215 -0.554 -1.26 -1.42 -3.23 3.336 0.564 1.447 0.244 1.038 -1.038 2.336 -2.335"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.422" d="M13.593 1.683l0.46 3.355 0.193 1.418 1.254 0.69 2.914 1.604 -3.108 1.673 -1.204 0.647 -0.247 1.345 -0.628 3.414 -2.298 -2.47 -1.034 -1.113 -1.498 0.24 -3.246 0.519 1.614 -3.05 0.643 -1.215 -0.554 -1.26 -1.42 -3.23 3.336 0.564 1.447 0.244 1.038 -1.038 2.336 -2.335"/>
+    </g>
+  </svg>
+  <svg x="44">
+    <defs>
+      <mask id="b" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.108 28.313)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-1.454 -10.124l-7.75 24.312 10.687 6 2.75 -0.375 1.5 -0.125 1.125 2.32 2.75 0.055 0.375 -1.07 1.625 -0.008 3.393 0.005 4.67 12.7 2.062 -19.564 3 -12.625 -0.375 -11.125 -25.813 -0.5z"/>
+      </mask>
+    </defs>
+    <path d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z"/>
+    <g mask="url(#b)" opacity=".156">
+      <path fill="rgb(48,163,255)" d="M13.328 1.594l0.588 3.314 0.248 1.4 1.272 0.636 2.957 1.48 -3.02 1.783 -1.17 0.69 -0.194 1.346 -0.49 3.416 -2.378 -2.364 -1.072 -1.064 -1.478 0.297 -3.203 0.643 1.482 -3.092 0.592 -1.233 -0.6 -1.23 -1.538 -3.152 3.336 0.429 1.447 0.186 0.99 -1.072 2.229 -2.412"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.413" d="M13.328 1.594l0.588 3.314 0.248 1.4 1.272 0.636 2.957 1.48 -3.02 1.783 -1.17 0.69 -0.194 1.346 -0.49 3.416 -2.378 -2.364 -1.072 -1.064 -1.478 0.297 -3.203 0.643 1.482 -3.092 0.592 -1.233 -0.6 -1.23 -1.538 -3.152 3.336 0.429 1.447 0.186 0.99 -1.072 2.229 -2.412"/>
+    </g>
+  </svg>
+  <svg x="66">
+    <defs>
+      <mask id="c" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.108 28.313)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-1.454 -10.124l-7.75 24.312 10.687 6 2.75 -0.375 1.5 -0.125 1.125 2.32 2.75 0.055 0.375 -1.07 1.625 -0.008 3.393 0.005 4.67 12.7 2.062 -19.564 3 -12.625 -0.375 -11.125 -25.813 -0.5z"/>
+      </mask>
+    </defs>
+    <path d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z"/>
+    <g mask="url(#c)" opacity=".316">
+      <path fill="rgb(48,163,255)" d="M12.953 1.508l0.766 3.249 0.323 1.373 1.295 0.558 3.009 1.3 -2.892 1.934 -1.12 0.748 -0.117 1.342 -0.295 3.41 -2.486 -2.209 -1.12 -0.994 -1.447 0.376 -3.135 0.814 1.296 -3.143 0.517 -1.254 -0.661 -1.184 -1.698 -3.036 3.327 0.24 1.442 0.105 0.92 -1.117 2.074 -2.51"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.401" d="M12.953 1.508l0.766 3.249 0.323 1.373 1.295 0.558 3.009 1.3 -2.892 1.934 -1.12 0.748 -0.117 1.342 -0.295 3.41 -2.486 -2.209 -1.12 -0.994 -1.447 0.376 -3.135 0.814 1.296 -3.143 0.517 -1.254 -0.661 -1.184 -1.698 -3.036 3.327 0.24 1.442 0.105 0.92 -1.117 2.074 -2.51"/>
+    </g>
+  </svg>
+  <svg x="88">
+    <defs>
+      <mask id="d" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.108 28.313)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-1.454 -10.124l-7.75 24.312 10.687 6 2.75 -0.375 1.5 -0.125 1.125 2.32 2.75 0.055 0.375 -1.07 1.625 -0.008 3.393 0.005 4.67 12.7 2.062 -19.564 3 -12.625 -0.375 -11.125 -25.813 -0.5z"/>
+      </mask>
+    </defs>
+    <path d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z"/>
+    <g mask="url(#d)" opacity=".5">
+      <path fill="rgb(48,163,255)" d="M12.525 1.445l0.963 3.162 0.406 1.336 1.315 0.47 3.056 1.094 -2.735 2.093 -1.06 0.81 -0.03 1.335 -0.075 3.387 -2.597 -2.025 -1.17 -0.91 -1.405 0.463 -3.047 1.002 1.082 -3.188 0.431 -1.271 -0.729 -1.128 -1.87 -2.892 3.303 0.026 1.432 0.011 0.839 -1.161 1.89 -2.612"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.388" d="M12.525 1.445l0.963 3.162 0.406 1.336 1.315 0.47 3.056 1.094 -2.735 2.093 -1.06 0.81 -0.03 1.335 -0.075 3.387 -2.597 -2.025 -1.17 -0.91 -1.405 0.463 -3.047 1.002 1.082 -3.188 0.431 -1.271 -0.729 -1.128 -1.87 -2.892 3.303 0.026 1.432 0.011 0.839 -1.161 1.89 -2.612"/>
+    </g>
+  </svg>
+  <svg x="110">
+    <defs>
+      <mask id="e" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.108 28.313)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-1.454 -10.124l-7.75 24.312 10.687 6 2.75 -0.375 1.5 -0.125 1.125 2.32 2.75 0.055 0.375 -1.07 1.625 -0.008 3.393 0.005 4.67 12.7 2.062 -19.564 3 -12.625 -0.375 -11.125 -25.813 -0.5z"/>
+      </mask>
+    </defs>
+    <path d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z"/>
+    <g mask="url(#e)" opacity=".684">
+      <path fill="rgb(48,163,255)" d="M12.101 1.412l1.152 3.062 0.486 1.294 1.329 0.381 3.089 0.888 -2.57 2.242 -0.995 0.867 0.055 1.32 0.14 3.352 -2.695 -1.836 -1.213 -0.826 -1.36 0.547 -2.946 1.184 0.867 -3.219 0.345 -1.283 -0.791 -1.068 -2.03 -2.74 3.263 -0.183 1.416 -0.08 0.755 -1.2 1.702 -2.7"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.374" d="M12.101 1.412l1.152 3.062 0.486 1.294 1.329 0.381 3.089 0.888 -2.57 2.242 -0.995 0.867 0.055 1.32 0.14 3.352 -2.695 -1.836 -1.213 -0.826 -1.36 0.547 -2.946 1.184 0.867 -3.219 0.345 -1.283 -0.791 -1.068 -2.03 -2.74 3.263 -0.183 1.416 -0.08 0.755 -1.2 1.702 -2.7"/>
+    </g>
+  </svg>
+  <svg x="132">
+    <defs>
+      <mask id="f" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.108 28.313)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-1.454 -10.124l-7.75 24.312 10.687 6 2.75 -0.375 1.5 -0.125 1.125 2.32 2.75 0.055 0.375 -1.07 1.625 -0.008 3.393 0.005 4.67 12.7 2.062 -19.564 3 -12.625 -0.375 -11.125 -25.813 -0.5z"/>
+      </mask>
+    </defs>
+    <path d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z"/>
+    <g mask="url(#f)" opacity=".844">
+      <path fill="rgb(48,163,255)" d="M11.736 1.4l1.31 2.967 0.552 1.254 1.337 0.304 3.106 0.707 -2.419 2.361 -0.937 0.914 0.127 1.303 0.324 3.31 -2.768 -1.668 -1.246 -0.75 -1.316 0.616 -2.85 1.335 0.68 -3.233 0.27 -1.29 -0.842 -1.013 -2.162 -2.599 3.22 -0.362 1.397 -0.157 0.682 -1.23 1.534 -2.767"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.362" d="M11.736 1.4l1.31 2.967 0.552 1.254 1.337 0.304 3.106 0.707 -2.419 2.361 -0.937 0.914 0.127 1.303 0.324 3.31 -2.768 -1.668 -1.246 -0.75 -1.316 0.616 -2.85 1.335 0.68 -3.233 0.27 -1.29 -0.842 -1.013 -2.162 -2.599 3.22 -0.362 1.397 -0.157 0.682 -1.23 1.534 -2.767"/>
+    </g>
+  </svg>
+  <svg x="154">
+    <defs>
+      <mask id="g" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.108 28.313)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-1.454 -10.124l-7.75 24.312 10.687 6 2.75 -0.375 1.5 -0.125 1.125 2.32 2.75 0.055 0.375 -1.07 1.625 -0.008 3.393 0.005 4.67 12.7 2.062 -19.564 3 -12.625 -0.375 -11.125 -25.813 -0.5z"/>
+      </mask>
+    </defs>
+    <path d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z"/>
+    <g mask="url(#g)" opacity=".957">
+      <path fill="rgb(48,163,255)" d="M11.481 1.392l1.417 2.895 0.598 1.224 1.34 0.249 3.111 0.58 -2.309 2.44 -0.894 0.944 0.177 1.289 0.452 3.273 -2.814 -1.547 -1.267 -0.696 -1.282 0.664 -2.779 1.437 0.548 -3.237 0.219 -1.291 -0.877 -0.973 -2.248 -2.496 3.184 -0.486 1.38 -0.21 0.628 -1.249 1.415 -2.808"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.353" d="M11.481 1.392l1.417 2.895 0.598 1.224 1.34 0.249 3.111 0.58 -2.309 2.44 -0.894 0.944 0.177 1.289 0.452 3.273 -2.814 -1.547 -1.267 -0.696 -1.282 0.664 -2.779 1.437 0.548 -3.237 0.219 -1.291 -0.877 -0.973 -2.248 -2.496 3.184 -0.486 1.38 -0.21 0.628 -1.249 1.415 -2.808"/>
+    </g>
+  </svg>
+  <svg x="176">
+    <defs>
+      <mask id="h" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.108 28.313)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-1.454 -10.124l-7.75 24.312 10.687 6 2.75 -0.375 1.5 -0.125 1.125 2.32 2.75 0.055 0.375 -1.07 1.625 -0.008 3.393 0.005 4.67 12.7 2.062 -19.564 3 -12.625 -0.375 -11.125 -25.813 -0.5z"/>
+      </mask>
+    </defs>
+    <path d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z"/>
+    <g mask="url(#h)">
+      <path fill="rgb(48,163,255)" d="M11.386 1.366l1.456 2.867 0.615 1.211 1.34 0.228 3.113 0.532 -2.267 2.469 -0.878 0.955 0.196 1.283 0.5 3.259 -2.83 -1.501 -1.275 -0.676 -1.269 0.682 -2.75 1.475 0.499 -3.237 0.198 -1.291 -0.889 -0.958 -2.28 -2.456 3.169 -0.532 1.373 -0.231 0.608 -1.255 1.37 -2.822"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M11.386 1.366l1.456 2.867 0.615 1.211 1.34 0.228 3.113 0.532 -2.267 2.469 -0.878 0.955 0.196 1.283 0.5 3.259 -2.83 -1.501 -1.275 -0.676 -1.269 0.682 -2.75 1.475 0.499 -3.237 0.198 -1.291 -0.889 -0.958 -2.28 -2.456 3.169 -0.532 1.373 -0.231 0.608 -1.255 1.37 -2.822"/>
+    </g>
+  </svg>
+  <svg x="198">
+    <defs>
+      <mask id="i" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.108 28.313)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-1.454 -10.124l-7.75 24.312 10.687 6 2.75 -0.375 1.5 -0.125 1.125 2.32 2.75 0.055 0.375 -1.07 1.625 -0.008 3.393 0.005 4.67 12.7 2.062 -19.564 3 -12.625 -0.375 -11.125 -25.813 -0.5z"/>
+      </mask>
+    </defs>
+    <path d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z"/>
+    <g mask="url(#i)">
+      <path fill="rgb(48,163,255)" d="M11.333 1.416l1.48 2.854 0.625 1.206 1.341 0.218 3.118 0.506 -2.247 2.487 -0.87 0.962 0.207 1.282 0.526 3.254 -2.842 -1.478 -1.28 -0.665 -1.263 0.692 -2.738 1.498 0.471 -3.241 0.188 -1.293 -0.896 -0.95 -2.3 -2.437 3.163 -0.558 1.372 -0.243 0.598 -1.26 1.346 -2.833"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M11.333 1.416l1.48 2.854 0.625 1.206 1.341 0.218 3.118 0.506 -2.247 2.487 -0.87 0.962 0.207 1.282 0.526 3.254 -2.842 -1.478 -1.28 -0.665 -1.263 0.692 -2.738 1.498 0.471 -3.241 0.188 -1.293 -0.896 -0.95 -2.3 -2.437 3.163 -0.558 1.372 -0.243 0.598 -1.26 1.346 -2.833"/>
+    </g>
+  </svg>
+  <svg x="220">
+    <defs>
+      <mask id="j" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.108 28.313)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-1.454 -10.124l-7.75 24.312 10.687 6 2.75 -0.375 1.5 -0.125 1.125 2.32 2.75 0.055 0.375 -1.07 1.625 -0.008 3.393 0.005 4.67 12.7 2.062 -19.564 3 -12.625 -0.375 -11.125 -25.813 -0.5z"/>
+      </mask>
+    </defs>
+    <path d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z"/>
+    <g mask="url(#j)">
+      <path fill="rgb(48,163,255)" d="M11.26 1.479l1.512 2.837 0.639 1.2 1.343 0.201 3.123 0.471 -2.217 2.512 -0.86 0.973 0.222 1.279 0.563 3.248 -2.859 -1.445 -1.287 -0.65 -1.256 0.706 -2.72 1.528 0.435 -3.246 0.173 -1.295 -0.908 -0.94 -2.328 -2.41 3.158 -0.595 1.369 -0.258 0.583 -1.266 1.313 -2.848"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M11.26 1.479l1.512 2.837 0.639 1.2 1.343 0.201 3.123 0.471 -2.217 2.512 -0.86 0.973 0.222 1.279 0.563 3.248 -2.859 -1.445 -1.287 -0.65 -1.256 0.706 -2.72 1.528 0.435 -3.246 0.173 -1.295 -0.908 -0.94 -2.328 -2.41 3.158 -0.595 1.369 -0.258 0.583 -1.266 1.313 -2.848"/>
+    </g>
+  </svg>
+  <svg x="242">
+    <defs>
+      <mask id="k" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.108 28.313)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-1.454 -10.124l-7.75 24.312 10.687 6 2.75 -0.375 1.5 -0.125 1.125 2.32 2.75 0.055 0.375 -1.07 1.625 -0.008 3.393 0.005 4.67 12.7 2.062 -19.564 3 -12.625 -0.375 -11.125 -25.813 -0.5z"/>
+      </mask>
+    </defs>
+    <path d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z"/>
+    <g mask="url(#k)">
+      <path fill="rgb(48,163,255)" d="M11.174 1.557l1.55 2.817 0.655 1.19 1.346 0.185 3.129 0.43 -2.184 2.54 -0.847 0.984 0.239 1.277 0.606 3.24 -2.878 -1.408 -1.296 -0.633 -1.246 0.723 -2.7 1.565 0.392 -3.252 0.156 -1.297 -0.92 -0.928 -2.36 -2.379 3.15 -0.636 1.365 -0.277 0.567 -1.273 1.275 -2.866"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M11.174 1.557l1.55 2.817 0.655 1.19 1.346 0.185 3.129 0.43 -2.184 2.54 -0.847 0.984 0.239 1.277 0.606 3.24 -2.878 -1.408 -1.296 -0.633 -1.246 0.723 -2.7 1.565 0.392 -3.252 0.156 -1.297 -0.92 -0.928 -2.36 -2.379 3.15 -0.636 1.365 -0.277 0.567 -1.273 1.275 -2.866"/>
+    </g>
+  </svg>
+  <svg x="264">
+    <defs>
+      <mask id="l" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.108 28.313)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-1.454 -10.124l-7.75 24.312 10.687 6 2.75 -0.375 1.5 -0.125 1.125 2.32 2.75 0.055 0.375 -1.07 1.625 -0.008 3.393 0.005 4.67 12.7 2.062 -19.564 3 -12.625 -0.375 -11.125 -25.813 -0.5z"/>
+      </mask>
+    </defs>
+    <path d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z"/>
+    <g mask="url(#l)">
+      <path fill="rgb(48,163,255)" d="M11.08 1.652l1.592 2.794 0.671 1.181 1.349 0.165 3.135 0.383 -2.147 2.573 -0.833 0.996 0.258 1.273 0.653 3.23 -2.898 -1.365 -1.305 -0.614 -1.235 0.741 -2.677 1.604 0.344 -3.257 0.137 -1.3 -0.933 -0.914 -2.394 -2.345 3.14 -0.682 1.361 -0.296 0.548 -1.282 1.234 -2.883"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M11.08 1.652l1.592 2.794 0.671 1.181 1.349 0.165 3.135 0.383 -2.147 2.573 -0.833 0.996 0.258 1.273 0.653 3.23 -2.898 -1.365 -1.305 -0.614 -1.235 0.741 -2.677 1.604 0.344 -3.257 0.137 -1.3 -0.933 -0.914 -2.394 -2.345 3.14 -0.682 1.361 -0.296 0.548 -1.282 1.234 -2.883"/>
+    </g>
+  </svg>
+  <svg x="286">
+    <defs>
+      <mask id="m" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.108 28.313)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-1.454 -10.124l-7.75 24.312 10.687 6 2.75 -0.375 1.5 -0.125 1.125 2.32 2.75 0.055 0.375 -1.07 1.625 -0.008 3.393 0.005 4.67 12.7 2.062 -19.564 3 -12.625 -0.375 -11.125 -25.813 -0.5z"/>
+      </mask>
+    </defs>
+    <path d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z"/>
+    <g mask="url(#m)">
+      <path fill="rgb(48,163,255)" d="M10.982 1.764l1.633 2.77 0.69 1.17 1.351 0.144 3.14 0.335 -2.107 2.606 -0.817 1.008 0.277 1.269 0.703 3.22 -2.919 -1.32 -1.314 -0.594 -1.224 0.76 -2.652 1.644 0.294 -3.262 0.117 -1.3 -0.947 -0.9 -2.43 -2.309 3.13 -0.73 1.356 -0.317 0.528 -1.29 1.19 -2.902"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M10.982 1.764l1.633 2.77 0.69 1.17 1.351 0.144 3.14 0.335 -2.107 2.606 -0.817 1.008 0.277 1.269 0.703 3.22 -2.919 -1.32 -1.314 -0.594 -1.224 0.76 -2.652 1.644 0.294 -3.262 0.117 -1.3 -0.947 -0.9 -2.43 -2.309 3.13 -0.73 1.356 -0.317 0.528 -1.29 1.19 -2.902"/>
+    </g>
+  </svg>
+  <svg x="308">
+    <defs>
+      <mask id="n" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.108 28.313)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-1.454 -10.124l-7.75 24.312 10.687 6 2.75 -0.375 1.5 -0.125 1.125 2.32 2.75 0.055 0.375 -1.07 1.625 -0.008 3.393 0.005 4.67 12.7 2.062 -19.564 3 -12.625 -0.375 -11.125 -25.813 -0.5z"/>
+      </mask>
+    </defs>
+    <path d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z"/>
+    <g mask="url(#n)">
+      <path fill="rgb(48,163,255)" d="M10.879 1.895l1.677 2.743 0.709 1.159 1.353 0.122 3.145 0.285 -2.065 2.64 -0.8 1.02 0.296 1.265 0.755 3.209 -2.94 -1.274 -1.323 -0.573 -1.212 0.78 -2.625 1.686 0.242 -3.266 0.096 -1.303 -0.961 -0.885 -2.467 -2.268 3.117 -0.78 1.351 -0.339 0.508 -1.298 1.142 -2.921"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M10.879 1.895l1.677 2.743 0.709 1.159 1.353 0.122 3.145 0.285 -2.065 2.64 -0.8 1.02 0.296 1.265 0.755 3.209 -2.94 -1.274 -1.323 -0.573 -1.212 0.78 -2.625 1.686 0.242 -3.266 0.096 -1.303 -0.961 -0.885 -2.467 -2.268 3.117 -0.78 1.351 -0.339 0.508 -1.298 1.142 -2.921"/>
+    </g>
+  </svg>
+  <svg x="330">
+    <defs>
+      <mask id="o" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.108 28.313)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-1.454 -10.124l-7.75 24.312 10.687 6 2.75 -0.375 1.5 -0.125 1.125 2.32 2.75 0.055 0.375 -1.07 1.625 -0.008 3.393 0.005 4.67 12.7 2.062 -19.564 3 -12.625 -0.375 -11.125 -25.813 -0.5z"/>
+      </mask>
+    </defs>
+    <path d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z"/>
+    <g mask="url(#o)">
+      <path fill="rgb(48,163,255)" d="M10.772 2.046l1.723 2.715 0.728 1.147 1.354 0.1 3.15 0.233 -2.022 2.673 -0.783 1.034 0.318 1.26 0.807 3.195 -2.96 -1.225 -1.333 -0.551 -1.198 0.8 -2.597 1.73 0.187 -3.27 0.075 -1.305 -0.976 -0.868 -2.503 -2.228 3.103 -0.831 1.346 -0.361 0.486 -1.307 1.094 -2.94"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M10.772 2.046l1.723 2.715 0.728 1.147 1.354 0.1 3.15 0.233 -2.022 2.673 -0.783 1.034 0.318 1.26 0.807 3.195 -2.96 -1.225 -1.333 -0.551 -1.198 0.8 -2.597 1.73 0.187 -3.27 0.075 -1.305 -0.976 -0.868 -2.503 -2.228 3.103 -0.831 1.346 -0.361 0.486 -1.307 1.094 -2.94"/>
+    </g>
+  </svg>
+  <svg x="352">
+    <defs>
+      <mask id="p" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.108 28.313)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-1.454 -10.124l-7.75 24.312 10.687 6 2.75 -0.375 1.5 -0.125 1.125 2.32 2.75 0.055 0.375 -1.07 1.625 -0.008 3.393 0.005 4.67 12.7 2.062 -19.564 3 -12.625 -0.375 -11.125 -25.813 -0.5z"/>
+      </mask>
+    </defs>
+    <path d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z"/>
+    <g mask="url(#p)">
+      <path fill="rgb(48,163,255)" d="M10.663 2.218l1.769 2.686 0.747 1.135 1.356 0.076 3.153 0.18 -1.976 2.707 -0.766 1.048 0.339 1.253 0.861 3.182 -2.98 -1.175 -1.342 -0.529 -1.185 0.82 -2.567 1.774 0.132 -3.273 0.053 -1.305 -0.99 -0.852 -2.541 -2.185 3.089 -0.884 1.339 -0.384 0.464 -1.314 1.044 -2.958"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M10.663 2.218l1.769 2.686 0.747 1.135 1.356 0.076 3.153 0.18 -1.976 2.707 -0.766 1.048 0.339 1.253 0.861 3.182 -2.98 -1.175 -1.342 -0.529 -1.185 0.82 -2.567 1.774 0.132 -3.273 0.053 -1.305 -0.99 -0.852 -2.541 -2.185 3.089 -0.884 1.339 -0.384 0.464 -1.314 1.044 -2.958"/>
+    </g>
+  </svg>
+  <svg x="374">
+    <defs>
+      <mask id="q" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.108 28.313)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-1.454 -10.124l-7.75 24.312 10.687 6 2.75 -0.375 1.5 -0.125 1.125 2.32 2.75 0.055 0.375 -1.07 1.625 -0.008 3.393 0.005 4.67 12.7 2.062 -19.564 3 -12.625 -0.375 -11.125 -25.813 -0.5z"/>
+      </mask>
+    </defs>
+    <path d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z"/>
+    <g mask="url(#q)">
+      <path fill="rgb(48,163,255)" d="M10.552 2.414l1.815 2.655 0.766 1.122 1.357 0.053 3.156 0.126 -1.929 2.74 -0.748 1.06 0.36 1.248 0.917 3.167 -3 -1.124 -1.351 -0.505 -1.17 0.84 -2.537 1.817 0.076 -3.274 0.03 -1.306 -1.005 -0.835 -2.578 -2.14 3.073 -0.937 1.333 -0.407 0.44 -1.323 0.994 -2.975"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M10.552 2.414l1.815 2.655 0.766 1.122 1.357 0.053 3.156 0.126 -1.929 2.74 -0.748 1.06 0.36 1.248 0.917 3.167 -3 -1.124 -1.351 -0.505 -1.17 0.84 -2.537 1.817 0.076 -3.274 0.03 -1.306 -1.005 -0.835 -2.578 -2.14 3.073 -0.937 1.333 -0.407 0.44 -1.323 0.994 -2.975"/>
+    </g>
+  </svg>
+  <svg x="396">
+    <defs>
+      <mask id="r" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.108 28.313)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-1.454 -10.124l-7.75 24.312 10.687 6 2.75 -0.375 1.5 -0.125 1.125 2.32 2.75 0.055 0.375 -1.07 1.625 -0.008 3.393 0.005 4.67 12.7 2.062 -19.564 3 -12.625 -0.375 -11.125 -25.813 -0.5z"/>
+      </mask>
+    </defs>
+    <path d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z"/>
+    <g mask="url(#r)">
+      <path fill="rgb(48,163,255)" d="M10.44 2.636l1.86 2.622 0.786 1.109 1.358 0.03 3.158 0.07 -1.881 2.773 -0.73 1.074 0.383 1.24 0.97 3.151 -3.018 -1.07 -1.36 -0.482 -1.155 0.86 -2.505 1.861 0.02 -3.275 0.006 -1.306 -1.019 -0.817 -2.615 -2.096 3.057 -0.99 1.325 -0.43 0.418 -1.33 0.94 -2.992"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M10.44 2.636l1.86 2.622 0.786 1.109 1.358 0.03 3.158 0.07 -1.881 2.773 -0.73 1.074 0.383 1.24 0.97 3.151 -3.018 -1.07 -1.36 -0.482 -1.155 0.86 -2.505 1.861 0.02 -3.275 0.006 -1.306 -1.019 -0.817 -2.615 -2.096 3.057 -0.99 1.325 -0.43 0.418 -1.33 0.94 -2.992"/>
+    </g>
+  </svg>
+  <svg x="418">
+    <defs>
+      <mask id="s" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.108 28.313)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-1.454 -10.124l-7.75 24.312 10.687 6 2.75 -0.375 1.5 -0.125 1.125 2.32 2.75 0.055 0.375 -1.07 1.625 -0.008 3.393 0.005 4.67 12.7 2.062 -19.564 3 -12.625 -0.375 -11.125 -25.813 -0.5z"/>
+      </mask>
+    </defs>
+    <path d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z"/>
+    <g mask="url(#s)">
+      <path fill="rgb(48,163,255)" d="M10.326 2.885l1.907 2.59 0.805 1.094 1.359 0.006 3.158 0.014 -1.832 2.807 -0.71 1.086 0.404 1.234 1.026 3.132 -3.037 -1.017 -1.368 -0.458 -1.14 0.88 -2.472 1.906 -0.038 -3.275 -0.016 -1.306 -1.034 -0.8 -2.651 -2.048 3.038 -1.044 1.318 -0.453 0.394 -1.338 0.888 -3.008"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M10.326 2.885l1.907 2.59 0.805 1.094 1.359 0.006 3.158 0.014 -1.832 2.807 -0.71 1.086 0.404 1.234 1.026 3.132 -3.037 -1.017 -1.368 -0.458 -1.14 0.88 -2.472 1.906 -0.038 -3.275 -0.016 -1.306 -1.034 -0.8 -2.651 -2.048 3.038 -1.044 1.318 -0.453 0.394 -1.338 0.888 -3.008"/>
+    </g>
+  </svg>
+  <svg x="440">
+    <defs>
+      <mask id="t" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.108 28.313)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-1.454 -10.124l-7.75 24.312 10.687 6 2.75 -0.375 1.5 -0.125 1.125 2.32 2.75 0.055 0.375 -1.07 1.625 -0.008 3.393 0.005 4.67 12.7 2.062 -19.564 3 -12.625 -0.375 -11.125 -25.813 -0.5z"/>
+      </mask>
+    </defs>
+    <path d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z"/>
+    <g mask="url(#t)">
+      <path fill="rgb(48,163,255)" d="M10.212 3.165l1.952 2.555 0.825 1.08 1.358 -0.019 3.158 -0.04 -1.782 2.837 -0.69 1.1 0.426 1.226 1.082 3.114 -3.055 -0.964 -1.376 -0.433 -1.125 0.9 -2.436 1.95 -0.097 -3.274 -0.04 -1.306 -1.047 -0.78 -2.688 -2.002 3.02 -1.098 1.309 -0.476 0.37 -1.344 0.835 -3.024"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M10.212 3.165l1.952 2.555 0.825 1.08 1.358 -0.019 3.158 -0.04 -1.782 2.837 -0.69 1.1 0.426 1.226 1.082 3.114 -3.055 -0.964 -1.376 -0.433 -1.125 0.9 -2.436 1.95 -0.097 -3.274 -0.04 -1.306 -1.047 -0.78 -2.688 -2.002 3.02 -1.098 1.309 -0.476 0.37 -1.344 0.835 -3.024"/>
+    </g>
+  </svg>
+  <svg x="462">
+    <defs>
+      <mask id="u" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.108 28.313)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-1.454 -10.124l-7.75 24.312 10.687 6 2.75 -0.375 1.5 -0.125 1.125 2.32 2.75 0.055 0.375 -1.07 1.625 -0.008 3.393 0.005 4.67 12.7 2.062 -19.564 3 -12.625 -0.375 -11.125 -25.813 -0.5z"/>
+      </mask>
+    </defs>
+    <path d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z"/>
+    <g mask="url(#u)">
+      <path fill="rgb(48,163,255)" d="M10.097 3.479l1.998 2.52 0.843 1.064 1.358 -0.043 3.157 -0.097 -1.73 2.87 -0.671 1.11 0.447 1.219 1.138 3.094 -3.072 -0.908 -1.383 -0.409 -1.108 0.92 -2.402 1.993 -0.156 -3.272 -0.062 -1.304 -1.061 -0.762 -2.723 -1.953 2.999 -1.152 1.3 -0.5 0.347 -1.35 0.78 -3.038"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M10.097 3.479l1.998 2.52 0.843 1.064 1.358 -0.043 3.157 -0.097 -1.73 2.87 -0.671 1.11 0.447 1.219 1.138 3.094 -3.072 -0.908 -1.383 -0.409 -1.108 0.92 -2.402 1.993 -0.156 -3.272 -0.062 -1.304 -1.061 -0.762 -2.723 -1.953 2.999 -1.152 1.3 -0.5 0.347 -1.35 0.78 -3.038"/>
+    </g>
+  </svg>
+  <svg x="484">
+    <defs>
+      <mask id="v" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.108 28.313)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-1.454 -10.124l-7.75 24.312 10.687 6 2.75 -0.375 1.5 -0.125 1.125 2.32 2.75 0.055 0.375 -1.07 1.625 -0.008 3.393 0.005 4.67 12.7 2.062 -19.564 3 -12.625 -0.375 -11.125 -25.813 -0.5z"/>
+      </mask>
+    </defs>
+    <path d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z"/>
+    <g mask="url(#v)">
+      <path fill="rgb(48,163,255)" d="M9.981 3.83l2.043 2.483 0.863 1.05 1.357 -0.068 3.154 -0.154 -1.678 2.9 -0.651 1.123 0.47 1.21 1.193 3.073 -3.088 -0.853 -1.39 -0.383 -1.092 0.94 -2.366 2.036 -0.214 -3.269 -0.086 -1.303 -1.075 -0.743 -2.757 -1.903 2.978 -1.206 1.291 -0.523 0.322 -1.357 0.726 -3.051"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M9.981 3.83l2.043 2.483 0.863 1.05 1.357 -0.068 3.154 -0.154 -1.678 2.9 -0.651 1.123 0.47 1.21 1.193 3.073 -3.088 -0.853 -1.39 -0.383 -1.092 0.94 -2.366 2.036 -0.214 -3.269 -0.086 -1.303 -1.075 -0.743 -2.757 -1.903 2.978 -1.206 1.291 -0.523 0.322 -1.357 0.726 -3.051"/>
+    </g>
+  </svg>
+  <svg x="506">
+    <defs>
+      <mask id="w" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.108 28.313)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-1.454 -10.124l-7.75 24.312 10.687 6 2.75 -0.375 1.5 -0.125 1.125 2.32 2.75 0.055 0.375 -1.07 1.625 -0.008 3.393 0.005 4.67 12.7 2.062 -19.564 3 -12.625 -0.375 -11.125 -25.813 -0.5z"/>
+      </mask>
+    </defs>
+    <path d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z"/>
+    <g mask="url(#w)">
+      <path fill="rgb(48,163,255)" d="M9.866 4.223l2.087 2.446 0.881 1.034 1.356 -0.092 3.15 -0.211 -1.625 2.93 -0.63 1.134 0.491 1.202 1.248 3.05 -3.103 -0.796 -1.397 -0.359 -1.074 0.96 -2.328 2.078 -0.274 -3.264 -0.109 -1.302 -1.088 -0.723 -2.791 -1.854 2.955 -1.259 1.282 -0.546 0.297 -1.362 0.67 -3.064"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M9.866 4.223l2.087 2.446 0.881 1.034 1.356 -0.092 3.15 -0.211 -1.625 2.93 -0.63 1.134 0.491 1.202 1.248 3.05 -3.103 -0.796 -1.397 -0.359 -1.074 0.96 -2.328 2.078 -0.274 -3.264 -0.109 -1.302 -1.088 -0.723 -2.791 -1.854 2.955 -1.259 1.282 -0.546 0.297 -1.362 0.67 -3.064"/>
+    </g>
+  </svg>
+  <svg x="528">
+    <defs>
+      <mask id="x" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.108 28.313)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-1.454 -10.124l-7.75 24.312 10.687 6 2.75 -0.375 1.5 -0.125 1.125 2.32 2.75 0.055 0.375 -1.07 1.625 -0.008 3.393 0.005 4.67 12.7 2.062 -19.564 3 -12.625 -0.375 -11.125 -25.813 -0.5z"/>
+      </mask>
+    </defs>
+    <path d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z"/>
+    <g mask="url(#x)">
+      <path fill="rgb(48,163,255)" d="M9.75 4.663l2.13 2.408 0.901 1.018 1.354 -0.116 3.146 -0.268 -1.573 2.959 -0.61 1.145 0.514 1.193 1.303 3.028 -3.117 -0.741 -1.403 -0.333 -1.057 0.979 -2.29 2.12 -0.333 -3.26 -0.132 -1.299 -1.101 -0.703 -2.825 -1.803 2.933 -1.312 1.271 -0.57 0.273 -1.367 0.615 -3.076"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M9.75 4.663l2.13 2.408 0.901 1.018 1.354 -0.116 3.146 -0.268 -1.573 2.959 -0.61 1.145 0.514 1.193 1.303 3.028 -3.117 -0.741 -1.403 -0.333 -1.057 0.979 -2.29 2.12 -0.333 -3.26 -0.132 -1.299 -1.101 -0.703 -2.825 -1.803 2.933 -1.312 1.271 -0.57 0.273 -1.367 0.615 -3.076"/>
+    </g>
+  </svg>
+  <svg x="550">
+    <defs>
+      <mask id="y" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.108 28.313)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-1.454 -10.124l-7.75 24.312 10.687 6 2.75 -0.375 1.5 -0.125 1.125 2.32 2.75 0.055 0.375 -1.07 1.625 -0.008 3.393 0.005 4.67 12.7 2.062 -19.564 3 -12.625 -0.375 -11.125 -25.813 -0.5z"/>
+      </mask>
+    </defs>
+    <path d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z"/>
+    <g mask="url(#y)">
+      <path fill="rgb(48,163,255)" d="M9.635 5.158l2.173 2.37 0.919 1 1.35 -0.14 3.142 -0.324 -1.52 2.987 -0.588 1.156 0.534 1.183 1.358 3.004 -3.13 -0.685 -1.409 -0.307 -1.039 0.997 -2.252 2.16 -0.39 -3.251 -0.157 -1.297 -1.113 -0.683 -2.857 -1.752 2.909 -1.365 1.26 -0.593 0.25 -1.371 0.559 -3.087"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M9.635 5.158l2.173 2.37 0.919 1 1.35 -0.14 3.142 -0.324 -1.52 2.987 -0.588 1.156 0.534 1.183 1.358 3.004 -3.13 -0.685 -1.409 -0.307 -1.039 0.997 -2.252 2.16 -0.39 -3.251 -0.157 -1.297 -1.113 -0.683 -2.857 -1.752 2.909 -1.365 1.26 -0.593 0.25 -1.371 0.559 -3.087"/>
+    </g>
+  </svg>
+  <svg x="572">
+    <defs>
+      <mask id="z" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.108 28.313)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-1.454 -10.124l-7.75 24.312 10.687 6 2.75 -0.375 1.5 -0.125 1.125 2.32 2.75 0.055 0.375 -1.07 1.625 -0.008 3.393 0.005 4.67 12.7 2.062 -19.564 3 -12.625 -0.375 -11.125 -25.813 -0.5z"/>
+      </mask>
+    </defs>
+    <path d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z"/>
+    <g mask="url(#z)">
+      <path fill="rgb(48,163,255)" d="M9.52 5.717l2.215 2.33 0.936 0.984 1.349 -0.164 3.135 -0.382 -1.466 3.014 -0.568 1.167 0.556 1.173 1.411 2.98 -3.141 -0.63 -1.415 -0.282 -1.02 1.017 -2.213 2.2 -0.45 -3.244 -0.179 -1.294 -1.125 -0.663 -2.888 -1.7 2.884 -1.418 1.25 -0.614 0.223 -1.376 0.504 -3.096"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M9.52 5.717l2.215 2.33 0.936 0.984 1.349 -0.164 3.135 -0.382 -1.466 3.014 -0.568 1.167 0.556 1.173 1.411 2.98 -3.141 -0.63 -1.415 -0.282 -1.02 1.017 -2.213 2.2 -0.45 -3.244 -0.179 -1.294 -1.125 -0.663 -2.888 -1.7 2.884 -1.418 1.25 -0.614 0.223 -1.376 0.504 -3.096"/>
+    </g>
+  </svg>
+  <svg x="594">
+    <defs>
+      <mask id="A" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.108 28.313)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-1.454 -10.124l-7.75 24.312 10.687 6 2.75 -0.375 1.5 -0.125 1.125 2.32 2.75 0.055 0.375 -1.07 1.625 -0.008 3.393 0.005 4.67 12.7 2.062 -19.564 3 -12.625 -0.375 -11.125 -25.813 -0.5z"/>
+      </mask>
+    </defs>
+    <path d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z"/>
+    <g mask="url(#A)">
+      <path fill="rgb(48,163,255)" d="M9.404 6.35l2.257 2.29 0.954 0.968 1.345 -0.19 3.128 -0.437 -1.411 3.04 -0.547 1.177 0.576 1.163 1.464 2.953 -3.152 -0.572 -1.419 -0.257 -1.002 1.035 -2.173 2.24 -0.508 -3.237 -0.202 -1.29 -1.137 -0.643 -2.918 -1.648 2.858 -1.469 1.239 -0.637 0.199 -1.38 0.448 -3.104"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M9.404 6.35l2.257 2.29 0.954 0.968 1.345 -0.19 3.128 -0.437 -1.411 3.04 -0.547 1.177 0.576 1.163 1.464 2.953 -3.152 -0.572 -1.419 -0.257 -1.002 1.035 -2.173 2.24 -0.508 -3.237 -0.202 -1.29 -1.137 -0.643 -2.918 -1.648 2.858 -1.469 1.239 -0.637 0.199 -1.38 0.448 -3.104"/>
+    </g>
+  </svg>
+  <svg x="616">
+    <defs>
+      <mask id="B" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.108 28.313)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-1.454 -10.124l-7.75 24.312 10.687 6 2.75 -0.375 1.5 -0.125 1.125 2.32 2.75 0.055 0.375 -1.07 1.625 -0.008 3.393 0.005 4.67 12.7 2.062 -19.564 3 -12.625 -0.375 -11.125 -25.813 -0.5z"/>
+      </mask>
+    </defs>
+    <path d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z"/>
+    <g mask="url(#B)">
+      <path fill="rgb(48,163,255)" d="M9.29 7.074l2.297 2.249 0.97 0.95 1.342 -0.212 3.12 -0.493 -1.357 3.064 -0.526 1.186 0.597 1.153 1.517 2.927 -3.162 -0.516 -1.424 -0.232 -0.984 1.052 -2.133 2.278 -0.564 -3.226 -0.226 -1.287 -1.148 -0.622 -2.947 -1.597 2.832 -1.518 1.227 -0.66 0.174 -1.383 0.394 -3.111"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M9.29 7.074l2.297 2.249 0.97 0.95 1.342 -0.212 3.12 -0.493 -1.357 3.064 -0.526 1.186 0.597 1.153 1.517 2.927 -3.162 -0.516 -1.424 -0.232 -0.984 1.052 -2.133 2.278 -0.564 -3.226 -0.226 -1.287 -1.148 -0.622 -2.947 -1.597 2.832 -1.518 1.227 -0.66 0.174 -1.383 0.394 -3.111"/>
+    </g>
+  </svg>
+  <svg x="638">
+    <defs>
+      <mask id="C" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5166 0 0 .5 13.263 28.454)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5166 0 0 .5 13.263 28.454)"/>
+      </mask>
+    </defs>
+    <path d="M7.985 22.141c-0.57 0 -1.033 0.448 -1.033 1v10c0 0.552 0.463 1 1.033 1 0.57 0 1.033 -0.448 1.033 -1v-10c0 -0.552 -0.462 -1 -1.033 -1zm3.1 -1c-0.57 0 -1.033 0.448 -1.033 1v11c0 0.552 0.462 1 1.033 1 0.57 0 1.033 -0.448 1.033 -1v-11c0 -0.552 -0.463 -1 -1.033 -1zm8.202 11.658l-4.132 -11c-0.185 -0.523 -0.772 -0.8 -1.313 -0.622 -0.539 0.178 -0.827 0.747 -0.642 1.27a0.509 0.509 0 0 0 0.013 0.036l4.133 11c0.185 0.523 0.772 0.801 1.312 0.622 0.54 -0.178 0.828 -0.747 0.643 -1.27 -0.004 -0.012 -0.008 -0.024 -0.014 -0.036zm-14.401 -12.658c-0.57 0 -1.034 0.448 -1.034 1v12c0 0.552 0.463 1 1.034 1 0.57 0 1.033 -0.448 1.033 -1v-12c0 -0.552 -0.463 -1 -1.033 -1z"/>
+    <g mask="url(#C)">
+      <path fill="rgb(48,163,255)" d="M9.175 7.909l2.337 2.208 0.987 0.933 1.338 -0.236 3.11 -0.548 -1.302 3.087 -0.506 1.196 0.618 1.142 1.568 2.9 -3.17 -0.46 -1.428 -0.207 -0.965 1.07 -2.092 2.315 -0.622 -3.216 -0.248 -1.283 -1.16 -0.602 -2.973 -1.544 2.803 -1.568 1.216 -0.681 0.15 -1.386 0.338 -3.118"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M9.175 7.909l2.337 2.208 0.987 0.933 1.338 -0.236 3.11 -0.548 -1.302 3.087 -0.506 1.196 0.618 1.142 1.568 2.9 -3.17 -0.46 -1.428 -0.207 -0.965 1.07 -2.092 2.315 -0.622 -3.216 -0.248 -1.283 -1.16 -0.602 -2.973 -1.544 2.803 -1.568 1.216 -0.681 0.15 -1.386 0.338 -3.118"/>
+    </g>
+  </svg>
+  <svg x="660">
+    <defs>
+      <mask id="D" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5332 0 0 .5 13.482 28.845)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5332 0 0 .5 13.482 28.845)"/>
+      </mask>
+    </defs>
+    <path d="M8.035 22.532c-0.589 0 -1.066 0.448 -1.066 1v10c0 0.552 0.477 1 1.066 1 0.589 0 1.066 -0.448 1.066 -1v-10c0 -0.552 -0.477 -1 -1.066 -1zm3.2 -1c-0.59 0 -1.067 0.448 -1.067 1v11c0 0.552 0.478 1 1.066 1 0.589 0 1.067 -0.448 1.067 -1v-11c0 -0.552 -0.478 -1 -1.067 -1zm8.465 11.658l-4.265 -11c-0.191 -0.523 -0.797 -0.8 -1.355 -0.622 -0.556 0.178 -0.854 0.747 -0.663 1.27l0.014 0.036 4.266 11c0.19 0.523 0.796 0.801 1.354 0.622 0.557 -0.178 0.854 -0.747 0.663 -1.27 -0.004 -0.012 -0.008 -0.024 -0.014 -0.036zm-14.864 -12.658c-0.589 0 -1.067 0.448 -1.067 1v12c0 0.552 0.478 1 1.067 1 0.588 0 1.066 -0.448 1.066 -1v-12c0 -0.552 -0.478 -1 -1.066 -1z"/>
+    <g mask="url(#D)">
+      <path fill="rgb(48,163,255)" d="M9.06 8.886l2.376 2.167 1.003 0.916 1.334 -0.26 3.1 -0.602 -1.248 3.11 -0.485 1.204 0.638 1.13 1.618 2.872 -3.178 -0.404 -1.43 -0.182 -0.947 1.086 -2.051 2.352 -0.678 -3.204 -0.27 -1.278 -1.17 -0.582 -3 -1.492 2.775 -1.617 1.204 -0.702 0.125 -1.389 0.284 -3.123"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M9.06 8.886l2.376 2.167 1.003 0.916 1.334 -0.26 3.1 -0.602 -1.248 3.11 -0.485 1.204 0.638 1.13 1.618 2.872 -3.178 -0.404 -1.43 -0.182 -0.947 1.086 -2.051 2.352 -0.678 -3.204 -0.27 -1.278 -1.17 -0.582 -3 -1.492 2.775 -1.617 1.204 -0.702 0.125 -1.389 0.284 -3.123"/>
+    </g>
+  </svg>
+  <svg x="682">
+    <defs>
+      <mask id="E" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.54974 0 0 .5 13.727 29.36)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.54974 0 0 .5 13.727 29.36)"/>
+      </mask>
+    </defs>
+    <path d="M8.11 23.047c-0.606 0 -1.099 0.448 -1.099 1v10c0 0.552 0.493 1 1.1 1 0.607 0 1.1 -0.448 1.1 -1v-10c0 -0.552 -0.493 -1 -1.1 -1zm3.3 -1c-0.608 0 -1.1 0.448 -1.1 1v11c0 0.552 0.492 1 1.1 1 0.606 0 1.099 -0.448 1.099 -1v-11c0 -0.552 -0.493 -1 -1.1 -1zm8.728 11.658l-4.398 -11c-0.197 -0.523 -0.821 -0.8 -1.396 -0.622 -0.574 0.178 -0.881 0.747 -0.684 1.27l0.014 0.036 4.398 11c0.197 0.523 0.821 0.801 1.396 0.622 0.574 -0.178 0.881 -0.747 0.684 -1.27l-0.014 -0.036zm-15.326 -12.658c-0.607 0 -1.1 0.448 -1.1 1v12c0 0.552 0.493 1 1.1 1 0.607 0 1.1 -0.448 1.1 -1v-12c0 -0.552 -0.493 -1 -1.1 -1z"/>
+    <g mask="url(#E)">
+      <path fill="rgb(48,163,255)" d="M8.946 10.051l2.413 2.126 1.019 0.898 1.329 -0.283 3.089 -0.655 -1.195 3.13 -0.463 1.213 0.657 1.12 1.668 2.843 -3.185 -0.35 -1.433 -0.156 -0.928 1.102 -2.01 2.387 -0.733 -3.192 -0.293 -1.273 -1.18 -0.562 -3.025 -1.44 2.747 -1.665 1.191 -0.722 0.102 -1.39 0.23 -3.129"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M8.946 10.051l2.413 2.126 1.019 0.898 1.329 -0.283 3.089 -0.655 -1.195 3.13 -0.463 1.213 0.657 1.12 1.668 2.843 -3.185 -0.35 -1.433 -0.156 -0.928 1.102 -2.01 2.387 -0.733 -3.192 -0.293 -1.273 -1.18 -0.562 -3.025 -1.44 2.747 -1.665 1.191 -0.722 0.102 -1.39 0.23 -3.129"/>
+    </g>
+  </svg>
+  <svg x="704">
+    <defs>
+      <mask id="F" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.56608 0 0 .5 13.962 29.878)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.56608 0 0 .5 13.962 29.878)"/>
+      </mask>
+    </defs>
+    <path d="M8.18 23.565c-0.626 0 -1.133 0.448 -1.133 1v10c0 0.552 0.507 1 1.132 1 0.625 0 1.133 -0.448 1.133 -1v-10c0 -0.552 -0.508 -1 -1.133 -1zm3.396 -1c-0.625 0 -1.132 0.448 -1.132 1v11c0 0.552 0.507 1 1.132 1 0.625 0 1.132 -0.448 1.132 -1v-11c0 -0.552 -0.507 -1 -1.132 -1zm8.988 11.658l-4.529 -11c-0.202 -0.523 -0.845 -0.8 -1.437 -0.622 -0.591 0.178 -0.907 0.747 -0.705 1.27a0.481 0.481 0 0 0 0.015 0.036l4.529 11c0.202 0.523 0.846 0.801 1.438 0.622 0.59 -0.178 0.907 -0.747 0.704 -1.27a0.481 0.481 0 0 0 -0.015 -0.036zm-15.781 -12.658c-0.625 0 -1.132 0.448 -1.132 1v12c0 0.552 0.507 1 1.132 1 0.625 0 1.132 -0.448 1.132 -1v-12c0 -0.552 -0.507 -1 -1.132 -1z"/>
+    <g mask="url(#F)">
+      <path fill="rgb(48,163,255)" d="M8.831 11.48l2.448 2.083 1.035 0.881 1.324 -0.305 3.077 -0.708 -1.14 3.15 -0.443 1.22 0.676 1.11 1.716 2.814 -3.19 -0.295 -1.436 -0.133 -0.909 1.118 -1.97 2.42 -0.787 -3.179 -0.314 -1.268 -1.189 -0.541 -3.05 -1.388 2.719 -1.712 1.179 -0.742 0.077 -1.392 0.176 -3.132"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M8.831 11.48l2.448 2.083 1.035 0.881 1.324 -0.305 3.077 -0.708 -1.14 3.15 -0.443 1.22 0.676 1.11 1.716 2.814 -3.19 -0.295 -1.436 -0.133 -0.909 1.118 -1.97 2.42 -0.787 -3.179 -0.314 -1.268 -1.189 -0.541 -3.05 -1.388 2.719 -1.712 1.179 -0.742 0.077 -1.392 0.176 -3.132"/>
+    </g>
+  </svg>
+  <svg x="726">
+    <defs>
+      <mask id="G" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.58198 0 0 .5 14.154 30.278)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.58198 0 0 .5 14.154 30.278)"/>
+      </mask>
+    </defs>
+    <path d="M8.209 23.965c-0.643 0 -1.164 0.448 -1.164 1v10c0 0.552 0.521 1 1.164 1 0.642 0 1.164 -0.448 1.164 -1v-10c0 -0.552 -0.522 -1 -1.164 -1zm3.492 -1c-0.643 0 -1.164 0.448 -1.164 1v11c0 0.552 0.521 1 1.164 1 0.642 0 1.164 -0.448 1.164 -1v-11c0 -0.552 -0.522 -1 -1.164 -1zm9.24 11.658l-4.655 -11c-0.209 -0.523 -0.87 -0.801 -1.479 -0.622 -0.607 0.178 -0.932 0.747 -0.724 1.27a0.474 0.474 0 0 0 0.016 0.036l4.655 11c0.209 0.523 0.87 0.8 1.479 0.622 0.607 -0.178 0.932 -0.747 0.724 -1.27l-0.016 -0.036zm-16.224 -12.658c-0.642 0 -1.164 0.448 -1.164 1v12c0 0.552 0.522 1 1.164 1 0.643 0 1.164 -0.448 1.164 -1v-12c0 -0.552 -0.521 -1 -1.164 -1z"/>
+    <g mask="url(#G)">
+      <path fill="rgb(48,163,255)" d="M8.714 13.295l2.483 2.043 1.05 0.863 1.318 -0.327 3.065 -0.76 -1.088 3.17 -0.422 1.227 0.694 1.097 1.763 2.786 -3.194 -0.242 -1.438 -0.108 -0.89 1.133 -1.929 2.453 -0.84 -3.166 -0.336 -1.262 -1.197 -0.522 -3.073 -1.336 2.69 -1.757 1.166 -0.763 0.054 -1.393 0.124 -3.134"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M8.714 13.295l2.483 2.043 1.05 0.863 1.318 -0.327 3.065 -0.76 -1.088 3.17 -0.422 1.227 0.694 1.097 1.763 2.786 -3.194 -0.242 -1.438 -0.108 -0.89 1.133 -1.929 2.453 -0.84 -3.166 -0.336 -1.262 -1.197 -0.522 -3.073 -1.336 2.69 -1.757 1.166 -0.763 0.054 -1.393 0.124 -3.134"/>
+    </g>
+  </svg>
+  <svg x="748">
+    <defs>
+      <mask id="H" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5969 0 0 .5 14.267 30.438)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5969 0 0 .5 14.267 30.438)"/>
+      </mask>
+    </defs>
+    <path d="M8.169 24.125c-0.66 0 -1.194 0.448 -1.194 1v10c0 0.552 0.535 1 1.194 1 0.659 0 1.193 -0.448 1.193 -1v-10c0 -0.552 -0.534 -1 -1.193 -1zm3.581 -1c-0.659 0 -1.194 0.448 -1.194 1v11c0 0.552 0.535 1 1.194 1 0.659 0 1.194 -0.448 1.194 -1v-11c0 -0.552 -0.535 -1 -1.194 -1zm9.478 11.658l-4.776 -11c-0.213 -0.523 -0.891 -0.801 -1.516 -0.622 -0.623 0.178 -0.956 0.747 -0.742 1.27a0.467 0.467 0 0 0 0.015 0.036l4.775 11c0.214 0.523 0.892 0.801 1.517 0.622 0.623 -0.178 0.956 -0.747 0.742 -1.27l-0.015 -0.036zm-16.64 -12.658c-0.66 0 -1.195 0.448 -1.195 1v12c0 0.552 0.535 1 1.194 1 0.66 0 1.194 -0.448 1.194 -1v-12c0 -0.552 -0.535 -1 -1.194 -1z"/>
+    <g mask="url(#H)">
+      <path fill="rgb(48,163,255)" d="M8.594 15.704l2.516 2.002 1.063 0.846 1.313 -0.349 3.053 -0.81 -1.036 3.187 -0.402 1.234 0.712 1.086 1.808 2.756 -3.198 -0.19 -1.44 -0.084 -0.87 1.147 -1.89 2.485 -0.891 -3.152 -0.356 -1.257 -1.206 -0.502 -3.095 -1.286 2.661 -1.8 1.154 -0.782 0.031 -1.394 0.073 -3.135"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M8.594 15.704l2.516 2.002 1.063 0.846 1.313 -0.349 3.053 -0.81 -1.036 3.187 -0.402 1.234 0.712 1.086 1.808 2.756 -3.198 -0.19 -1.44 -0.084 -0.87 1.147 -1.89 2.485 -0.891 -3.152 -0.356 -1.257 -1.206 -0.502 -3.095 -1.286 2.661 -1.8 1.154 -0.782 0.031 -1.394 0.073 -3.135"/>
+    </g>
+  </svg>
+  <svg x="770">
+    <defs>
+      <mask id="I" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.60979 0 0 .5 14.335 30.217)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.60979 0 0 .5 14.335 30.217)"/>
+      </mask>
+    </defs>
+    <path d="M8.105 23.904c-0.673 0 -1.22 0.448 -1.22 1v10c0 0.552 0.547 1 1.22 1 0.674 0 1.22 -0.448 1.22 -1v-10c0 -0.552 -0.546 -1 -1.22 -1zm3.659 -1c-0.673 0 -1.22 0.448 -1.22 1v11c0 0.552 0.547 1 1.22 1 0.673 0 1.22 -0.448 1.22 -1v-11c0 -0.552 -0.547 -1 -1.22 -1zm9.682 11.658l-4.878 -11c-0.218 -0.523 -0.911 -0.801 -1.549 -0.622 -0.637 0.178 -0.977 0.747 -0.758 1.27a0.462 0.462 0 0 0 0.015 0.036l4.879 11c0.218 0.523 0.91 0.8 1.549 0.622 0.636 -0.178 0.976 -0.747 0.758 -1.27l-0.016 -0.036zm-17 -12.658c-0.673 0 -1.219 0.448 -1.219 1v12c0 0.552 0.546 1 1.22 1 0.673 0 1.22 -0.448 1.22 -1v-12c0 -0.552 -0.547 -1 -1.22 -1z"/>
+    <g mask="url(#I)">
+      <path fill="rgb(48,163,255)" d="M8.47 18.813l2.547 1.962 1.077 0.83 1.307 -0.37 3.04 -0.859 -0.986 3.203 -0.382 1.24 0.729 1.075 1.852 2.727 -3.2 -0.139 -1.442 -0.062 -0.852 1.161 -1.85 2.514 -0.941 -3.137 -0.376 -1.25 -1.214 -0.483 -3.115 -1.237 2.632 -1.843 1.141 -0.8 0.01 -1.393 0.022 -3.137"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M8.47 18.813l2.547 1.962 1.077 0.83 1.307 -0.37 3.04 -0.859 -0.986 3.203 -0.382 1.24 0.729 1.075 1.852 2.727 -3.2 -0.139 -1.442 -0.062 -0.852 1.161 -1.85 2.514 -0.941 -3.137 -0.376 -1.25 -1.214 -0.483 -3.115 -1.237 2.632 -1.843 1.141 -0.8 0.01 -1.393 0.022 -3.137"/>
+    </g>
+  </svg>
+  <svg x="792">
+    <defs>
+      <mask id="J" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.61897 0 0 .5 14.4 29.689)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.61897 0 0 .5 14.4 29.689)"/>
+      </mask>
+    </defs>
+    <path d="M8.076 23.376c-0.683 0 -1.237 0.448 -1.237 1v10c0 0.552 0.554 1 1.237 1 0.684 0 1.238 -0.448 1.238 -1v-10c0 -0.552 -0.554 -1 -1.238 -1zm3.714 -1c-0.683 0 -1.238 0.448 -1.238 1v11c0 0.552 0.555 1 1.238 1 0.684 0 1.238 -0.448 1.238 -1v-11c0 -0.552 -0.554 -1 -1.238 -1zm9.828 11.658l-4.951 -11c-0.222 -0.523 -0.925 -0.801 -1.573 -0.622 -0.646 0.178 -0.991 0.747 -0.77 1.27a0.459 0.459 0 0 0 0.016 0.036l4.952 11c0.222 0.523 0.925 0.801 1.572 0.622 0.647 -0.178 0.992 -0.747 0.77 -1.27a0.459 0.459 0 0 0 -0.016 -0.036zm-17.255 -12.658c-0.684 0 -1.238 0.448 -1.238 1v12c0 0.552 0.554 1 1.238 1 0.683 0 1.238 -0.448 1.238 -1v-12c0 -0.552 -0.555 -1 -1.238 -1z"/>
+    <g mask="url(#J)">
+      <path fill="rgb(48,163,255)" d="M8.351 21.743l2.577 1.923 1.09 0.812 1.3 -0.39 3.027 -0.904 -0.937 3.217 -0.363 1.246 0.746 1.063 1.893 2.699 -3.202 -0.09 -1.442 -0.04 -0.834 1.174 -1.81 2.543 -0.99 -3.123 -0.395 -1.245 -1.222 -0.463 -3.133 -1.19 2.603 -1.882 1.129 -0.817 -0.012 -1.394 -0.025 -3.137"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M8.351 21.743l2.577 1.923 1.09 0.812 1.3 -0.39 3.027 -0.904 -0.937 3.217 -0.363 1.246 0.746 1.063 1.893 2.699 -3.202 -0.09 -1.442 -0.04 -0.834 1.174 -1.81 2.543 -0.99 -3.123 -0.395 -1.245 -1.222 -0.463 -3.133 -1.19 2.603 -1.882 1.129 -0.817 -0.012 -1.394 -0.025 -3.137"/>
+    </g>
+  </svg>
+  <svg x="814">
+    <defs>
+      <mask id="K" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.62351 0 0 .5 14.434 29.059)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.62351 0 0 .5 14.434 29.059)"/>
+      </mask>
+    </defs>
+    <path d="M8.064 22.746c-0.688 0 -1.247 0.448 -1.247 1v10c0 0.552 0.56 1 1.247 1 0.689 0 1.247 -0.448 1.247 -1v-10c0 -0.552 -0.558 -1 -1.247 -1zm3.741 -1c-0.688 0 -1.247 0.448 -1.247 1v11c0 0.552 0.56 1 1.247 1 0.689 0 1.247 -0.448 1.247 -1v-11c0 -0.552 -0.558 -1 -1.247 -1zm9.9 11.658l-4.988 -11c-0.223 -0.523 -0.931 -0.801 -1.583 -0.622 -0.651 0.178 -1 0.747 -0.776 1.27l0.016 0.036 4.988 11c0.224 0.523 0.932 0.8 1.584 0.622 0.651 -0.178 0.999 -0.747 0.776 -1.27a0.457 0.457 0 0 0 -0.016 -0.036zm-17.382 -12.658c-0.688 0 -1.247 0.448 -1.247 1v12c0 0.552 0.559 1 1.247 1 0.689 0 1.247 -0.448 1.247 -1v-12c0 -0.552 -0.558 -1 -1.247 -1z"/>
+    <g mask="url(#K)">
+      <path fill="rgb(48,163,255)" d="M8.248 23.608l2.606 1.885 1.1 0.796 1.296 -0.408 3.012 -0.95 -0.889 3.232 -0.345 1.25 0.761 1.053 1.933 2.67 -3.203 -0.043 -1.442 -0.018 -0.818 1.186 -1.772 2.568 -1.036 -3.107 -0.413 -1.24 -1.228 -0.445 -3.15 -1.143 2.575 -1.92 1.117 -0.834 -0.033 -1.394 -0.07 -3.136"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M8.248 23.608l2.606 1.885 1.1 0.796 1.296 -0.408 3.012 -0.95 -0.889 3.232 -0.345 1.25 0.761 1.053 1.933 2.67 -3.203 -0.043 -1.442 -0.018 -0.818 1.186 -1.772 2.568 -1.036 -3.107 -0.413 -1.24 -1.228 -0.445 -3.15 -1.143 2.575 -1.92 1.117 -0.834 -0.033 -1.394 -0.07 -3.136"/>
+    </g>
+  </svg>
+  <svg x="836">
+    <defs>
+      <mask id="L" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.62484 0 0 .5 14.423 28.531)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.62484 0 0 .5 14.423 28.531)"/>
+      </mask>
+    </defs>
+    <path d="M8.04 22.218c-0.69 0 -1.25 0.448 -1.25 1v10c0 0.552 0.56 1 1.25 1s1.249 -0.448 1.249 -1v-10c0 -0.552 -0.56 -1 -1.25 -1zm3.748 -1c-0.69 0 -1.25 0.448 -1.25 1v11c0 0.552 0.56 1 1.25 1s1.25 -0.448 1.25 -1v-11c0 -0.552 -0.56 -1 -1.25 -1zm9.922 11.658l-5 -11c-0.223 -0.523 -0.933 -0.801 -1.586 -0.622 -0.653 0.178 -1.001 0.747 -0.778 1.27a0.457 0.457 0 0 0 0.017 0.036l4.998 11c0.224 0.523 0.934 0.801 1.588 0.622 0.652 -0.178 1 -0.747 0.777 -1.27a0.457 0.457 0 0 0 -0.016 -0.036zm-17.42 -12.658c-0.69 0 -1.25 0.448 -1.25 1v12c0 0.552 0.56 1 1.25 1s1.25 -0.448 1.25 -1v-12c0 -0.552 -0.56 -1 -1.25 -1z"/>
+    <g mask="url(#L)">
+      <path fill="rgb(48,163,255)" d="M8.16 24.7l2.63 1.85 1.112 0.78 1.29 -0.426 2.999 -0.99 -0.844 3.243 -0.328 1.256 0.775 1.041 1.97 2.644 -3.204 0.001 -1.442 0.001 -0.801 1.197 -1.737 2.593 -1.079 -3.093 -0.43 -1.233 -1.234 -0.43 -3.165 -1.099 2.548 -1.956 1.105 -0.848 -0.051 -1.394 -0.114 -3.134"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M8.16 24.7l2.63 1.85 1.112 0.78 1.29 -0.426 2.999 -0.99 -0.844 3.243 -0.328 1.256 0.775 1.041 1.97 2.644 -3.204 0.001 -1.442 0.001 -0.801 1.197 -1.737 2.593 -1.079 -3.093 -0.43 -1.233 -1.234 -0.43 -3.165 -1.099 2.548 -1.956 1.105 -0.848 -0.051 -1.394 -0.114 -3.134"/>
+    </g>
+  </svg>
+  <svg x="858">
+    <defs>
+      <mask id="M" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.625 0 0 .5 14.385 28.313)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.625 0 0 .5 14.385 28.313)"/>
+      </mask>
+    </defs>
+    <path d="M8 22c-0.69 0 -1.25 0.448 -1.25 1v10c0 0.552 0.56 1 1.25 1s1.25 -0.448 1.25 -1v-10c0 -0.552 -0.56 -1 -1.25 -1zm3.75 -1c-0.69 0 -1.25 0.448 -1.25 1v11c0 0.552 0.56 1 1.25 1s1.25 -0.448 1.25 -1v-11c0 -0.552 -0.56 -1 -1.25 -1zm9.924 11.658l-5 -11c-0.224 -0.523 -0.934 -0.801 -1.588 -0.622 -0.652 0.178 -1.001 0.747 -0.777 1.27l0.016 0.036 5 11c0.224 0.523 0.934 0.801 1.587 0.622 0.653 -0.178 1.002 -0.747 0.778 -1.27a0.457 0.457 0 0 0 -0.016 -0.036zm-17.424 -12.658c-0.69 0 -1.25 0.448 -1.25 1v12c0 0.552 0.56 1 1.25 1s1.25 -0.448 1.25 -1v-12c0 -0.552 -0.56 -1 -1.25 -1z"/>
+    <g mask="url(#M)">
+      <path fill="rgb(48,163,255)" d="M8.083 25.355l2.654 1.815 1.121 0.768 1.284 -0.443 2.987 -1.028 -0.804 3.253 -0.312 1.26 0.789 1.032 2.002 2.618 -3.203 0.042 -1.442 0.02 -0.786 1.206 -1.705 2.614 -1.117 -3.079 -0.445 -1.228 -1.24 -0.413 -3.179 -1.06 2.524 -1.988 1.094 -0.862 -0.068 -1.392 -0.154 -3.133"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M8.083 25.355l2.654 1.815 1.121 0.768 1.284 -0.443 2.987 -1.028 -0.804 3.253 -0.312 1.26 0.789 1.032 2.002 2.618 -3.203 0.042 -1.442 0.02 -0.786 1.206 -1.705 2.614 -1.117 -3.079 -0.445 -1.228 -1.24 -0.413 -3.179 -1.06 2.524 -1.988 1.094 -0.862 -0.068 -1.392 -0.154 -3.133"/>
+    </g>
+  </svg>
+  <svg x="880">
+    <defs>
+      <mask id="N" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.61111 0 0 .5 14.298 28.255)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.61111 0 0 .5 14.298 28.255)"/>
+      </mask>
+    </defs>
+    <path d="M8.054 21.942c-0.674 0 -1.222 0.448 -1.222 1v10c0 0.552 0.548 1 1.222 1 0.675 0 1.223 -0.448 1.223 -1v-10c0 -0.552 -0.548 -1 -1.223 -1zm3.667 -1c-0.675 0 -1.222 0.448 -1.222 1v11c0 0.552 0.547 1 1.222 1 0.675 0 1.222 -0.448 1.222 -1v-11c0 -0.552 -0.547 -1 -1.222 -1zm9.703 11.658l-4.889 -11c-0.218 -0.523 -0.913 -0.8 -1.552 -0.622 -0.638 0.178 -0.979 0.747 -0.76 1.27l0.016 0.036 4.889 11c0.219 0.523 0.913 0.801 1.552 0.622 0.638 -0.178 0.979 -0.747 0.76 -1.27l-0.016 -0.036zm-17.036 -12.658c-0.675 0 -1.222 0.448 -1.222 1v12c0 0.552 0.547 1 1.222 1 0.674 0 1.222 -0.448 1.222 -1v-12c0 -0.552 -0.548 -1 -1.222 -1z"/>
+    <g mask="url(#N)">
+      <path fill="rgb(48,163,255)" d="M8.02 25.74l2.672 1.787 1.13 0.755 1.28 -0.457 2.974 -1.06 -0.768 3.262 -0.298 1.263 0.8 1.023 2.03 2.597 -3.202 0.076 -1.442 0.035 -0.773 1.216 -1.676 2.632 -1.15 -3.067 -0.46 -1.222 -1.243 -0.4 -3.19 -1.026 2.502 -2.015 1.085 -0.874 -0.084 -1.392 -0.188 -3.13"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M8.02 25.74l2.672 1.787 1.13 0.755 1.28 -0.457 2.974 -1.06 -0.768 3.262 -0.298 1.263 0.8 1.023 2.03 2.597 -3.202 0.076 -1.442 0.035 -0.773 1.216 -1.676 2.632 -1.15 -3.067 -0.46 -1.222 -1.243 -0.4 -3.19 -1.026 2.502 -2.015 1.085 -0.874 -0.084 -1.392 -0.188 -3.13"/>
+    </g>
+  </svg>
+  <svg x="902">
+    <defs>
+      <mask id="O" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.59722 0 0 .5 14.154 28.183)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.59722 0 0 .5 14.154 28.183)"/>
+      </mask>
+    </defs>
+    <path d="M8.052 21.87c-0.659 0 -1.194 0.448 -1.194 1v10c0 0.552 0.535 1 1.194 1 0.66 0 1.195 -0.448 1.195 -1v-10c0 -0.552 -0.535 -1 -1.195 -1zm3.584 -1c-0.66 0 -1.195 0.448 -1.195 1v11c0 0.552 0.535 1 1.195 1 0.659 0 1.194 -0.448 1.194 -1v-11c0 -0.552 -0.535 -1 -1.194 -1zm9.482 11.658l-4.777 -11c-0.214 -0.523 -0.893 -0.801 -1.517 -0.622 -0.624 0.178 -0.957 0.747 -0.743 1.27a0.467 0.467 0 0 0 0.015 0.036l4.778 11c0.214 0.523 0.892 0.8 1.517 0.622 0.623 -0.178 0.957 -0.747 0.743 -1.27a0.467 0.467 0 0 0 -0.016 -0.036zm-16.649 -12.658c-0.66 0 -1.194 0.448 -1.194 1v12c0 0.552 0.535 1 1.194 1 0.66 0 1.194 -0.448 1.194 -1v-12c0 -0.552 -0.535 -1 -1.194 -1z"/>
+    <g mask="url(#O)">
+      <path fill="rgb(48,163,255)" d="M7.971 25.945l2.688 1.764 1.136 0.746 1.276 -0.467 2.966 -1.085 -0.741 3.268 -0.288 1.265 0.808 1.017 2.052 2.58 -3.202 0.102 -1.441 0.047 -0.763 1.222 -1.654 2.647 -1.175 -3.057 -0.47 -1.22 -1.247 -0.39 -3.198 -0.998 2.485 -2.036 1.077 -0.883 -0.095 -1.39 -0.214 -3.13"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M7.971 25.945l2.688 1.764 1.136 0.746 1.276 -0.467 2.966 -1.085 -0.741 3.268 -0.288 1.265 0.808 1.017 2.052 2.58 -3.202 0.102 -1.441 0.047 -0.763 1.222 -1.654 2.647 -1.175 -3.057 -0.47 -1.22 -1.247 -0.39 -3.198 -0.998 2.485 -2.036 1.077 -0.883 -0.095 -1.39 -0.214 -3.13"/>
+    </g>
+  </svg>
+  <svg x="924">
+    <defs>
+      <mask id="P" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.58333 0 0 .5 13.973 28.156)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.58333 0 0 .5 13.973 28.156)"/>
+      </mask>
+    </defs>
+    <path d="M8.013 21.843c-0.644 0 -1.166 0.448 -1.166 1v10c0 0.552 0.522 1 1.166 1 0.644 0 1.167 -0.448 1.167 -1v-10c0 -0.552 -0.523 -1 -1.167 -1zm3.5 -1c-0.644 0 -1.166 0.448 -1.166 1v11c0 0.552 0.522 1 1.166 1 0.644 0 1.167 -0.448 1.167 -1v-11c0 -0.552 -0.523 -1 -1.167 -1zm9.262 11.658l-4.666 -11c-0.21 -0.523 -0.872 -0.801 -1.482 -0.622 -0.609 0.178 -0.934 0.747 -0.726 1.27a0.473 0.473 0 0 0 0.016 0.036l4.666 11c0.21 0.523 0.872 0.8 1.482 0.622 0.609 -0.178 0.934 -0.747 0.726 -1.27l-0.016 -0.036zm-16.262 -12.658c-0.644 0 -1.166 0.448 -1.166 1v12c0 0.552 0.522 1 1.166 1 0.644 0 1.167 -0.448 1.167 -1v-12c0 -0.552 -0.523 -1 -1.167 -1z"/>
+    <g mask="url(#P)">
+      <path fill="rgb(48,163,255)" d="M7.95 26.013l2.695 1.754 1.138 0.742 1.274 -0.472 2.962 -1.096 -0.729 3.27 -0.283 1.267 0.812 1.013 2.062 2.572 -3.201 0.115 -1.442 0.053 -0.758 1.224 -1.644 2.653 -1.187 -3.053 -0.474 -1.217 -1.248 -0.385 -3.203 -0.987 2.478 -2.045 1.074 -0.887 -0.1 -1.39 -0.226 -3.129"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M7.95 26.013l2.695 1.754 1.138 0.742 1.274 -0.472 2.962 -1.096 -0.729 3.27 -0.283 1.267 0.812 1.013 2.062 2.572 -3.201 0.115 -1.442 0.053 -0.758 1.224 -1.644 2.653 -1.187 -3.053 -0.474 -1.217 -1.248 -0.385 -3.203 -0.987 2.478 -2.045 1.074 -0.887 -0.1 -1.39 -0.226 -3.129"/>
+    </g>
+  </svg>
+  <svg x="946">
+    <defs>
+      <mask id="Q" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.56944 0 0 .5 13.787 28.166)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.56944 0 0 .5 13.787 28.166)"/>
+      </mask>
+    </defs>
+    <path d="M7.97 21.853c-0.629 0 -1.139 0.448 -1.139 1v10c0 0.552 0.51 1 1.139 1s1.139 -0.448 1.139 -1v-10c0 -0.552 -0.51 -1 -1.139 -1zm3.417 -1c-0.629 0 -1.14 0.448 -1.14 1v11c0 0.552 0.511 1 1.14 1 0.628 0 1.139 -0.448 1.139 -1v-11c0 -0.552 -0.51 -1 -1.14 -1zm9.041 11.658l-4.555 -11c-0.204 -0.523 -0.851 -0.8 -1.447 -0.622 -0.594 0.178 -0.912 0.747 -0.708 1.27a0.48 0.48 0 0 0 0.015 0.036l4.555 11c0.204 0.523 0.851 0.801 1.447 0.622 0.594 -0.178 0.912 -0.747 0.708 -1.27a0.48 0.48 0 0 0 -0.015 -0.036zm-15.875 -12.658c-0.628 0 -1.139 0.448 -1.139 1v12c0 0.552 0.51 1 1.14 1 0.628 0 1.138 -0.448 1.138 -1v-12c0 -0.552 -0.51 -1 -1.139 -1z"/>
+    <g mask="url(#Q)">
+      <path fill="rgb(48,163,255)" d="M7.95 26.013l2.695 1.754 1.138 0.742 1.274 -0.472 2.962 -1.096 -0.729 3.27 -0.283 1.267 0.812 1.013 2.062 2.573 -3.201 0.115 -1.442 0.052 -0.758 1.225 -1.644 2.652 -1.187 -3.053 -0.474 -1.217 -1.248 -0.385 -3.203 -0.986 2.478 -2.046 1.074 -0.887 -0.1 -1.39 -0.226 -3.129"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M7.95 26.013l2.695 1.754 1.138 0.742 1.274 -0.472 2.962 -1.096 -0.729 3.27 -0.283 1.267 0.812 1.013 2.062 2.573 -3.201 0.115 -1.442 0.052 -0.758 1.225 -1.644 2.652 -1.187 -3.053 -0.474 -1.217 -1.248 -0.385 -3.203 -0.986 2.478 -2.046 1.074 -0.887 -0.1 -1.39 -0.226 -3.129"/>
+    </g>
+  </svg>
+  <svg x="968">
+    <defs>
+      <mask id="R" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.55556 0 0 .5 13.611 28.195)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.55556 0 0 .5 13.611 28.195)"/>
+      </mask>
+    </defs>
+    <path d="M7.936 21.882c-0.614 0 -1.112 0.448 -1.112 1v10c0 0.552 0.498 1 1.112 1 0.613 0 1.11 -0.448 1.11 -1v-10c0 -0.552 -0.497 -1 -1.11 -1zm3.333 -1c-0.613 0 -1.111 0.448 -1.111 1v11c0 0.552 0.498 1 1.11 1 0.614 0 1.112 -0.448 1.112 -1v-11c0 -0.552 -0.498 -1 -1.111 -1zm8.821 11.658l-4.444 -11c-0.2 -0.523 -0.83 -0.8 -1.412 -0.622 -0.58 0.178 -0.89 0.747 -0.69 1.27a0.487 0.487 0 0 0 0.014 0.036l4.444 11c0.2 0.523 0.83 0.801 1.411 0.622 0.58 -0.178 0.89 -0.747 0.691 -1.27a0.487 0.487 0 0 0 -0.014 -0.036zm-15.488 -12.658c-0.613 0 -1.11 0.448 -1.11 1v12c0 0.552 0.497 1 1.11 1 0.614 0 1.111 -0.448 1.111 -1v-12c0 -0.552 -0.497 -1 -1.11 -1z"/>
+    <g mask="url(#R)">
+      <path fill="rgb(48,163,255)" d="M7.95 26.013l2.695 1.754 1.138 0.742 1.274 -0.472 2.962 -1.096 -0.729 3.27 -0.283 1.267 0.812 1.013 2.062 2.573 -3.201 0.115 -1.442 0.052 -0.758 1.225 -1.644 2.652 -1.187 -3.053 -0.474 -1.217 -1.248 -0.385 -3.203 -0.986 2.478 -2.046 1.074 -0.887 -0.1 -1.39 -0.226 -3.129"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M7.95 26.013l2.695 1.754 1.138 0.742 1.274 -0.472 2.962 -1.096 -0.729 3.27 -0.283 1.267 0.812 1.013 2.062 2.573 -3.201 0.115 -1.442 0.052 -0.758 1.225 -1.644 2.652 -1.187 -3.053 -0.474 -1.217 -1.248 -0.385 -3.203 -0.986 2.478 -2.046 1.074 -0.887 -0.1 -1.39 -0.226 -3.129"/>
+    </g>
+  </svg>
+  <svg x="990">
+    <defs>
+      <mask id="S" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.54167 0 0 .5 13.449 28.232)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.54167 0 0 .5 13.449 28.232)"/>
+      </mask>
+    </defs>
+    <path d="M7.915 21.919c-0.598 0 -1.083 0.448 -1.083 1v10c0 0.552 0.485 1 1.083 1s1.084 -0.448 1.084 -1v-10c0 -0.552 -0.486 -1 -1.084 -1zm3.25 -1c-0.598 0 -1.083 0.448 -1.083 1v11c0 0.552 0.485 1 1.083 1s1.084 -0.448 1.084 -1v-11c0 -0.552 -0.486 -1 -1.084 -1zm8.6 11.658l-4.333 -11c-0.193 -0.523 -0.809 -0.801 -1.375 -0.622 -0.566 0.178 -0.868 0.747 -0.674 1.27a0.494 0.494 0 0 0 0.014 0.036l4.333 11c0.194 0.523 0.81 0.8 1.376 0.622 0.566 -0.178 0.868 -0.747 0.674 -1.27a0.494 0.494 0 0 0 -0.014 -0.036zm-15.1 -12.658c-0.598 0 -1.083 0.448 -1.083 1v12c0 0.552 0.485 1 1.083 1s1.084 -0.448 1.084 -1v-12c0 -0.552 -0.486 -1 -1.084 -1z"/>
+    <g mask="url(#S)">
+      <path fill="rgb(48,163,255)" d="M7.95 26.013l2.695 1.754 1.138 0.742 1.274 -0.472 2.962 -1.096 -0.729 3.27 -0.283 1.267 0.812 1.013 2.062 2.573 -3.201 0.115 -1.442 0.052 -0.758 1.225 -1.644 2.652 -1.187 -3.053 -0.474 -1.217 -1.248 -0.385 -3.203 -0.986 2.478 -2.046 1.074 -0.887 -0.1 -1.39 -0.226 -3.129"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M7.95 26.013l2.695 1.754 1.138 0.742 1.274 -0.472 2.962 -1.096 -0.729 3.27 -0.283 1.267 0.812 1.013 2.062 2.573 -3.201 0.115 -1.442 0.052 -0.758 1.225 -1.644 2.652 -1.187 -3.053 -0.474 -1.217 -1.248 -0.385 -3.203 -0.986 2.478 -2.046 1.074 -0.887 -0.1 -1.39 -0.226 -3.129"/>
+    </g>
+  </svg>
+  <svg x="1012">
+    <defs>
+      <mask id="T" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.52778 0 0 .5 13.306 28.269)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.52778 0 0 .5 13.306 28.269)"/>
+      </mask>
+    </defs>
+    <path d="M7.914 21.956c-0.583 0 -1.056 0.448 -1.056 1v10c0 0.552 0.473 1 1.056 1 0.583 0 1.056 -0.448 1.056 -1v-10c0 -0.552 -0.473 -1 -1.056 -1zm3.167 -1c-0.583 0 -1.056 0.448 -1.056 1v11c0 0.552 0.473 1 1.056 1 0.582 0 1.055 -0.448 1.055 -1v-11c0 -0.552 -0.473 -1 -1.055 -1zm8.38 11.658l-4.222 -11c-0.19 -0.523 -0.789 -0.801 -1.341 -0.622 -0.551 0.178 -0.846 0.747 -0.657 1.27l0.014 0.036 4.222 11c0.19 0.523 0.789 0.8 1.34 0.622 0.552 -0.178 0.846 -0.747 0.657 -1.27l-0.013 -0.036zm-14.714 -12.658c-0.582 0 -1.055 0.448 -1.055 1v12c0 0.552 0.473 1 1.055 1 0.583 0 1.056 -0.448 1.056 -1v-12c0 -0.552 -0.473 -1 -1.056 -1z"/>
+    <g mask="url(#T)">
+      <path fill="rgb(48,163,255)" d="M7.95 26.013l2.695 1.754 1.138 0.742 1.274 -0.472 2.962 -1.096 -0.729 3.27 -0.283 1.267 0.812 1.013 2.062 2.573 -3.201 0.115 -1.442 0.052 -0.758 1.225 -1.644 2.652 -1.187 -3.053 -0.474 -1.217 -1.248 -0.385 -3.203 -0.986 2.478 -2.046 1.074 -0.887 -0.1 -1.39 -0.226 -3.129"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M7.95 26.013l2.695 1.754 1.138 0.742 1.274 -0.472 2.962 -1.096 -0.729 3.27 -0.283 1.267 0.812 1.013 2.062 2.573 -3.201 0.115 -1.442 0.052 -0.758 1.225 -1.644 2.652 -1.187 -3.053 -0.474 -1.217 -1.248 -0.385 -3.203 -0.986 2.478 -2.046 1.074 -0.887 -0.1 -1.39 -0.226 -3.129"/>
+    </g>
+  </svg>
+  <svg x="1034">
+    <defs>
+      <mask id="U" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.51389 0 0 .5 13.188 28.299)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.51389 0 0 .5 13.188 28.299)"/>
+      </mask>
+    </defs>
+    <path d="M7.938 21.986c-0.567 0 -1.027 0.448 -1.027 1v10c0 0.552 0.46 1 1.027 1 0.568 0 1.028 -0.448 1.028 -1v-10c0 -0.552 -0.46 -1 -1.028 -1zm3.084 -1c-0.568 0 -1.028 0.448 -1.028 1v11c0 0.552 0.46 1 1.028 1 0.567 0 1.028 -0.448 1.028 -1v-11c0 -0.552 -0.46 -1 -1.028 -1zm8.16 11.658l-4.112 -11c-0.184 -0.523 -0.768 -0.801 -1.305 -0.622 -0.537 0.178 -0.823 0.747 -0.64 1.27a0.51 0.51 0 0 0 0.014 0.036l4.111 11c0.184 0.523 0.768 0.8 1.305 0.622 0.537 -0.178 0.824 -0.747 0.64 -1.27l-0.014 -0.036zm-14.327 -12.658c-0.567 0 -1.028 0.448 -1.028 1v12c0 0.552 0.46 1 1.028 1 0.567 0 1.028 -0.448 1.028 -1v-12c0 -0.552 -0.46 -1 -1.028 -1z"/>
+    <g mask="url(#U)">
+      <path fill="rgb(48,163,255)" d="M7.95 26.013l2.695 1.754 1.138 0.742 1.274 -0.472 2.962 -1.096 -0.729 3.27 -0.283 1.267 0.812 1.013 2.062 2.573 -3.201 0.115 -1.442 0.052 -0.758 1.225 -1.644 2.652 -1.187 -3.053 -0.474 -1.217 -1.248 -0.385 -3.203 -0.986 2.478 -2.046 1.074 -0.887 -0.1 -1.39 -0.226 -3.129"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M7.95 26.013l2.695 1.754 1.138 0.742 1.274 -0.472 2.962 -1.096 -0.729 3.27 -0.283 1.267 0.812 1.013 2.062 2.573 -3.201 0.115 -1.442 0.052 -0.758 1.225 -1.644 2.652 -1.187 -3.053 -0.474 -1.217 -1.248 -0.385 -3.203 -0.986 2.478 -2.046 1.074 -0.887 -0.1 -1.39 -0.226 -3.129"/>
+    </g>
+  </svg>
+  <svg x="1056">
+    <defs>
+      <mask id="V" mask-type="alpha">
+        <path fill="rgb(48,163,255)" d="M-29.125 -76.875l-15.5 48.625 21.375 12 5.5 -0.75 3 -0.25 2.25 4.641 5.5 0.109 0.75 -2.141 3.25 -0.015 6.787 0.009 9.339 25.4 4.124 -39.128 6 -25.25 -0.75 -22.25 -51.625 -1z" transform="matrix(.5 0 0 .5 13.108 28.313)"/>
+        <path fill-opacity="0" stroke="rgb(135,17,17)" stroke-width="0" d="M-1.454 -10.124l-7.75 24.312 10.687 6 2.75 -0.375 1.5 -0.125 1.125 2.32 2.75 0.055 0.375 -1.07 1.625 -0.008 3.393 0.005 4.67 12.7 2.062 -19.564 3 -12.625 -0.375 -11.125 -25.813 -0.5z"/>
+      </mask>
+    </defs>
+    <path d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z"/>
+    <g mask="url(#V)">
+      <path fill="rgb(48,163,255)" d="M7.95 26.013l2.695 1.754 1.138 0.742 1.274 -0.472 2.962 -1.096 -0.729 3.27 -0.283 1.267 0.812 1.013 2.062 2.573 -3.201 0.115 -1.442 0.052 -0.758 1.225 -1.644 2.652 -1.187 -3.053 -0.474 -1.217 -1.248 -0.385 -3.203 -0.986 2.478 -2.046 1.074 -0.887 -0.1 -1.39 -0.226 -3.129"/>
+      <path fill="none" stroke="rgb(48,163,255)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M7.95 26.013l2.695 1.754 1.138 0.742 1.274 -0.472 2.962 -1.096 -0.729 3.27 -0.283 1.267 0.812 1.013 2.062 2.573 -3.201 0.115 -1.442 0.052 -0.758 1.225 -1.644 2.652 -1.187 -3.053 -0.474 -1.217 -1.248 -0.385 -3.203 -0.986 2.478 -2.046 1.074 -0.887 -0.1 -1.39 -0.226 -3.129"/>
+    </g>
+  </svg>
+  <svg x="1078">
+    <path d="M8 22a1 1 0 0 0 -1 1v10a1 1 0 0 0 2 0v-10a1 1 0 0 0 -1 -1zm3 -1a1 1 0 0 0 -1 1v11a1 1 0 0 0 2 0v-11a1 1 0 0 0 -1 -1zm7.939 11.658l-4 -11a1 1 0 1 0 -1.879 0.684l4 11a1 1 0 1 0 1.892 -0.648l-0.013 -0.036zm-13.939 -12.658a1 1 0 0 0 -1 1v12a1 1 0 0 0 2 0v-12a1 1 0 0 0 -1 -1z"/>
+  </svg>
+</svg>
--- a/browser/themes/shared/incontentprefs/icons.svg
+++ b/browser/themes/shared/incontentprefs/icons.svg
@@ -16,63 +16,32 @@
       fill: ThreeDHighlight;
     }
   </style>
   <defs>
     <g id="general-shape">
       <path d="M18.97,3H5.03C3.914,3,3,3.914,3,5.03v13.94C3,20.086,3.914,21,5.03,21H18.97c1.117,0,2.03-0.914,2.03-2.03 V5.03C21,3.914,20.086,3,18.97,3z M5.35,19.326c-0.404,0-0.731-0.327-0.731-0.731c0-0.404,0.327-0.731,0.731-0.731 c0.404,0,0.731,0.327,0.731,0.731C6.081,19,5.754,19.326,5.35,19.326z M5.35,6.168c-0.403,0-0.731-0.328-0.731-0.731 c0-0.404,0.328-0.731,0.731-0.731c0.403,0,0.731,0.327,0.731,0.731C6.081,5.84,5.753,6.168,5.35,6.168z M15.243,14.035 c0,0.229-0.186,0.416-0.414,0.416c-0.229,0-0.415,0.186-0.415,0.414v3.347c0,0.228-0.185,0.384-0.414,0.384l-4.141,0.03 c-0.227,0-0.414-0.186-0.414-0.414v-3.347c0-0.228-0.185-0.414-0.414-0.414c-0.227,0-0.414-0.187-0.414-0.416V6.582 c0-0.229,0.187-0.414,0.414-0.414h5.798c0.228,0,0.414,0.185,0.414,0.414V14.035z M18.509,19.326c-0.404,0-0.731-0.327-0.731-0.731 c0-0.404,0.327-0.731,0.731-0.731c0.404,0,0.731,0.327,0.731,0.731C19.24,19,18.913,19.326,18.509,19.326z M18.509,6.168 c-0.404,0-0.731-0.328-0.731-0.731c0-0.404,0.327-0.731,0.731-0.731c0.404,0,0.731,0.327,0.731,0.731 C19.24,5.84,18.913,6.168,18.509,6.168z"/>
       <path d="M12.757,7.824h-1.657c-0.456,0-0.828,0.373-0.828,0.828v8.282c0,0.456,0.373,0.828,0.828,0.828h1.657 c0.456,0,0.828-0.373,0.828-0.828V8.652C13.586,8.196,13.213,7.824,12.757,7.824z"/>
     </g>
-    <g id="content-shape">
-      <path d="M16.286,2H5.571C4.388,2,3.429,2.96,3.429,4.143v15.714 C3.429,21.04,4.388,22,5.571,22h12.857c1.185,0,2.143-0.96,2.143-2.143V6.286L16.286,2z M18.945,19.223c0,0.22-0.18,0.4-0.4,0.4 h-13.2c-0.22,0-0.4-0.18-0.4-0.4v-0.846c0-0.22,0.18-0.4,0.4-0.4h13.2c0.22,0,0.4,0.18,0.4,0.4V19.223z M18.945,15.223 c0,0.22-0.18,0.4-0.4,0.4h-13.2c-0.22,0-0.4-0.18-0.4-0.4v-0.846c0-0.22,0.18-0.4,0.4-0.4h13.2c0.22,0,0.4,0.18,0.4,0.4V15.223z M18.945,11.229c0,0.22-0.18,0.4-0.4,0.4h-13.2c-0.22,0-0.4-0.18-0.4-0.4v-0.846c0-0.22,0.18-0.4,0.4-0.4h13.2 c0.22,0,0.4,0.18,0.4,0.4V11.229z M14.833,7.707v-4.65l4.65,4.65H14.833z"/>
-    </g>
     <g id="security-shape">
       <path d="M18.909,9.783h-0.863V8.086C18.046,4.725,15.339,2,12,2 C8.661,2,5.954,4.725,5.954,8.086v1.697H5.091c-0.955,0-1.728,0.779-1.728,1.739v8.738c0,0.961,0.773,1.74,1.728,1.74h13.818 c0.954,0,1.728-0.779,1.728-1.74v-8.738C20.637,10.562,19.863,9.783,18.909,9.783z M8.545,8.086c0-1.92,1.547-3.478,3.455-3.478 c1.908,0,3.455,1.557,3.455,3.478v1.697h-6.91V8.086z M5.181,16.092l-0.909-1.2v-2.284l2.728,3.483H5.181z M8.818,16.092 l-2.773-3.657h1.727l2.864,3.657H8.818z M12,16.092l-2.773-3.657h1.727l2.864,3.657H12z M15.637,16.092l-2.773-3.657h1.727 l2.864,3.657H15.637z M19.728,16.092h-0.455l-2.773-3.657h1.727l1.501,1.916V16.092z"/>
     </g>
     <g id="sync-shape">
       <path style="fill:#F1F1F1;" d="M3.2,22h3.3h10.8h3.3c0.5,0,0.9-0.4,0.9-0.9V20c0-1-0.5-1.9-1.2-2.5c-2.3-1.8-4.6-2.9-5.1-3.1
         c-0.1,0-0.1-0.1-0.1-0.2v-1.6c0.3-0.5,0.4-1,0.5-1.5c0.2,0.1,0.6,0.1,1-1.3c0.3-1.1,0.1-1.5-0.2-1.6c0.9-4.4-1.1-4.5-1.1-4.5
         S15,3.1,14.1,2.6c-0.5-0.3-1.3-0.6-2.3-0.5c-0.4,0-0.7,0.1-1,0.2c-0.4,0.1-0.7,0.3-1,0.5C9.4,3.1,9.1,3.3,8.7,3.7
         c-0.5,0.5-1,1.2-1.1,2C7.4,6.4,7.4,7.1,7.7,7.9C7.3,7.8,6.9,8,7.3,9.5c0.3,1.1,0.6,1.4,0.8,1.4c0.1,0.6,0.3,1.3,0.7,1.9v1.4
         c0,0.1,0,0.1-0.1,0.2c-0.5,0.2-2.8,1.4-5.1,3.1C2.8,18.1,2.3,19,2.3,20v1.1C2.3,21.6,2.7,22,3.2,22"/>
     </g>
-    <g id="advanced-shape">
-      <path style="fill:#F1F1F1;" d="M21.3,15.6L21.3,15.6L21.3,15.6L21.3,15.6L21.3,15.6z M21.3,15.6c-0.1,1-0.5,1.8-1.2,2.4
-        c-0.5,0.5-1.1,0.9-1.7,1.2c-0.2,0.4-0.4,0.7-0.8,1c-0.5,0.4-1.3,0.8-2.1,1c-0.9,0.2-1.6,0.3-2.3,0.3h-0.9c0.1,0.2,0.2,0.2,0.4,0.2
-        c-1.1-0.1-2.1-0.3-2.9-0.5c0.2,0.2,0.5,0.4,0.8,0.4c-1.5-0.3-2.9-1-4.1-1.9c-0.3-0.2-0.4-0.3-0.5-0.4c-1-0.8-1.7-1.6-2.3-2.6
-        c-0.7-1.1-1.1-2.5-1.3-4.1c-0.1,0.5-0.1,0.9-0.1,1.1c-0.2-1.3-0.2-2.5,0.1-3.6c-0.1,0.3-0.3,0.7-0.4,1.1c0.1-0.8,0.4-1.8,0.9-2.8
-        C3,8.1,3.2,7.8,3.3,7.7V6.6c0-0.1,0-0.3,0.1-0.6c0-0.2,0.1-0.4,0.2-0.6v0.1V5.4c0-0.1,0-0.1,0-0.1c0-0.1,0-0.2,0.1-0.2v0.1V5.1V5
-        c0,0,0-0.1,0-0.2C4,4.4,4,4.3,4,4.3c0.2-0.1,0.2-0.2,0.3-0.2v0.1c0,0.2,0.1,0.5,0.3,1l0,0C4.8,5.3,5,5.7,5.4,5.9
-        c0.8-0.2,1.5-0.3,2.4-0.1c0.1,0,0.1-0.1,0.2-0.2v0.1c0.1-0.2,0.3-0.3,0.6-0.4l0,0c0.2-0.1,0.5-0.3,1-0.4H9.5
-        c0.1-0.1,0.2-0.1,0.3-0.1s0.2,0,0.3,0s0.3,0,0.4,0c-0.1,0-0.1,0.1-0.1,0.1L10.3,5h-0.1h0.1C9.8,5.5,9.4,6,9.2,6.7
-        c-0.1,0-0.1,0.1-0.1,0.2L9.2,7c0.2,0.3,0.5,0.5,0.9,0.5h1.4c0.2,0.1,0.3,0.2,0.3,0.2c0,0.2-0.1,0.4-0.3,0.6c0,0.1-0.1,0.2-0.3,0.4
-        C10.5,9.2,10,9.6,9.7,9.9V10c0,0,0,0,0,0.1c0,0,0,0,0,0.1c-0.1,0-0.1,0-0.1,0.1c0.1-0.1,0.2,0,0.2,0.2s0,0.4-0.1,0.6L9.6,11
-        c-0.1,0-0.1,0-0.1,0c0.1,0.1,0.2,0.1,0.2,0.2v0.1H9.6l-0.1-0.1H9.4c-0.1,0-0.1,0-0.2-0.1c-0.1,0-0.1,0-0.1,0L9,10.9
-        c-0.1,0-0.1,0-0.1,0H9c-0.1,0-0.1,0-0.2,0H8.7c-0.2,0.1-0.3,0.3-0.3,0.6c0,0.6,0.4,1.1,1.1,1.5c0.2,0.2,0.5,0.3,0.8,0.4
-        c0.3,0,0.5,0,0.7,0c0.2-0.1,0.4-0.1,0.6-0.2S12,13,12.1,13c0.7-0.2,1.4,0,1.9,0.5c0.2,0.1,0.2,0.2,0.1,0.4
-        c-0.1,0.2-0.2,0.3-0.4,0.2c-0.1,0-0.2,0-0.2,0c-0.1,0-0.1,0-0.3,0.1s-0.1,0-0.2,0s-0.2,0.1-0.3,0.2c-0.1,0.1-0.3,0.2-0.4,0.3
-        c-0.9,0.5-1.9,0.6-3,0.4c0.4,0.4,0.7,0.7,1.1,0.9c0.1,0,0.2,0.1,0.6,0.1c0.3,0,0.5,0.1,0.6,0.2c-0.2-0.1-0.5-0.1-0.7,0
-        c0.8,0.5,1.7,0.7,2.8,0.5c0.4-0.1,0.7-0.2,1-0.4c-0.1,0.1-0.1,0.3-0.2,0.4c0.1,0.1,0.4-0.1,0.6-0.5c0.1-0.1,0.3-0.3,0.6-0.4
-        c0,0,0,0.1,0,0.2s0,0.1,0,0.2s0,0.1,0.1,0.1c0.4,0,0.7-0.4,1.1-1.3c0.3-0.6,0.5-1.3,0.6-2.2c0.1,0.2,0.2,0.5,0.2,0.8
-        c0.2-0.5,0.3-1,0.3-1.3s0-1.3-0.1-2.9c0.3,0.4,0.5,0.7,0.7,1.1c0.1-1.2-0.1-2.2-0.5-3.1c-0.4-0.8-0.9-1.5-1.4-1.9
-        c0.5,0.1,1,0.3,1.4,0.6L17.8,6c-1.4-1.4-3.1-2.2-5.1-2.4S8.9,4,7.3,5.1c-0.6,0-1.1,0-1.5,0.1C5.6,4.9,5.5,4.8,5.5,4.8
-        C7.3,3,9.4,2.2,11.9,2.2s4.6,0.8,6.5,2.4l-0.2-0.4c0.6,0.3,1,0.7,1.4,1.2l-0.1-0.3v0.1l0,0c0.9,0.7,1.4,1.6,1.7,2.7
-        c0.2,0.9,0.2,1.6,0.1,2.3c0.1,0.1,0.1,0.1,0.1,0.3l0.3-1.1c0.1,0.3,0.2,0.7,0.2,1c0.1,0.4,0.1,0.8,0.1,1.1c0,0.4-0.1,0.7-0.1,1
-        c-0.1,0.3-0.1,0.7-0.2,1s-0.2,0.6-0.3,0.8c-0.1,0.2-0.2,0.5-0.3,0.7C21.1,15.1,21.2,15.2,21.3,15.6L21.3,15.6z"/>
-    </g>
-    <g id="searchResults-shape">
+    <g id="search-shape">
       <path d="M20.6,19.6l-4.4-4.5c2.4-2.9,2.4-7.1,0.2-10c-2.3-3-6.3-3.9-9.6-2.3c-3.3,1.6-5.1,5.3-4.3,9 c0.8,3.7,4,6.3,7.7,6.3c1.5,0,3-0.4,4.3-1.3l4.5,4.6c0.3,0.3,0.8,0.4,1.2,0.3c0.4-0.1,0.7-0.4,0.9-0.9S20.9,19.9,20.6,19.6z M10.1,16c-3.3,0-6-2.7-6-6.1c0-3.4,2.7-6.1,6-6.1c3.3,0,6,2.7,6,6.1C16.1,13.3,13.4,16,10.1,16z"/>
       <path d="M10.1,5.3c-2.5,0-4.6,2.1-4.6,4.7c0,1.2,0.5,2.4,1.4,3.3c0.9,0.9,2,1.4,3.3,1.4c2.5,0,4.6-2.1,4.6-4.7 C14.7,7.4,12.7,5.3,10.1,5.3z M10,7.9c-1,0-1.8,0.8-1.8,1.8c0,0.4-0.3,0.8-0.8,0.8s-0.8-0.4-0.8-0.8c0-1.9,1.5-3.4,3.3-3.4h0 c0.4,0,0.8,0.4,0.8,0.8S10.4,7.9,10,7.9z"/>
     </g>
   </defs>
   <use id="general" href="#general-shape"/>
   <use id="general-native" href="#general-shape"/>
-  <use id="content" href="#content-shape"/>
-  <use id="content-native" href="#content-shape"/>
   <use id="security" href="#security-shape"/>
   <use id="security-native" href="#security-shape"/>
   <use id="sync" href="#sync-shape"/>
   <use id="sync-native" href="#sync-shape"/>
-  <use id="advanced" href="#advanced-shape"/>
-  <use id="advanced-native" href="#advanced-shape"/>
-  <use id="searchResults" href="#searchResults-shape"/>
-  <use id="searchResults-native" href="#searchResults-shape"/>
+  <use id="search" href="#search-shape"/>
+  <use id="search-native" href="#search-shape"/>
 </svg>
--- a/browser/themes/shared/incontentprefs/preferences.inc.css
+++ b/browser/themes/shared/incontentprefs/preferences.inc.css
@@ -104,39 +104,27 @@ html|option {
   visibility: collapse;
 }
 
 #category-general > .category-icon {
   list-style-image: url("chrome://browser/skin/preferences/in-content-new/icons.svg#general");
 }
 
 #category-search > .category-icon {
-  list-style-image: url("chrome://browser/skin/preferences/in-content-new/icons.svg#searchResults");
-}
-
-#category-application > .category-icon {
-  list-style-image: url("chrome://browser/skin/preferences/in-content-new/icons.svg#content");
+  list-style-image: url("chrome://browser/skin/preferences/in-content-new/icons.svg#search");
 }
 
 #category-privacy > .category-icon {
   list-style-image: url("chrome://browser/skin/preferences/in-content-new/icons.svg#security");
 }
 
 #category-sync > .category-icon {
   list-style-image: url("chrome://browser/skin/preferences/in-content-new/icons.svg#sync");
 }
 
-#category-advanced > .category-icon {
-  list-style-image: url("chrome://browser/skin/preferences/in-content-new/icons.svg#advanced");
-}
-
-#category-search-results > .category-icon {
-  list-style-image: url("chrome://browser/skin/preferences/in-content-new/icons.svg#searchResults");
-}
-
 @media (max-width: 800px) {
   .category-name {
     display: none;
   }
   .help-button {
     font-size: 0 !important;
   }
 }
--- a/browser/themes/shared/jar.inc.mn
+++ b/browser/themes/shared/jar.inc.mn
@@ -117,16 +117,17 @@
   skin/classic/browser/arrow-dropdown.svg             (../shared/icons/arrow-dropdown.svg)
   skin/classic/browser/arrow-left.svg                 (../shared/icons/arrow-left.svg)
   skin/classic/browser/back.svg                       (../shared/icons/back.svg)
 #ifndef MOZ_PHOTON_THEME
   skin/classic/browser/back-large.svg                 (../shared/icons/back-large.svg)
 #endif
   skin/classic/browser/back-12.svg                    (../shared/icons/back-12.svg)
   skin/classic/browser/bookmark.svg                   (../shared/icons/bookmark.svg)
+  skin/classic/browser/bookmark-animation.svg         (../shared/icons/bookmark-animation.svg)
   skin/classic/browser/bookmark-hollow.svg            (../shared/icons/bookmark-hollow.svg)
 #ifndef MOZ_PHOTON_THEME
   skin/classic/browser/bookmarksMenu.svg              (../shared/icons/bookmarksMenu.svg)
 #else
   skin/classic/browser/bookmark-star-on-tray.svg      (../shared/icons/bookmark-star-on-tray.svg)
 #endif
   skin/classic/browser/characterEncoding.svg          (../shared/icons/characterEncoding.svg)
   skin/classic/browser/chevron.svg                    (../shared/icons/chevron.svg)
@@ -156,16 +157,17 @@
   skin/classic/browser/forward.svg                    (../shared/icons/forward.svg)
   skin/classic/browser/fullscreen.svg                 (../shared/icons/fullscreen.svg)
   skin/classic/browser/fullscreen-enter.svg           (../shared/icons/fullscreen-enter.svg)
   skin/classic/browser/fullscreen-exit.svg            (../shared/icons/fullscreen-exit.svg)
   skin/classic/browser/help.svg                       (../shared/icons/help.svg)
   skin/classic/browser/history.svg                    (../shared/icons/history.svg)
   skin/classic/browser/home.svg                       (../shared/icons/home.svg)
   skin/classic/browser/library.svg                    (../shared/icons/library.svg)
+  skin/classic/browser/library-bookmark-animation.svg (../shared/icons/library-bookmark-animation.svg)
 #ifdef MOZ_PHOTON_THEME
   skin/classic/browser/link.svg                       (../shared/icons/link.svg)
 #endif
   skin/classic/browser/mail.svg                       (../shared/icons/mail.svg)
   skin/classic/browser/menu.svg                       (../shared/icons/menu.svg)
   skin/classic/browser/new-tab.svg                    (../shared/icons/new-tab.svg)
   skin/classic/browser/new-window.svg                 (../shared/icons/new-window.svg)
   skin/classic/browser/open.svg                       (../shared/icons/open.svg)
--- a/browser/themes/shared/toolbarbutton-icons.inc.css
+++ b/browser/themes/shared/toolbarbutton-icons.inc.css
@@ -428,8 +428,94 @@ toolbar:not([brighttext]) #bookmarks-men
 
 #webide-button@attributeSelectorForToolbar@ {
   list-style-image: url("chrome://browser/skin/webIDE.svg");
 }
 
 #library-button {
   list-style-image: url("chrome://browser/skin/library.svg");
 }
+
+@keyframes library-bookmark-animation {
+  from {
+    transform: translateX(0);
+    fill: inherit;
+  }
+  25% {
+    fill: inherit;
+  }
+  50% {
+    fill: rgb(10,132,255);
+  }
+  to {
+    transform: translateX(-1056px);
+    fill: rgb(10,132,255);
+  }
+}
+
+@keyframes library-bookmark-animation-rtl {
+  from {
+    transform: scaleX(-1) translateX(0);
+    fill: inherit;
+  }
+  25% {
+    fill: inherit;
+  }
+  50% {
+    fill: rgb(10,132,255);
+  }
+  to {
+    transform: scaleX(-1) translateX(-1056px);
+    fill: rgb(10,132,255);
+  }
+}
+
+@keyframes library-bookmark-fade {
+  from {
+    fill: rgb(10,132,255);
+  }
+  to {
+    fill: inherit;
+  }
+}
+
+#library-button[animate="bookmark"] {
+  position: relative;
+}
+
+#library-button[animate="bookmark"] > .toolbarbutton-icon {
+  fill: transparent;
+}
+
+#library-button[animate="bookmark"] > .toolbarbutton-animatable-box {
+  position: absolute;
+  overflow: hidden;
+  top: calc(50% - 27px); /* 27px is half the height of the sprite */
+  /* Set a margin relative to the difference in widths of the .toolbarbutton-icon
+     and the .toolbar-animatable-box */
+  margin-inline-start: calc((16px + 2 * var(--toolbarbutton-inner-padding) - 22px) / 2);
+  /* Set the min- and max- width and height of the box equal to that
+     of each frame of the SVG sprite (must use min- and max- due to bug 1379332). */
+  min-width: 22px;
+  max-width: 22px;
+  min-height: 54px;
+  max-height: 54px;
+}
+
+#library-button[animate="bookmark"] > .toolbarbutton-animatable-box > .toolbarbutton-animatable-image {
+  height: var(--toolbarbutton-height);
+  background-image: url("chrome://browser/skin/library-bookmark-animation.svg");
+  width: 1078px;
+  animation-name: library-bookmark-animation;
+  animation-duration: 768ms;
+  animation-timing-function: steps(48);
+}
+
+#library-button[animate="bookmark"]:-moz-locale-dir(rtl) > .toolbarbutton-animatable-box > .toolbarbutton-animatable-image {
+  animation-name: library-bookmark-animation-rtl;
+  transform: scaleX(-1);
+}
+
+#library-button[animate="bookmark"][fade] > .toolbarbutton-animatable-box > .toolbarbutton-animatable-image {
+  animation-name: library-bookmark-fade;
+  animation-duration: 2s;
+  animation-timing-function: ease-out;
+}
--- a/browser/themes/shared/urlbar-searchbar.inc.css
+++ b/browser/themes/shared/urlbar-searchbar.inc.css
@@ -81,26 +81,93 @@
 #urlbar-page-action-button,
 .urlbar-icon {
   -moz-context-properties: fill, fill-opacity;
   fill: currentColor;
   fill-opacity: 0.6;
   color: inherit;
 }
 
+@keyframes bookmark-animation {
+  from {
+    transform: translateX(0);
+  }
+  to {
+    transform: translateX(-627px);
+  }
+}
+
+@keyframes bookmark-animation-rtl {
+  from {
+    transform: scaleX(-1) translateX(0);
+  }
+  to {
+    transform: scaleX(-1) translateX(-627px);
+  }
+}
+
+#star-button-box[animationsenabled] {
+  position: relative;
+}
+
 #star-button {
   list-style-image: url("chrome://browser/skin/bookmark-hollow.svg");
 }
 
 #star-button[starred] {
   list-style-image: url("chrome://browser/skin/bookmark.svg");
   fill-opacity: 1;
   fill: var(--toolbarbutton-icon-fill-attention);
 }
 
+/* Preload the bookmark animations to prevent a flicker during the first playing
+   of the animations. */
+#star-button[preloadanimations] + #star-button-animatable-box > #star-button-animatable-image {
+  background-image: url("chrome://browser/skin/bookmark-animation.svg"),
+                    url("chrome://browser/skin/library-bookmark-animation.svg");
+  background-size: 0, 0;
+}
+
+#star-button-box[animationsenabled] > #star-button[starred][animate] {
+  fill: transparent;
+  position: relative;
+}
+
+#star-button-box[animationsenabled] > #star-button[starred][animate] + #star-button-animatable-box {
+  position: absolute;
+  overflow: hidden;
+  top: calc(50% - 16.5px); /* 16.5px is half the height of the sprite */
+  /* .urlbar-icon has width 22px. Each frame is 33px wide. Set margin-inline-start
+     to be half the difference. */
+  margin-inline-start: -5.5px;
+  /* Set the height to equal the height of each frame of the SVG. Must use
+     min- and max- width and height due to bug 1379332. */
+  min-width: 33px;
+  max-width: 33px;
+  min-height: 33px;
+  max-height: 33px;
+}
+
+#star-button-box[animationsenabled] > #star-button[starred][animate] + #star-button-animatable-box > #star-button-animatable-image {
+  background-image: url("chrome://browser/skin/bookmark-animation.svg");
+  background-size: auto;
+  list-style-image: none;
+  height: var(--toolbarbutton-height);
+  animation-name: bookmark-animation;
+  animation-fill-mode: forwards;
+  animation-iteration-count: 1;
+  animation-timing-function: steps(19);
+  animation-duration: 304ms;
+  width: 660px;
+}
+
+#star-button-box[animationsenabled] > #star-button[starred][animate]:-moz-locale-dir(rtl) + #star-button-animatable-box > #star-button-animatable-image {
+  animation-name: bookmark-animation-rtl;
+}
+
 /* Page action popup */
 #page-action-bookmark-button {
   list-style-image: url("chrome://browser/skin/bookmark-hollow.svg");
 }
 
 #page-action-bookmark-button[starred] {
   list-style-image: url("chrome://browser/skin/bookmark.svg");
 }
--- a/build/mach_bootstrap.py
+++ b/build/mach_bootstrap.py
@@ -59,16 +59,17 @@ MACH_MODULES = [
     'testing/talos/mach_commands.py',
     'testing/web-platform/mach_commands.py',
     'testing/xpcshell/mach_commands.py',
     'tools/compare-locales/mach_commands.py',
     'tools/docs/mach_commands.py',
     'tools/lint/mach_commands.py',
     'tools/mach_commands.py',
     'tools/power/mach_commands.py',
+    'tools/tryselect/mach_commands.py',
     'mobile/android/mach_commands.py',
 ]
 
 
 CATEGORIES = {
     'build': {
         'short': 'Build Commands',
         'long': 'Interact with the build system',
old mode 100644
new mode 100755
--- a/build/moz.configure/toolchain.configure
+++ b/build/moz.configure/toolchain.configure
@@ -1042,16 +1042,24 @@ set_config('VISIBILITY_FLAGS', visibilit
 # We only want to include windows.configure when we are compiling on
 # Windows, for Windows.
 @depends(target, host)
 def is_windows(target, host):
     return host.kernel == 'WINNT' and target.kernel == 'WINNT'
 
 include('windows.configure', when=is_windows)
 
+# Shader Compiler for Windows (and MinGW Cross Compile)
+# ==============================================================
+
+fxc = check_prog('FXC', ('fxc.exe', 'fxc2.exe'), when=depends(target)
+                 (lambda t: t.kernel == 'WINNT'))
+wine = check_prog('WINE', ['wine'], when=depends(target, host)
+                  (lambda t, h: t.kernel == 'WINNT' and h.kernel == 'Linux'))
+
 # Security Hardening
 # ==============================================================
 
 option('--enable-hardening', env='MOZ_SECURITY_HARDENING',
        help='Enables security hardening compiler options')
 
 @depends('--enable-hardening', c_compiler)
 def security_hardening_cflags(value, c_compiler):
@@ -1157,13 +1165,15 @@ def enable_gold(enable_gold_option, c_co
         )
 
     # Special case for Android. In the ndk, it is gold
     if 'GNU gold' in cmd_output:
         return namespace(
             KIND='gold'
         )
 
-    die("Could not find any linker")
-
+    # For other platforms without gold or the GNU linker
+    return namespace(
+        KIND='other'
+    )
 
 set_config('LD_IS_BFD', depends(enable_gold.KIND)(lambda x: x == 'bfd' or None))
 set_config('LINKER_LDFLAGS', enable_gold.LINKER_FLAG)
--- a/build/virtualenv_packages.txt
+++ b/build/virtualenv_packages.txt
@@ -17,34 +17,34 @@ mozilla.pth:third_party/python/pystache
 mozilla.pth:third_party/python/pyyaml/lib
 mozilla.pth:third_party/python/requests
 mozilla.pth:third_party/python/slugid
 mozilla.pth:third_party/python/py
 mozilla.pth:third_party/python/pytest
 mozilla.pth:third_party/python/pytoml
 mozilla.pth:third_party/python/redo
 mozilla.pth:third_party/python/voluptuous
+mozilla.pth:third_party/python/json-e
 mozilla.pth:build
 objdir:build
 mozilla.pth:build/pymake
 mozilla.pth:config
 mozilla.pth:dom/bindings
 mozilla.pth:dom/bindings/parser
 mozilla.pth:layout/tools/reftest
 mozilla.pth:other-licenses/ply/
 mozilla.pth:taskcluster
 mozilla.pth:testing
 mozilla.pth:testing/firefox-ui/harness
 mozilla.pth:testing/marionette/client
 mozilla.pth:testing/marionette/harness
 mozilla.pth:testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py
 mozilla.pth:testing/marionette/puppeteer/firefox
 packages.txt:testing/mozbase/packages.txt
-mozilla.pth:testing/taskcluster
-mozilla.pth:testing/tools/autotry
+mozilla.pth:tools
 mozilla.pth:testing/web-platform
 mozilla.pth:testing/web-platform/tests/tools/wptrunner
 mozilla.pth:testing/web-platform/tests/tools/wptserve
 mozilla.pth:testing/web-platform/tests/tools/six
 mozilla.pth:testing/xpcshell
 mozilla.pth:third_party/python/mock-1.0.0
 mozilla.pth:xpcom/typelib/xpt/tools
 mozilla.pth:tools/docs
--- a/config/config.mk
+++ b/config/config.mk
@@ -220,16 +220,19 @@ OS_CFLAGS += $(if $(filter $(notdir $<),
 OS_CXXFLAGS += $(if $(filter $(notdir $<),$(notdir $(NO_PROFILE_GUIDED_OPTIMIZE))),,$(PROFILE_USE_CFLAGS))
 OS_LDFLAGS += $(PROFILE_USE_LDFLAGS)
 ifeq (WINNT,$(OS_ARCH))
 AR_FLAGS += -LTCG
 endif
 endif # MOZ_PROFILE_USE
 endif # NO_PROFILE_GUIDED_OPTIMIZE
 
+# linker
+OS_LDFLAGS += $(LINKER_LDFLAGS)
+
 MAKE_JARS_FLAGS = \
 	-t $(topsrcdir) \
 	-f $(MOZ_JAR_MAKER_FILE_FORMAT) \
 	$(NULL)
 
 ifdef USE_EXTENSION_MANIFEST
 MAKE_JARS_FLAGS += -e
 endif
--- a/devtools/client/definitions.js
+++ b/devtools/client/definitions.js
@@ -25,18 +25,21 @@ loader.lazyGetter(this, "ScratchpadPanel
 loader.lazyGetter(this, "DomPanel", () => require("devtools/client/dom/dom-panel").DomPanel);
 
 // Other dependencies
 loader.lazyRequireGetter(this, "CommandUtils", "devtools/client/shared/developer-toolbar", true);
 loader.lazyRequireGetter(this, "CommandState", "devtools/shared/gcli/command-state", true);
 loader.lazyImporter(this, "ResponsiveUIManager", "resource://devtools/client/responsivedesign/responsivedesign.jsm");
 loader.lazyImporter(this, "ScratchpadManager", "resource://devtools/client/scratchpad/scratchpad-manager.jsm");
 
-const {LocalizationHelper} = require("devtools/shared/l10n");
-const L10N = new LocalizationHelper("devtools/client/locales/startup.properties");
+const {MultiLocalizationHelper} = require("devtools/shared/l10n");
+const L10N = new MultiLocalizationHelper(
+  "devtools/client/locales/startup.properties",
+  "devtools/client/locales/key-shortcuts.properties"
+);
 
 var Tools = {};
 exports.Tools = Tools;
 
 // Definitions
 Tools.options = {
   id: "options",
   ordinal: 0,
@@ -57,27 +60,26 @@ Tools.options = {
   build: function (iframeWindow, toolbox) {
     return new OptionsPanel(iframeWindow, toolbox);
   }
 };
 
 Tools.inspector = {
   id: "inspector",
   accesskey: l10n("inspector.accesskey"),
-  key: l10n("inspector.commandkey"),
   ordinal: 1,
-  modifiers: osString == "Darwin" ? "accel,alt" : "accel,shift",
   icon: "chrome://devtools/skin/images/tool-inspector.svg",
   invertIconForDarkTheme: true,
   url: "chrome://devtools/content/inspector/inspector.xhtml",
   label: l10n("inspector.label"),
   panelLabel: l10n("inspector.panelLabel"),
   get tooltip() {
     return l10n("inspector.tooltip2",
-    (osString == "Darwin" ? "Cmd+Opt+" : "Ctrl+Shift+") + this.key);
+    (osString == "Darwin" ? "Cmd+Opt+" : "Ctrl+Shift+") +
+    l10n("inspector.commandkey"));
   },
   inMenu: true,
   commands: [
     "devtools/client/responsivedesign/resize-commands",
     "devtools/client/inspector/inspector-commands"
   ],
 
   preventClosingOnKey: true,
@@ -90,30 +92,29 @@ Tools.inspector = {
   },
 
   build: function (iframeWindow, toolbox) {
     return new InspectorPanel(iframeWindow, toolbox);
   }
 };
 Tools.webConsole = {
   id: "webconsole",
-  key: l10n("cmd.commandkey"),
   accesskey: l10n("webConsoleCmd.accesskey"),
-  modifiers: Services.appinfo.OS == "Darwin" ? "accel,alt" : "accel,shift",
   ordinal: 2,
   oldWebConsoleURL: "chrome://devtools/content/webconsole/webconsole.xul",
   newWebConsoleURL: "chrome://devtools/content/webconsole/webconsole.xhtml",
   icon: "chrome://devtools/skin/images/tool-webconsole.svg",
   invertIconForDarkTheme: true,
   label: l10n("ToolboxTabWebconsole.label"),
   menuLabel: l10n("MenuWebconsole.label"),
   panelLabel: l10n("ToolboxWebConsole.panelLabel"),
   get tooltip() {
     return l10n("ToolboxWebconsole.tooltip2",
-    (osString == "Darwin" ? "Cmd+Opt+" : "Ctrl+Shift+") + this.key);
+    (osString == "Darwin" ? "Cmd+Opt+" : "Ctrl+Shift+") +
+    l10n("webconsole.commandkey"));
   },
   inMenu: true,
   commands: "devtools/client/webconsole/console-commands",
 
   preventClosingOnKey: true,
   onkey: function (panel, toolbox) {
     if (toolbox.splitConsole) {
       return toolbox.focusConsoleInput();
@@ -141,29 +142,28 @@ switchWebconsole();
 
 Services.prefs.addObserver(
   "devtools.webconsole.new-frontend-enabled",
   { observe: switchWebconsole }
 );
 
 Tools.jsdebugger = {
   id: "jsdebugger",
-  key: l10n("debuggerMenu.commandkey"),
   accesskey: l10n("debuggerMenu.accesskey"),
-  modifiers: osString == "Darwin" ? "accel,alt" : "accel,shift",
   ordinal: 3,
   icon: "chrome://devtools/skin/images/tool-debugger.svg",
   invertIconForDarkTheme: true,
   highlightedicon: "chrome://devtools/skin/images/tool-debugger-paused.svg",
   url: "chrome://devtools/content/debugger/debugger.xul",
   label: l10n("ToolboxDebugger.label"),
   panelLabel: l10n("ToolboxDebugger.panelLabel"),
   get tooltip() {
     return l10n("ToolboxDebugger.tooltip2",
-    (osString == "Darwin" ? "Cmd+Opt+" : "Ctrl+Shift+") + this.key);
+    (osString == "Darwin" ? "Cmd+Opt+" : "Ctrl+Shift+") +
+    l10n("debugger.commandkey"));
   },
   inMenu: true,
   commands: "devtools/client/debugger/debugger-commands",
 
   isTargetSupported: function () {
     return true;
   },
 
@@ -189,29 +189,27 @@ switchDebugger();
 
 Services.prefs.addObserver(
   "devtools.debugger.new-debugger-frontend",
   { observe: switchDebugger }
 );
 
 Tools.styleEditor = {
   id: "styleeditor",
-  key: l10n("open.commandkey"),
   ordinal: 4,
   visibilityswitch: "devtools.styleeditor.enabled",
   accesskey: l10n("open.accesskey"),
-  modifiers: "shift",
   icon: "chrome://devtools/skin/images/tool-styleeditor.svg",
   invertIconForDarkTheme: true,
   url: "chrome://devtools/content/styleeditor/styleeditor.xul",
   label: l10n("ToolboxStyleEditor.label"),
   panelLabel: l10n("ToolboxStyleEditor.panelLabel"),
   get tooltip() {
     return l10n("ToolboxStyleEditor.tooltip3",
-    "Shift+" + functionkey(this.key));
+    "Shift+" + functionkey(l10n("styleeditor.commandkey")));
   },
   inMenu: true,
   commands: "devtools/client/styleeditor/styleeditor-commands",
 
   isTargetSupported: function (target) {
     return target.hasActor("styleEditor") || target.hasActor("styleSheets");
   },
 
@@ -268,21 +266,20 @@ Tools.performance = {
   icon: "chrome://devtools/skin/images/tool-profiler.svg",
   invertIconForDarkTheme: true,
   highlightedicon: "chrome://devtools/skin/images/tool-profiler-active.svg",
   url: "chrome://devtools/content/performance/performance.xul",
   visibilityswitch: "devtools.performance.enabled",
   label: l10n("performance.label"),
   panelLabel: l10n("performance.panelLabel"),
   get tooltip() {
-    return l10n("performance.tooltip", "Shift+" + functionkey(this.key));
+    return l10n("performance.tooltip", "Shift+" +
+    functionkey(l10n("performance.commandkey")));
   },
   accesskey: l10n("performance.accesskey"),
-  key: l10n("performance.commandkey"),
-  modifiers: "shift",
   inMenu: true,
 
   isTargetSupported: function (target) {
     return target.hasActor("profiler");
   },
 
   build: function (frame, target) {
     return new PerformancePanel(frame, target);
@@ -308,55 +305,53 @@ Tools.memory = {
   build: function (frame, target) {
     return new MemoryPanel(frame, target);
   }
 };
 
 Tools.netMonitor = {
   id: "netmonitor",
   accesskey: l10n("netmonitor.accesskey"),
-  key: l10n("netmonitor.commandkey2"),
   ordinal: 9,
-  modifiers: osString == "Darwin" ? "accel,alt" : "accel,shift",
   visibilityswitch: "devtools.netmonitor.enabled",
   icon: "chrome://devtools/skin/images/tool-network.svg",
   invertIconForDarkTheme: true,
   url: "chrome://devtools/content/netmonitor/index.html",
   label: l10n("netmonitor.label"),
   panelLabel: l10n("netmonitor.panelLabel"),
   get tooltip() {
     return l10n("netmonitor.tooltip2",
-    (osString == "Darwin" ? "Cmd+Opt+" : "Ctrl+Shift+") + this.key);
+    (osString == "Darwin" ? "Cmd+Opt+" : "Ctrl+Shift+") +
+    l10n("netmonitor.commandkey"));
   },
   inMenu: true,
 
   isTargetSupported: function (target) {
     return target.getTrait("networkMonitor");
   },
 
   build: function (iframeWindow, toolbox) {
     return new NetMonitorPanel(iframeWindow, toolbox);
   }
 };
 
 Tools.storage = {
   id: "storage",
-  key: l10n("storage.commandkey"),
   ordinal: 10,
   accesskey: l10n("storage.accesskey"),
-  modifiers: "shift",
   visibilityswitch: "devtools.storage.enabled",
   icon: "chrome://devtools/skin/images/tool-storage.svg",
   invertIconForDarkTheme: true,
   url: "chrome://devtools/content/storage/storage.xul",
   label: l10n("storage.label"),
   menuLabel: l10n("storage.menuLabel"),
   panelLabel: l10n("storage.panelLabel"),
   get tooltip() {
-    return l10n("storage.tooltip3", "Shift+" + functionkey(this.key));
+    return l10n("storage.tooltip3", "Shift+" +
+    functionkey(l10n("storage.commandkey")));
   },
   inMenu: true,
 
   isTargetSupported: function (target) {
     return target.isLocalTab ||
            (target.hasActor("storage") && target.getTrait("storageInspector"));
   },
 
@@ -405,28 +400,27 @@ Tools.scratchpad = {
   build: function (iframeWindow, toolbox) {
     return new ScratchpadPanel(iframeWindow, toolbox);
   }
 };
 
 Tools.dom = {
   id: "dom",
   accesskey: l10n("dom.accesskey"),
-  key: l10n("dom.commandkey"),
   ordinal: 13,
-  modifiers: osString == "Darwin" ? "accel,alt" : "accel,shift",
   visibilityswitch: "devtools.dom.enabled",
   icon: "chrome://devtools/skin/images/tool-dom.svg",
   invertIconForDarkTheme: true,
   url: "chrome://devtools/content/dom/dom.html",
   label: l10n("dom.label"),
   panelLabel: l10n("dom.panelLabel"),
   get tooltip() {
     return l10n("dom.tooltip",
-      (osString == "Darwin" ? "Cmd+Opt+" : "Ctrl+Shift+") + this.key);
+      (osString == "Darwin" ? "Cmd+Opt+" : "Ctrl+Shift+") +
+      l10n("dom.commandkey"));
   },
   inMenu: true,
 
   isTargetSupported: function (target) {
     return target.getTrait("webConsoleCommands");
   },
 
   build: function (iframeWindow, toolbox) {
--- a/devtools/client/devtools-startup.js
+++ b/devtools/client/devtools-startup.js
@@ -1,30 +1,166 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /**
  * This XPCOM component is loaded very early.
- * It handles command line arguments like -jsconsole, but also ensures starting
+ * Be careful to lazy load dependencies as much as possible.
+ *
+ * It manages all the possible entry points for DevTools:
+ * - Handles command line arguments like -jsconsole,
+ * - Register all key shortcuts,
+ * - Listen for "Web Developer" system menu opening, under "Tools",
+ * - Inject the wrench icon in toolbar customization, which is used
+ *   by the "Web Developer" list displayed in the hamburger menu,
+ * - Register the JSON Viewer protocol handler.
+ *
+ * Only once any of these entry point is fired, this module ensures starting
  * core modules like 'devtools-browser.js' that hooks the browser windows
  * and ensure setting up tools.
- *
- * Be careful to lazy load dependencies as much as possible.
  **/
 
 "use strict";
 
 const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 const kDebuggerPrefs = [
   "devtools.debugger.remote-enabled",
   "devtools.chrome.enabled"
 ];
 const { XPCOMUtils } = Cu.import("resource://gre/modules/XPCOMUtils.jsm", {});
-XPCOMUtils.defineLazyModuleGetter(this, "Services", "resource://gre/modules/Services.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Services",
+                                  "resource://gre/modules/Services.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "AppConstants",
+                                  "resource://gre/modules/AppConstants.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "CustomizableUI",
+                                  "resource:///modules/CustomizableUI.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "CustomizableWidgets",
+                                  "resource:///modules/CustomizableWidgets.jsm");
+
+XPCOMUtils.defineLazyGetter(this, "Bundle", function () {
+  const kUrl = "chrome://devtools/locale/key-shortcuts.properties";
+  return Services.strings.createBundle(kUrl);
+});
+
+XPCOMUtils.defineLazyGetter(this, "KeyShortcuts", function () {
+  const isMac = AppConstants.platform == "macosx";
+
+  // Common modifier shared by most key shortcuts
+  const modifiers = isMac ? "accel,alt" : "accel,shift";
+
+  // List of all key shortcuts triggering installation UI
+  // `id` should match tool's id from client/definitions.js
+  return [
+    // The following keys are also registered in /client/menus.js
+    // And should be synced.
+
+    // Both are toggling the toolbox on the last selected panel
+    // or the default one.
+    {
+      id: "toggleToolbox",
+      shortcut: Bundle.GetStringFromName("toggleToolbox.commandkey"),
+      modifiers
+    },
+    // All locales are using F12
+    {
+      id: "toggleToolboxF12",
+      shortcut: Bundle.GetStringFromName("toggleToolboxF12.commandkey"),
+      modifiers: "" // F12 is the only one without modifiers
+    },
+    // Toggle the visibility of the Developer Toolbar (=gcli)
+    {
+      id: "toggleToolbar",
+      shortcut: Bundle.GetStringFromName("toggleToolbar.commandkey"),
+      modifiers: "shift"
+    },
+    // Open WebIDE window
+    {
+      id: "webide",
+      shortcut: Bundle.GetStringFromName("webide.commandkey"),
+      modifiers: "shift"
+    },
+    // Open the Browser Toolbox
+    {
+      id: "browserToolbox",
+      shortcut: Bundle.GetStringFromName("browserToolbox.commandkey"),
+      modifiers: "accel,alt,shift"
+    },
+    // Open the Browser Console
+    {
+      id: "browserConsole",
+      shortcut: Bundle.GetStringFromName("browserConsole.commandkey"),
+      modifiers: "accel,shift"
+    },
+    // Toggle the Responsive Design Mode
+    {
+      id: "responsiveDesignMode",
+      shortcut: Bundle.GetStringFromName("responsiveDesignMode.commandkey"),
+      modifiers
+    },
+    // Open ScratchPad window
+    {
+      id: "scratchpad",
+      shortcut: Bundle.GetStringFromName("scratchpad.commandkey"),
+      modifiers: "shift"
+    },
+
+    // The following keys are also registered in /client/definitions.js
+    // and should be synced.
+
+    // Key for opening the Inspector
+    {
+      toolId: "inspector",
+      shortcut: Bundle.GetStringFromName("inspector.commandkey"),
+      modifiers
+    },
+    // Key for opening the Web Console
+    {
+      toolId: "webconsole",
+      shortcut: Bundle.GetStringFromName("webconsole.commandkey"),
+      modifiers
+    },
+    // Key for opening the Debugger
+    {
+      toolId: "jsdebugger",
+      shortcut: Bundle.GetStringFromName("debugger.commandkey"),
+      modifiers
+    },
+    // Key for opening the Network Monitor
+    {
+      toolId: "netmonitor",
+      shortcut: Bundle.GetStringFromName("netmonitor.commandkey"),
+      modifiers
+    },
+    // Key for opening the Style Editor
+    {
+      toolId: "styleeditor",
+      shortcut: Bundle.GetStringFromName("styleeditor.commandkey"),
+      modifiers: "shift"
+    },
+    // Key for opening the Performance Panel
+    {
+      toolId: "performance",
+      shortcut: Bundle.GetStringFromName("performance.commandkey"),
+      modifiers: "shift"
+    },
+    // Key for opening the Storage Panel
+    {
+      toolId: "storage",
+      shortcut: Bundle.GetStringFromName("storage.commandkey"),
+      modifiers: "shift"
+    },
+    // Key for opening the DOM Panel
+    {
+      toolId: "dom",
+      shortcut: Bundle.GetStringFromName("dom.commandkey"),
+      modifiers
+    },
+  ];
+});
 
 function DevToolsStartup() {}
 
 DevToolsStartup.prototype = {
   handle: function (cmdLine) {
     let consoleFlag = cmdLine.handleFlag("jsconsole", false);
     let debuggerFlag = cmdLine.handleFlag("jsdebugger", false);
     let devtoolsFlag = cmdLine.handleFlag("devtools", false);
@@ -43,34 +179,193 @@ DevToolsStartup.prototype = {
       // We get an error if the option is given but not followed by a value.
       // By catching and trying again, the value is effectively optional.
       debuggerServerFlag = cmdLine.handleFlag("start-debugger-server", false);
     }
     if (debuggerServerFlag) {
       this.handleDebuggerServerFlag(cmdLine, debuggerServerFlag);
     }
 
-    let onStartup = window => {
-      Services.obs.removeObserver(onStartup,
-                                  "browser-delayed-startup-finished");
-      // Ensure loading core module once firefox is ready
-      this.initDevTools();
+    // Only top level Firefox Windows fire a browser-delayed-startup-finished event
+    let onWindowReady = window => {
+      this.hookWindow(window);
 
       if (devtoolsFlag) {
         this.handleDevToolsFlag(window);
+        // This listener is called for all Firefox windows, but we want to execute
+        // that command only once
+        devtoolsFlag = false;
       }
+      JsonView.initialize();
     };
-    Services.obs.addObserver(onStartup, "browser-delayed-startup-finished");
+    Services.obs.addObserver(onWindowReady, "browser-delayed-startup-finished");
+  },
+
+  /**
+   * Register listeners to all possible entry points for Developer Tools.
+   * But instead of implementing the actual actions, defer to DevTools codebase.
+   * In most cases, it only needs to call this.initDevTools which handles the rest.
+   * We do that to prevent loading any DevTools module until the user intent to use them.
+   */
+  hookWindow(window) {
+    this.hookKeyShortcuts(window);
+
+    // All the other hooks are only necessary if the tools aren't loaded yet.
+    if (this.initialized) {
+      return;
+    }
+
+    this.hookWebDeveloperMenu(window);
+    this.hookDeveloperToggle(window);
   },
 
+  /**
+   * Dynamically register a wrench icon in the customization menu.
+   * You can use this button by right clicking on Firefox toolbar
+   * and dragging it from the customization panel to the toolbar.
+   * (i.e. this isn't displayed by default to users!)
+   *
+   * _But_, the "Web Developer" entry in the hamburger menu (the menu with
+   * 3 horizontal lines), is using this "developer-button" view to populate
+   * its menu. So we have to register this button for the menu to work.
+   *
+   * Also, this menu duplicates its own entries from the "Web Developer"
+   * menu in the system menu, under "Tools" main menu item. The system
+   * menu is being hooked by "hookWebDeveloperMenu" which ends up calling
+   * devtools/client/framework/browser-menu to create the items for real,
+   * initDevTools, from onViewShowing is also calling browser-menu.
+   */
+  hookDeveloperToggle(window) {
+    let id = "developer-button";
+    let widget = CustomizableUI.getWidget(id);
+    if (widget && widget.provider == CustomizableUI.PROVIDER_API) {
+      return;
+    }
+    let item = {
+      id: id,
+      type: "view",
+      viewId: "PanelUI-developer",
+      shortcutId: "key_toggleToolbox",
+      tooltiptext: "developer-button.tooltiptext2",
+      defaultArea: AppConstants.MOZ_DEV_EDITION ?
+                     CustomizableUI.AREA_NAVBAR :
+                     CustomizableUI.AREA_PANEL,
+      onViewShowing: (event) => {
+        // Ensure creating the menuitems in the system menu before trying to copy them.
+        this.initDevTools();
+
+        // Populate the subview with whatever menuitems are in the developer
+        // menu. We skip menu elements, because the menu panel has no way
+        // of dealing with those right now.
+        let doc = event.target.ownerDocument;
+
+        let menu = doc.getElementById("menuWebDeveloperPopup");
+
+        let itemsToDisplay = [...menu.children];
+        // Hardcode the addition of the "work offline" menuitem at the bottom:
+        itemsToDisplay.push({localName: "menuseparator", getAttribute: () => {}});
+        itemsToDisplay.push(doc.getElementById("goOfflineMenuitem"));
+
+        let developerItems = doc.getElementById("PanelUI-developerItems");
+        // Import private helpers from CustomizableWidgets
+        let { clearSubview, fillSubviewFromMenuItems } =
+          Cu.import("resource:///modules/CustomizableWidgets.jsm", {});
+        clearSubview(developerItems);
+        fillSubviewFromMenuItems(itemsToDisplay, developerItems);
+      },
+      onInit(anchor) {
+        // Since onBeforeCreated already bails out when initialized, we can call
+        // it right away.
+        this.onBeforeCreated(anchor.ownerDocument);
+      },
+      onBeforeCreated(doc) {
+        // Bug 1223127, CUI should make this easier to do.
+        if (doc.getElementById("PanelUI-developerItems")) {
+          return;
+        }
+        let view = doc.createElement("panelview");
+        view.id = "PanelUI-developerItems";
+        let panel = doc.createElement("vbox");
+        panel.setAttribute("class", "panel-subview-body");
+        view.appendChild(panel);
+        doc.getElementById("PanelUI-multiView").appendChild(view);
+      }
+    };
+    CustomizableUI.createWidget(item);
+    CustomizableWidgets.push(item);
+  },
+
+  /*
+   * We listen to the "Web Developer" system menu, which is under "Tools" main item.
+   * This menu item is hardcoded empty in Firefox UI. We listen for its opening to
+   * populate it lazily. Loading main DevTools module is going to populate it.
+   */
+  hookWebDeveloperMenu(window) {
+    let menu = window.document.getElementById("webDeveloperMenu");
+    menu.addEventListener("popupshowing", () => this.initDevTools(), { once: true });
+  },
+
+  hookKeyShortcuts(window) {
+    let doc = window.document;
+    let keyset = doc.createElement("keyset");
+    keyset.setAttribute("id", "devtoolsKeyset");
+
+    for (let key of KeyShortcuts) {
+      let xulKey = this.createKey(doc, key, () => this.onKey(window, key));
+      keyset.appendChild(xulKey);
+    }
+
+    // Appending a <key> element is not always enough. The <keyset> needs
+    // to be detached and reattached to make sure the <key> is taken into
+    // account (see bug 832984).
+    let mainKeyset = doc.getElementById("mainKeyset");
+    mainKeyset.parentNode.insertBefore(keyset, mainKeyset);
+  },
+
+  onKey(window, key) {
+    let require = this.initDevTools();
+    let { gDevToolsBrowser } = require("devtools/client/framework/devtools-browser");
+    gDevToolsBrowser.onKeyShortcut(window, key);
+  },
+
+  // Create a <xul:key> DOM Element
+  createKey(doc, { id, toolId, shortcut, modifiers: mod }, oncommand) {
+    let k = doc.createElement("key");
+    k.id = "key_" + (id || toolId);
+
+    if (shortcut.startsWith("VK_")) {
+      k.setAttribute("keycode", shortcut);
+    } else {
+      k.setAttribute("key", shortcut);
+    }
+
+    if (mod) {
+      k.setAttribute("modifiers", mod);
+    }
+
+    // Bug 371900: command event is fired only if "oncommand" attribute is set.
+    k.setAttribute("oncommand", ";");
+    k.addEventListener("command", oncommand);
+
+    return k;
+  },
+
+  /**
+   * Boolean flag to check if DevTools have been already initialized or not.
+   * By initialized, we mean that its main modules are loaded.
+   */
+  initialized: false,
+
   initDevTools: function () {
-    let { loader } = Cu.import("resource://devtools/shared/Loader.jsm", {});
+    this.initialized = true;
+    let { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
     // Ensure loading main devtools module that hooks up into browser UI
     // and initialize all devtools machinery.
-    loader.require("devtools/client/framework/devtools-browser");
+    require("devtools/client/framework/devtools-browser");
+    return require;
   },
 
   handleConsoleFlag: function (cmdLine) {
     let window = Services.wm.getMostRecentWindow("devtools:webconsole");
     if (!window) {
       this.initDevTools();
 
       let { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
@@ -84,17 +379,17 @@ DevToolsStartup.prototype = {
 
     if (cmdLine.state == Ci.nsICommandLine.STATE_REMOTE_AUTO) {
       cmdLine.preventDefault = true;
     }
   },
 
   // Open the toolbox on the selected tab once the browser starts up.
   handleDevToolsFlag: function (window) {
-    const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
+    const require = this.initDevTools();
     const {gDevTools} = require("devtools/client/framework/devtools");
     const {TargetFactory} = require("devtools/client/framework/target");
     let target = TargetFactory.forTab(window.gBrowser.selectedTab);
     gDevTools.showToolbox(target);
   },
 
   _isRemoteDebuggingEnabled() {
     let remoteDebuggingEnabled = false;
@@ -213,26 +508,97 @@ DevToolsStartup.prototype = {
       dump("Unable to start debugger server on " + portOrPath + ": " + e);
     }
 
     if (cmdLine.state == Ci.nsICommandLine.STATE_REMOTE_AUTO) {
       cmdLine.preventDefault = true;
     }
   },
 
+  // Used by tests and the toolbox to register the same key shortcuts in toolboxes loaded
+  // in a window window.
+  get KeyShortcuts() {
+    return KeyShortcuts;
+  },
+  get wrappedJSObject() {
+    return this;
+  },
+
   /* eslint-disable max-len */
   helpInfo: "  --jsconsole        Open the Browser Console.\n" +
             "  --jsdebugger       Open the Browser Toolbox.\n" +
             "  --wait-for-jsdebugger Spin event loop until JS debugger connects.\n" +
             "                     Enables debugging (some) application startup code paths.\n" +
             "                     Only has an effect when `--jsdebugger` is also supplied.\n" +
             "  --devtools         Open DevTools on initial load.\n" +
             "  --start-debugger-server [ws:][ <port> | <path> ] Start the debugger server on\n" +
             "                     a TCP port or Unix domain socket path. Defaults to TCP port\n" +
             "                     6000. Use WebSocket protocol if ws: prefix is specified.\n",
   /* eslint-disable max-len */
 
   classID: Components.ID("{9e9a9283-0ce9-4e4a-8f1c-ba129a032c32}"),
   QueryInterface: XPCOMUtils.generateQI([Ci.nsICommandLineHandler]),
 };
 
+/**
+ * Singleton object that represents the JSON View in-content tool.
+ * It has the same lifetime as the browser.
+ */
+const JsonView = {
+  initialized: false,
+
+  initialize: function () {
+    // Prevent loading the frame script multiple times if we call this more than once.
+    if (this.initialized) {
+      return;
+    }
+    this.initialized = true;
+
+    // Load JSON converter module. This converter is responsible
+    // for handling 'application/json' documents and converting
+    // them into a simple web-app that allows easy inspection
+    // of the JSON data.
+    Services.ppmm.loadProcessScript(
+      "resource://devtools/client/jsonview/converter-observer.js",
+      true);
+
+    // Register for messages coming from the child process.
+    // This is never removed as there is no particular need to unregister
+    // it during shutdown.
+    Services.ppmm.addMessageListener(
+      "devtools:jsonview:save", this.onSave);
+  },
+
+  // Message handlers for events from child processes
+
+  /**
+   * Save JSON to a file needs to be implemented here
+   * in the parent process.
+   */
+  onSave: function (message) {
+    let chrome = Services.wm.getMostRecentWindow("navigator:browser");
+    let browser = chrome.gBrowser.selectedBrowser;
+    if (message.data.url === null) {
+      // Save original contents
+      chrome.saveBrowser(browser, false, message.data.windowID);
+    } else {
+      // The following code emulates saveBrowser, but:
+      // - Uses the given blob URL containing the custom contents to save.
+      // - Obtains the file name from the URL of the document, not the blob.
+      let persistable = browser.QueryInterface(Ci.nsIFrameLoaderOwner)
+        .frameLoader.QueryInterface(Ci.nsIWebBrowserPersistable);
+      persistable.startPersistence(message.data.windowID, {
+        onDocumentReady(doc) {
+          let uri = chrome.makeURI(doc.documentURI, doc.characterSet);
+          let filename = chrome.getDefaultFileName(undefined, uri, doc, null);
+          chrome.internalSave(message.data.url, doc, filename, null, doc.contentType,
+            false, null, null, null, doc, false, null, undefined);
+        },
+        onError(status) {
+          throw new Error("JSON Viewer's onSave failed in startPersistence");
+        }
+      });
+    }
+  }
+};
+
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory(
   [DevToolsStartup]);
--- a/devtools/client/framework/browser-menus.js
+++ b/devtools/client/framework/browser-menus.js
@@ -1,18 +1,18 @@
 /* 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";
 
 /**
- * This module inject dynamically menu items and key shortcuts into browser UI.
+ * This module inject dynamically menu items into browser UI.
  *
- * Menu and shortcut definitions are fetched from:
+ * Menu definitions are fetched from:
  * - devtools/client/menus for top level entires
  * - devtools/client/definitions for tool-specifics entries
  */
 
 const {LocalizationHelper} = require("devtools/shared/l10n");
 const MENUS_L10N = new LocalizationHelper("devtools/client/locales/menus.properties");
 
 loader.lazyRequireGetter(this, "gDevTools", "devtools/client/framework/devtools", true);
@@ -22,63 +22,20 @@ loader.lazyRequireGetter(this, "gDevTool
 // Maps browser xul document => list of DOM Elements
 const FragmentsCache = new Map();
 
 function l10n(key) {
   return MENUS_L10N.getStr(key);
 }
 
 /**
- * Create a xul:key element
- *
- * @param {XULDocument} doc
- *        The document to which keys are to be added.
- * @param {String} id
- *        key's id, automatically prefixed with "key_".
- * @param {String} shortcut
- *        The key shortcut value.
- * @param {String} keytext
- *        If `shortcut` refers to a function key, refers to the localized
- *        string to describe a non-character shortcut.
- * @param {String} modifiers
- *        Space separated list of modifier names.
- * @param {Function} oncommand
- *        The function to call when the shortcut is pressed.
- *
- * @return XULKeyElement
- */
-function createKey({ doc, id, shortcut, keytext, modifiers, oncommand }) {
-  let k = doc.createElement("key");
-  k.id = "key_" + id;
-
-  if (shortcut.startsWith("VK_")) {
-    k.setAttribute("keycode", shortcut);
-    if (keytext) {
-      k.setAttribute("keytext", keytext);
-    }
-  } else {
-    k.setAttribute("key", shortcut);
-  }
-
-  if (modifiers) {
-    k.setAttribute("modifiers", modifiers);
-  }
-
-  // Bug 371900: command event is fired only if "oncommand" attribute is set.
-  k.setAttribute("oncommand", ";");
-  k.addEventListener("command", oncommand);
-
-  return k;
-}
-
-/**
  * Create a xul:menuitem element
  *
  * @param {XULDocument} doc
- *        The document to which keys are to be added.
+ *        The document to which menus are to be added.
  * @param {String} id
  *        Element id.
  * @param {String} label
  *        Menu label.
  * @param {String} accesskey (optional)
  *        Access key of the menuitem, used as shortcut while opening the menu.
  * @param {Boolean} isCheckbox (optional)
  *        If true, the menuitem will act as a checkbox and have an optional
@@ -96,39 +53,16 @@ function createMenuItem({ doc, id, label
   if (isCheckbox) {
     menuitem.setAttribute("type", "checkbox");
     menuitem.setAttribute("autocheck", "false");
   }
   return menuitem;
 }
 
 /**
- * Add a <key> to <keyset id="devtoolsKeyset">.
- * Appending a <key> element is not always enough. The <keyset> needs
- * to be detached and reattached to make sure the <key> is taken into
- * account (see bug 832984).
- *
- * @param {XULDocument} doc
- *        The document to which keys are to be added
- * @param {XULElement} or {DocumentFragment} keys
- *        Keys to add
- */
-function attachKeybindingsToBrowser(doc, keys) {
-  let devtoolsKeyset = doc.getElementById("devtoolsKeyset");
-
-  if (!devtoolsKeyset) {
-    devtoolsKeyset = doc.createElement("keyset");
-    devtoolsKeyset.setAttribute("id", "devtoolsKeyset");
-  }
-  devtoolsKeyset.appendChild(keys);
-  let mainKeyset = doc.getElementById("mainKeyset");
-  mainKeyset.parentNode.insertBefore(devtoolsKeyset, mainKeyset);
-}
-
-/**
  * Add a menu entry for a tool definition
  *
  * @param {Object} toolDefinition
  *        Tool definition of the tool to add a menu entry.
  * @param {XULDocument} doc
  *        The document to which the tool menu item is to be added.
  */
 function createToolMenuElements(toolDefinition, doc) {
@@ -140,62 +74,45 @@ function createToolMenuElements(toolDefi
     return;
   }
 
   let oncommand = function (id, event) {
     let window = event.target.ownerDocument.defaultView;
     gDevToolsBrowser.selectToolCommand(window.gBrowser, id);
   }.bind(null, id);
 
-  let key = null;
-  if (toolDefinition.key) {
-    key = createKey({
-      doc,
-      id,
-      shortcut: toolDefinition.key,
-      modifiers: toolDefinition.modifiers,
-      oncommand: oncommand
-    });
-  }
-
   let menuitem = createMenuItem({
     doc,
     id: "menuitem_" + id,
     label: toolDefinition.menuLabel || toolDefinition.label,
     accesskey: toolDefinition.accesskey
   });
-  if (key) {
-    // Refer to the key in order to display the key shortcut at menu ends
-    menuitem.setAttribute("key", key.id);
-  }
+  // Refer to the key in order to display the key shortcut at menu ends
+  // This <key> element is being created by devtools/client/devtools-startup.js
+  menuitem.setAttribute("key", "key_" + id);
   menuitem.addEventListener("command", oncommand);
 
   return {
-    key,
     menuitem
   };
 }
 
 /**
  * Create xul menuitem, key elements for a given tool.
  * And then insert them into browser DOM.
  *
  * @param {XULDocument} doc
  *        The document to which the tool is to be registered.
  * @param {Object} toolDefinition
  *        Tool definition of the tool to register.
  * @param {Object} prevDef
  *        The tool definition after which the tool menu item is to be added.
  */
 function insertToolMenuElements(doc, toolDefinition, prevDef) {
-  let { key, menuitem } = createToolMenuElements(toolDefinition, doc);
-
-  if (key) {
-    attachKeybindingsToBrowser(doc, key);
-  }
+  let { menuitem } = createToolMenuElements(toolDefinition, doc);
 
   let ref;
   if (prevDef) {
     let menuitem = doc.getElementById("menuitem_" + prevDef.id);
     ref = menuitem && menuitem.nextSibling ? menuitem.nextSibling : null;
   } else {
     ref = doc.getElementById("menu_devtools_separator");
   }
@@ -249,32 +166,29 @@ function addAllToolsToMenu(doc) {
     }
 
     if (elements.key) {
       fragKeys.appendChild(elements.key);
     }
     fragMenuItems.appendChild(elements.menuitem);
   }
 
-  attachKeybindingsToBrowser(doc, fragKeys);
-
   let mps = doc.getElementById("menu_devtools_separator");
   if (mps) {
     mps.parentNode.insertBefore(fragMenuItems, mps);
   }
 }
 
 /**
- * Add global menus and shortcuts that are not panel specific.
+ * Add global menus that are not panel specific.
  *
  * @param {XULDocument} doc
- *        The document to which keys and menus are to be added.
+ *        The document to which menus are to be added.
  */
 function addTopLevelItems(doc) {
-  let keys = doc.createDocumentFragment();
   let menuItems = doc.createDocumentFragment();
 
   let { menuitems } = require("../menus");
   for (let item of menuitems) {
     if (item.separator) {
       let separator = doc.createElement("menuseparator");
       separator.id = item.id;
       menuItems.appendChild(separator);
@@ -287,104 +201,72 @@ function addTopLevelItems(doc) {
         id,
         label: l10n(l10nKey + ".label"),
         accesskey: l10n(l10nKey + ".accesskey"),
         isCheckbox: item.checkbox
       });
       menuitem.addEventListener("command", item.oncommand);
       menuItems.appendChild(menuitem);
 
-      if (item.key && l10nKey) {
-        // Create a <key>
-        let shortcut = l10n(l10nKey + ".key");
-        let key = createKey({
-          doc,
-          id: item.key.id,
-          shortcut: shortcut,
-          keytext: shortcut.startsWith("VK_") ? l10n(l10nKey + ".keytext") : null,
-          modifiers: item.key.modifiers,
-          oncommand: item.oncommand
-        });
-        // Refer to the key in order to display the key shortcut at menu ends
-        menuitem.setAttribute("key", key.id);
-        keys.appendChild(key);
-      }
-      if (item.additionalKeys) {
-        // Create additional <key>
-        for (let key of item.additionalKeys) {
-          let shortcut = l10n(key.l10nKey + ".key");
-          let node = createKey({
-            doc,
-            id: key.id,
-            shortcut: shortcut,
-            keytext: shortcut.startsWith("VK_") ? l10n(key.l10nKey + ".keytext") : null,
-            modifiers: key.modifiers,
-            oncommand: item.oncommand
-          });
-          keys.appendChild(node);
-        }
+      if (item.keyId) {
+        menuitem.setAttribute("key", "key_" + item.keyId);
       }
     }
   }
 
   // Cache all nodes before insertion to be able to remove them on unload
   let nodes = [];
-  for (let node of keys.children) {
-    nodes.push(node);
-  }
   for (let node of menuItems.children) {
     nodes.push(node);
   }
   FragmentsCache.set(doc, nodes);
 
-  attachKeybindingsToBrowser(doc, keys);
-
   let menu = doc.getElementById("menuWebDeveloperPopup");
   menu.appendChild(menuItems);
 
   // There is still "Page Source" menuitem hardcoded into browser.xul. Instead
   // of manually inserting everything around it, move it to the expected
   // position.
   let pageSource = doc.getElementById("menu_pageSource");
   let endSeparator = doc.getElementById("devToolsEndSeparator");
   menu.insertBefore(pageSource, endSeparator);
 }
 
 /**
- * Remove global menus and shortcuts that are not panel specific.
+ * Remove global menus that are not panel specific.
  *
  * @param {XULDocument} doc
- *        The document to which keys and menus are to be added.
+ *        The document to which menus are to be added.
  */
 function removeTopLevelItems(doc) {
   let nodes = FragmentsCache.get(doc);
   if (!nodes) {
     return;
   }
   FragmentsCache.delete(doc);
   for (let node of nodes) {
     node.remove();
   }
 }
 
 /**
- * Add menus and shortcuts to a browser document
+ * Add menus to a browser document
  *
  * @param {XULDocument} doc
- *        The document to which keys and menus are to be added.
+ *        The document to which menus are to be added.
  */
 exports.addMenus = function (doc) {
   addTopLevelItems(doc);
 
   addAllToolsToMenu(doc);
 };
 
 /**
- * Remove menus and shortcuts from a browser document
+ * Remove menus from a browser document
  *
  * @param {XULDocument} doc
- *        The document to which keys and menus are to be removed.
+ *        The document to which menus are to be removed.
  */
 exports.removeMenus = function (doc) {
   // We only remove top level entries. Per-tool entries are removed while
   // unregistering each tool.
   removeTopLevelItems(doc);
 };
--- a/devtools/client/framework/devtools-browser.js
+++ b/devtools/client/framework/devtools-browser.js
@@ -7,29 +7,32 @@
 /**
  * This is the main module loaded in Firefox desktop that handles browser
  * windows and coordinates devtools around each window.
  *
  * This module is loaded lazily by devtools-clhandler.js, once the first
  * browser window is ready (i.e. fired browser-delayed-startup-finished event)
  **/
 
-const {Cc, Ci, Cu} = require("chrome");
+const {Cc, Ci} = require("chrome");
 const Services = require("Services");
 const defer = require("devtools/shared/defer");
 const {gDevTools} = require("./devtools");
 
 // Load target and toolbox lazily as they need gDevTools to be fully initialized
 loader.lazyRequireGetter(this, "TargetFactory", "devtools/client/framework/target", true);
 loader.lazyRequireGetter(this, "Toolbox", "devtools/client/framework/toolbox", true);
 loader.lazyRequireGetter(this, "DebuggerServer", "devtools/server/main", true);
 loader.lazyRequireGetter(this, "DebuggerClient", "devtools/shared/client/main", true);
 loader.lazyRequireGetter(this, "BrowserMenus", "devtools/client/framework/browser-menus");
 loader.lazyRequireGetter(this, "appendStyleSheet", "devtools/client/shared/stylesheet-utils", true);
 loader.lazyRequireGetter(this, "DeveloperToolbar", "devtools/client/shared/developer-toolbar", true);
+loader.lazyImporter(this, "BrowserToolboxProcess", "resource://devtools/client/framework/ToolboxProcess.jsm");
+loader.lazyImporter(this, "ResponsiveUIManager", "resource://devtools/client/responsivedesign/responsivedesign.jsm");
+loader.lazyImporter(this, "ScratchpadManager", "resource://devtools/client/scratchpad/scratchpad-manager.jsm");
 
 loader.lazyImporter(this, "CustomizableUI", "resource:///modules/CustomizableUI.jsm");
 loader.lazyImporter(this, "CustomizableWidgets", "resource:///modules/CustomizableWidgets.jsm");
 loader.lazyImporter(this, "AppConstants", "resource://gre/modules/AppConstants.jsm");
 loader.lazyImporter(this, "LightweightThemeManager", "resource://gre/modules/LightweightThemeManager.jsm");
 
 const {LocalizationHelper} = require("devtools/shared/l10n");
 const L10N = new LocalizationHelper("devtools/client/locales/toolbox.properties");
@@ -270,16 +273,63 @@ var gDevToolsBrowser = exports.gDevTools
       gDevTools.showToolbox(target, toolId).then(newToolbox => {
         newToolbox.fireCustomKey(toolId);
         gDevTools.emit("select-tool-command", toolId);
       });
     }
   },
 
   /**
+   * Called by devtools/client/devtools-startup.js when a key shortcut is pressed
+   *
+   * @param  {Window} window
+   *         The top level browser window from which the key shortcut is pressed.
+   * @param  {Object} key
+   *         Key object describing the key shortcut being pressed. It comes
+   *         from devtools-startup.js's KeyShortcuts array. The useful fields here
+   *         are:
+   *         - `toolId` used to identify a toolbox's panel like inspector or webconsole,
+   *         - `id` used to identify any other key shortcuts like scratchpad or
+   *         about:debugging
+   */
+  onKeyShortcut(window, key) {
+    // If this is a toolbox's panel key shortcut, delegate to selectToolCommand
+    if (key.toolId) {
+      gDevToolsBrowser.selectToolCommand(window.gBrowser, key.toolId);
+      return;
+    }
+    // Otherwise implement all other key shortcuts individually here
+    switch (key.id) {
+      case "toggleToolbox":
+      case "toggleToolboxF12":
+        gDevToolsBrowser.toggleToolboxCommand(window.gBrowser);
+        break;
+      case "toggleToolbar":
+        window.DeveloperToolbar.focusToggle();
+        break;
+      case "webide":
+        gDevToolsBrowser.openWebIDE();
+        break;
+      case "browserToolbox":
+        BrowserToolboxProcess.init();
+        break;
+      case "browserConsole":
+        let HUDService = require("devtools/client/webconsole/hudservice");
+        HUDService.openBrowserConsoleOrFocus();
+        break;
+      case "responsiveDesignMode":
+        ResponsiveUIManager.toggle(window, window.gBrowser.selectedTab);
+        break;
+      case "scratchpad":
+        ScratchpadManager.openScratchpad();
+        break;
+    }
+  },
+
+  /**
    * Open a tab on "about:debugging", optionally pre-select a given tab.
    */
    // Used by browser-sets.inc, command
   openAboutDebugging(gBrowser, hash) {
     let url = "about:debugging" + (hash ? "#" + hash : "");
     gBrowser.selectedTab = gBrowser.addTab(url);
   },
 
@@ -364,76 +414,16 @@ var gDevToolsBrowser = exports.gDevTools
           });
     } else {
       let msg = L10N.getStr("toolbox.noContentProcessForTab.message");
       Services.prompt.alert(null, "", msg);
     }
   },
 
   /**
-   * Install Developer widget
-   */
-  installDeveloperWidget() {
-    let id = "developer-button";
-    let widget = CustomizableUI.getWidget(id);
-    if (widget && widget.provider == CustomizableUI.PROVIDER_API) {
-      return;
-    }
-    let item = {
-      id: id,
-      type: "view",
-      viewId: "PanelUI-developer",
-      shortcutId: "key_devToolboxMenuItem",
-      tooltiptext: "developer-button.tooltiptext2",
-      defaultArea: AppConstants.MOZ_DEV_EDITION ?
-                     CustomizableUI.AREA_NAVBAR :
-                     CustomizableUI.AREA_PANEL,
-      onViewShowing(event) {
-        // Populate the subview with whatever menuitems are in the developer
-        // menu. We skip menu elements, because the menu panel has no way
-        // of dealing with those right now.
-        let doc = event.target.ownerDocument;
-
-        let menu = doc.getElementById("menuWebDeveloperPopup");
-
-        let itemsToDisplay = [...menu.children];
-        // Hardcode the addition of the "work offline" menuitem at the bottom:
-        itemsToDisplay.push({localName: "menuseparator", getAttribute: () => {}});
-        itemsToDisplay.push(doc.getElementById("goOfflineMenuitem"));
-
-        let developerItems = doc.getElementById("PanelUI-developerItems");
-        // Import private helpers from CustomizableWidgets
-        let { clearSubview, fillSubviewFromMenuItems } =
-          Cu.import("resource:///modules/CustomizableWidgets.jsm", {});
-        clearSubview(developerItems);
-        fillSubviewFromMenuItems(itemsToDisplay, developerItems);
-      },
-      onInit(anchor) {
-        // Since onBeforeCreated already bails out when initialized, we can call
-        // it right away.
-        this.onBeforeCreated(anchor.ownerDocument);
-      },
-      onBeforeCreated(doc) {
-        // Bug 1223127, CUI should make this easier to do.
-        if (doc.getElementById("PanelUI-developerItems")) {
-          return;
-        }
-        let view = doc.createElement("panelview");
-        view.id = "PanelUI-developerItems";
-        let panel = doc.createElement("vbox");
-        panel.setAttribute("class", "panel-subview-body");
-        view.appendChild(panel);
-        doc.getElementById("PanelUI-multiView").appendChild(view);
-      }
-    };
-    CustomizableUI.createWidget(item);
-    CustomizableWidgets.push(item);
-  },
-
-  /**
    * Install WebIDE widget
    */
   // Used by itself
   installWebIDEWidget() {
     if (this.isWebIDEWidgetInstalled()) {
       return;
     }
 
@@ -496,20 +486,16 @@ var gDevToolsBrowser = exports.gDevTools
   _registerBrowserWindow(win) {
     if (gDevToolsBrowser._trackedBrowserWindows.has(win)) {
       return;
     }
     gDevToolsBrowser._trackedBrowserWindows.add(win);
 
     BrowserMenus.addMenus(win.document);
 
-    // Register the Developer widget in the Hamburger menu or navbar
-    // only once menus are registered as it depends on it.
-    gDevToolsBrowser.installDeveloperWidget();
-
     this.updateCommandAvailability(win);
     this.updateDevtoolsThemeAttribute(win);
     this.ensurePrefObserver();
     win.addEventListener("unload", this);
 
     let tabContainer = win.gBrowser.tabContainer;
     tabContainer.addEventListener("TabSelect", this);
     tabContainer.addEventListener("TabOpen", this);
--- a/devtools/client/framework/devtools.js
+++ b/devtools/client/framework/devtools.js
@@ -19,17 +19,16 @@ loader.lazyImporter(this, "ScratchpadMan
 // Dependencies required for addon sdk compatibility layer.
 loader.lazyRequireGetter(this, "DebuggerServer", "devtools/server/main", true);
 loader.lazyRequireGetter(this, "DebuggerClient", "devtools/shared/client/main", true);
 loader.lazyImporter(this, "BrowserToolboxProcess", "resource://devtools/client/framework/ToolboxProcess.jsm");
 
 const {defaultTools: DefaultTools, defaultThemes: DefaultThemes} =
   require("devtools/client/definitions");
 const EventEmitter = require("devtools/shared/event-emitter");
-const {JsonView} = require("devtools/client/jsonview/main");
 const AboutDevTools = require("devtools/client/framework/about-devtools-toolbox");
 const {Task} = require("devtools/shared/task");
 const {getTheme, setTheme, addThemeObserver, removeThemeObserver} =
   require("devtools/client/shared/theme");
 
 const FORBIDDEN_IDS = new Set(["toolbox", ""]);
 const MAX_ORDINAL = 99;
 
@@ -39,19 +38,16 @@ const MAX_ORDINAL = 99;
  */
 function DevTools() {
   this._tools = new Map();     // Map<toolId, tool>
   this._themes = new Map();    // Map<themeId, theme>
   this._toolboxes = new Map(); // Map<target, toolbox>
   // List of toolboxes that are still in process of creation
   this._creatingToolboxes = new Map(); // Map<target, toolbox Promise>
 
-  // JSON Viewer for 'application/json' documents.
-  JsonView.initialize();
-
   AboutDevTools.register();
 
   EventEmitter.decorate(this);
 
   // Listen for changes to the theme pref.
   this._onThemeChanged = this._onThemeChanged.bind(this);
   addThemeObserver(this._onThemeChanged);
 
@@ -639,18 +635,16 @@ DevTools.prototype = {
       }
       AboutDevTools.unregister();
     }
 
     for (let [key, ] of this.getToolDefinitionMap()) {
       this.unregisterTool(key, true);
     }
 
-    JsonView.destroy();
-
     gDevTools.unregisterDefaults();
 
     removeThemeObserver(this._onThemeChanged);
 
     // Do not unregister devtools from the DevToolsShim if the destroy is caused by an
     // application shutdown. For instance SessionStore needs to save the Scratchpad
     // manager state on shutdown.
     if (!shuttingDown) {
--- a/devtools/client/framework/test/browser_toolbox_dynamic_registration.js
+++ b/devtools/client/framework/test/browser_toolbox_dynamic_registration.js
@@ -21,17 +21,16 @@ function testRegister(aToolbox)
   gDevTools.once("tool-registered", toolRegistered);
 
   gDevTools.registerTool({
     id: "test-tool",
     label: "Test Tool",
     inMenu: true,
     isTargetSupported: () => true,
     build: function () {},
-    key: "t"
   });
 }
 
 function toolRegistered(event, toolId)
 {
   is(toolId, "test-tool", "tool-registered event handler sent tool id");
 
   ok(gDevTools.getToolDefinitionMap().has(toolId), "tool added to map");
@@ -40,18 +39,16 @@ function toolRegistered(event, toolId)
   let doc = toolbox.doc;
   let tab = doc.getElementById("toolbox-tab-" + toolId);
   ok(tab, "new tool's tab exists in toolbox UI");
 
   let panel = doc.getElementById("toolbox-panel-" + toolId);
   ok(panel, "new tool's panel exists in toolbox UI");
 
   for (let win of getAllBrowserWindows()) {
-    let key = win.document.getElementById("key_" + toolId);
-    ok(key, "key for new tool added to every browser window");
     let menuitem = win.document.getElementById("menuitem_" + toolId);
     ok(menuitem, "menu item of new tool added to every browser window");
   }
 
   // then unregister it
   testUnregister();
 }
 
@@ -81,18 +78,16 @@ function toolUnregistered(event, toolId)
   let doc = toolbox.doc;
   let tab = doc.getElementById("toolbox-tab-" + toolId);
   ok(!tab, "tool's tab was removed from the toolbox UI");
 
   let panel = doc.getElementById("toolbox-panel-" + toolId);
   ok(!panel, "tool's panel was removed from toolbox UI");
 
   for (let win of getAllBrowserWindows()) {
-    let key = win.document.getElementById("key_" + toolId);
-    ok(!key, "key removed from every browser window");
     let menuitem = win.document.getElementById("menuitem_" + toolId);
     ok(!menuitem, "menu item removed from every browser window");
   }
 
   cleanup();
 }
 
 function cleanup()
--- a/devtools/client/framework/test/browser_toolbox_window_shortcuts.js
+++ b/devtools/client/framework/test/browser_toolbox_window_shortcuts.js
@@ -1,37 +1,42 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
+var Startup = Cc["@mozilla.org/devtools/startup-clh;1"].getService(Ci.nsISupports)
+  .wrappedJSObject;
 var {Toolbox} = require("devtools/client/framework/toolbox");
 
-var toolbox, toolIDs, idIndex, modifiedPrefs = [];
+var toolbox, toolIDs, toolShortcuts = [], idIndex, modifiedPrefs = [];
 
 function test() {
   addTab("about:blank").then(function () {
     toolIDs = [];
     for (let [id, definition] of gDevTools._tools) {
-      if (definition.key) {
-        toolIDs.push(id);
+      let shortcut = Startup.KeyShortcuts.filter(s => s.toolId == id)[0];
+      if (!shortcut) {
+        continue;
+      }
+      toolIDs.push(id);
+      toolShortcuts.push(shortcut);
 
-        // Enable disabled tools
-        let pref = definition.visibilityswitch, prefValue;
-        try {
-          prefValue = Services.prefs.getBoolPref(pref);
-        } catch (e) {
-          continue;
-        }
-        if (!prefValue) {
-          modifiedPrefs.push(pref);
-          Services.prefs.setBoolPref(pref, true);
-        }
+      // Enable disabled tools
+      let pref = definition.visibilityswitch, prefValue;
+      try {
+        prefValue = Services.prefs.getBoolPref(pref);
+      } catch (e) {
+        continue;
+      }
+      if (!prefValue) {
+        modifiedPrefs.push(pref);
+        Services.prefs.setBoolPref(pref, true);
       }
     }
     let target = TargetFactory.forTab(gBrowser.selectedTab);
     idIndex = 0;
     gDevTools.showToolbox(target, toolIDs[0], Toolbox.HostType.WINDOW)
              .then(testShortcuts);
   });
 }
@@ -44,18 +49,19 @@ function testShortcuts(aToolbox, aIndex)
     return;
   }
 
   toolbox = aToolbox;
   info("Toolbox fired a `ready` event");
 
   toolbox.once("select", selectCB);
 
-  let key = gDevTools._tools.get(toolIDs[aIndex]).key;
-  let toolModifiers = gDevTools._tools.get(toolIDs[aIndex]).modifiers;
+  let shortcut = toolShortcuts[aIndex];
+  let key = shortcut.shortcut;
+  let toolModifiers = shortcut.modifiers;
   let modifiers = {
     accelKey: toolModifiers.includes("accel"),
     altKey: toolModifiers.includes("alt"),
     shiftKey: toolModifiers.includes("shift"),
   };
   idIndex = aIndex;
   info("Testing shortcut for tool " + aIndex + ":" + toolIDs[aIndex] +
        " using key " + key);
--- a/devtools/client/framework/toolbox.js
+++ b/devtools/client/framework/toolbox.js
@@ -9,29 +9,31 @@ const SOURCE_MAP_WORKER = "resource://de
 const MAX_ORDINAL = 99;
 const SPLITCONSOLE_ENABLED_PREF = "devtools.toolbox.splitconsoleEnabled";
 const SPLITCONSOLE_HEIGHT_PREF = "devtools.toolbox.splitconsoleHeight";
 const DISABLE_AUTOHIDE_PREF = "ui.popup.disable_autohide";
 const HOST_HISTOGRAM = "DEVTOOLS_TOOLBOX_HOST";
 const SCREENSIZE_HISTOGRAM = "DEVTOOLS_SCREEN_RESOLUTION_ENUMERATED_PER_USER";
 const HTML_NS = "http://www.w3.org/1999/xhtml";
 
-var {Ci, Cu} = require("chrome");
+var {Ci, Cu, Cc} = require("chrome");
 var promise = require("promise");
 var defer = require("devtools/shared/defer");
 var Services = require("Services");
 var {Task} = require("devtools/shared/task");
 var {gDevTools} = require("devtools/client/framework/devtools");
 var EventEmitter = require("devtools/shared/event-emitter");
 var Telemetry = require("devtools/client/shared/telemetry");
 var { attachThread, detachThread } = require("./attach-thread");
 var Menu = require("devtools/client/framework/menu");
 var MenuItem = require("devtools/client/framework/menu-item");
 var { DOMHelpers } = require("resource://devtools/client/shared/DOMHelpers.jsm");
 const { KeyCodes } = require("devtools/client/shared/keycodes");
+var Startup = Cc["@mozilla.org/devtools/startup-clh;1"].getService(Ci.nsISupports)
+  .wrappedJSObject;
 
 const { BrowserLoader } =
   Cu.import("resource://devtools/client/shared/browser-loader.js", {});
 
 const {LocalizationHelper} = require("devtools/shared/l10n");
 const L10N = new LocalizationHelper("devtools/client/locales/toolbox.properties");
 
 loader.lazyRequireGetter(this, "getHighlighterUtils",
@@ -852,34 +854,35 @@ Toolbox.prototype = {
    */
   _addKeysToWindow: function () {
     if (this.hostType != Toolbox.HostType.WINDOW) {
       return;
     }
 
     let doc = this.win.parent.document;
 
-    for (let [id, toolDefinition] of gDevTools.getToolDefinitionMap()) {
-      // Prevent multiple entries for the same tool.
-      if (!toolDefinition.key || doc.getElementById("key_" + id)) {
+    for (let item of Startup.KeyShortcuts) {
+      // KeyShortcuts contain tool-specific and global key shortcuts,
+      // here we only need to copy shortcut specific to each tool.
+      if (!item.toolId) {
         continue;
       }
+      let { toolId, shortcut, modifiers } = item;
 
-      let toolId = id;
       let key = doc.createElement("key");
 
       key.id = "key_" + toolId;
 
-      if (toolDefinition.key.startsWith("VK_")) {
-        key.setAttribute("keycode", toolDefinition.key);
+      if (shortcut.startsWith("VK_")) {
+        key.setAttribute("keycode", shortcut);
       } else {
-        key.setAttribute("key", toolDefinition.key);
+        key.setAttribute("key", shortcut);
       }
 
-      key.setAttribute("modifiers", toolDefinition.modifiers);
+      key.setAttribute("modifiers", modifiers);
       // needed. See bug 371900
       key.setAttribute("oncommand", "void(0);");
       key.addEventListener("command", () => {
         this.selectTool(toolId).then(() => this.fireCustomKey(toolId));
       }, true);
       doc.getElementById("toolbox-keyset").appendChild(key);
     }
 
--- a/devtools/client/inspector/test/browser_inspector_navigation.js
+++ b/devtools/client/inspector/test/browser_inspector_navigation.js
@@ -8,16 +8,23 @@
 // Test that inspector updates when page is navigated.
 
 const TEST_URL_FILE = "browser/devtools/client/inspector/test/" +
   "doc_inspector_breadcrumbs.html";
 
 const TEST_URL_1 = "http://test1.example.org/" + TEST_URL_FILE;
 const TEST_URL_2 = "http://test2.example.org/" + TEST_URL_FILE;
 
+// Bug 1340592: "srcset" attribute causes bfcache events (pageshow/pagehide)
+// with buggy "persisted" values.
+const TEST_URL_3 = "data:text/html;charset=utf-8," +
+  encodeURIComponent("<img src=\"foo.png\" srcset=\"foo.png 1.5x\" />");
+const TEST_URL_4 = "data:text/html;charset=utf-8," +
+  encodeURIComponent("<h1>bar</h1>");
+
 add_task(function* () {
   let { inspector, testActor } = yield openInspectorForURL(TEST_URL_1);
 
   yield selectNode("#i1", inspector);
 
   info("Navigating to a different page.");
   yield navigateTo(inspector, TEST_URL_2);
 
@@ -36,8 +43,37 @@ add_task(function* () {
   info("Check that the inspector updates");
   yield onUpdated;
 
   ok(true, "Old page loaded");
   is((yield testActor.eval("location.href;")), TEST_URL_1, "URL is correct.");
 
   yield selectNode("#i1", inspector);
 });
+
+add_task(function* () {
+  let { inspector, testActor } = yield openInspectorForURL(TEST_URL_3);
+
+  yield selectNode("img", inspector);
+
+  info("Navigating to a different page.");
+  yield navigateTo(inspector, TEST_URL_4);
+
+  ok(true, "New page loaded");
+  yield selectNode("#h1", inspector);
+
+  let markuploaded = inspector.once("markuploaded");
+  let onUpdated = inspector.once("inspector-updated");
+
+  info("Going back in history");
+  yield testActor.eval("history.go(-1)");
+
+  info("Waiting for markup view to load after going back in history.");
+  yield markuploaded;
+
+  info("Check that the inspector updates");
+  yield onUpdated;
+
+  ok(true, "Old page loaded");
+  is((yield testActor.eval("location.href;")), TEST_URL_3, "URL is correct.");
+
+  yield selectNode("img", inspector);
+});
deleted file mode 100644
--- a/devtools/client/jsonview/main.js
+++ /dev/null
@@ -1,71 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-