Merge fx-team to central, a=merge
authorWes Kocher <wkocher@mozilla.com>
Tue, 20 Oct 2015 14:53:07 -0700
changeset 303729 1b6d33aad42529d204a4edd8af2d8f8628da0016
parent 303705 0416fbbd3a63280eab7738c1246acd4b0104b619 (current diff)
parent 303728 647db461d78d11af43eaf177c438a6bacce8243b (diff)
child 303764 f397034950304b845175f8dab8fccbdd0e8bf995
push id1001
push userraliiev@mozilla.com
push dateMon, 18 Jan 2016 19:06:03 +0000
treeherdermozilla-release@8b89261f3ac4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone44.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 fx-team to central, a=merge
mobile/android/base/resources/layout/tabs_panel_back_button.xml
mobile/android/gradle/branding/AndroidManifest.xml
mobile/android/gradle/branding/build.gradle
mobile/android/gradle/preprocessed_code/AndroidManifest.xml
mobile/android/gradle/preprocessed_code/build.gradle
mobile/android/gradle/preprocessed_resources/AndroidManifest.xml
mobile/android/gradle/preprocessed_resources/build.gradle
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -671,17 +671,17 @@
              overflowable="true"
              overflowbutton="nav-bar-overflow-button"
              overflowtarget="widget-overflow-list"
              overflowpanel="widget-overflow"
              context="toolbar-context-menu">
 
       <hbox id="nav-bar-customization-target" flex="1">
         <toolbaritem id="urlbar-container" flex="400" persist="width"
-                     title="&locationItem.title;" removable="false"
+                     removable="false"
                      class="chromeclass-location" overflows="false">
           <toolbarbutton id="back-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
                          label="&backCmd.label;"
                          command="Browser:BackOrBackDuplicate"
                          onclick="checkForMiddleClick(this, event);"
                          tooltip="back-button-tooltip"
                          context="backForwardMenu"/>
           <hbox id="urlbar-wrapper" flex="1">
@@ -794,26 +794,23 @@
               </hbox>
               <hbox id="userContext-icons">
                 <label id="userContext-label"/>
                 <image id="userContext-indicator"/>
               </hbox>
               <toolbarbutton id="urlbar-go-button"
                              class="chromeclass-toolbar-additional"
                              onclick="gURLBar.handleCommand(event);"
-                             aria-label="&goEndCap.tooltip;"
                              tooltiptext="&goEndCap.tooltip;"/>
               <toolbarbutton id="urlbar-reload-button"
                              class="chromeclass-toolbar-additional"
                              command="Browser:ReloadOrDuplicate"
                              onclick="checkForMiddleClick(this, event);"
-                             aria-label="&reloadButton.tooltip;"
                              tooltiptext="&reloadButton.tooltip;"/>
               <toolbarbutton id="urlbar-stop-button"
-                             aria-label="&stopButton.tooltip;"
                              class="chromeclass-toolbar-additional"
                              command="Browser:Stop"
                              tooltiptext="&stopButton.tooltip;"/>
             </textbox>
           </hbox>
         </toolbaritem>
 
         <toolbaritem id="search-container" title="&searchItem.title;"
--- a/browser/base/content/test/alerts/browser.ini
+++ b/browser/base/content/test/alerts/browser.ini
@@ -1,7 +1,9 @@
 [DEFAULT]
 support-files =
   file_dom_notifications.html
 
 [browser_notification_open_settings.js]
+[browser_notification_remove_permission.js]
+skip-if = e10s
 [browser_notification_tab_switching.js]
 skip-if = buildapp == 'mulet' || e10s # Bug 1100662 - content access causing uncaught exception - Error: cannot ipc non-cpow object at chrome://mochitests/content/browser/browser/base/content/test/general/browser_notification_tab_switching.js:32 (or in RemoteAddonsChild.jsm)
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/alerts/browser_notification_remove_permission.js
@@ -0,0 +1,79 @@
+"use strict";
+
+var tab;
+var notification;
+var notificationURL = "http://example.org/browser/browser/base/content/test/alerts/file_dom_notifications.html";
+var alertWindowClosed = false;
+var permRemoved = false;
+
+function test () {
+  waitForExplicitFinish();
+
+  let pm = Services.perms;
+  registerCleanupFunction(function() {
+    pm.remove(makeURI(notificationURL), "desktop-notification");
+    gBrowser.removeTab(tab);
+    window.restore();
+  });
+
+  pm.add(makeURI(notificationURL), "desktop-notification", pm.ALLOW_ACTION);
+
+  tab = gBrowser.addTab(notificationURL);
+  gBrowser.selectedTab = tab;
+  tab.linkedBrowser.addEventListener("load", onLoad, true);
+}
+
+function onLoad() {
+  tab.linkedBrowser.removeEventListener("load", onLoad, true);
+  let win = tab.linkedBrowser.contentWindow.wrappedJSObject;
+  notification = win.showNotification2();
+  notification.addEventListener("show", onAlertShowing);
+}
+
+function onAlertShowing() {
+  info("Notification alert showing");
+  notification.removeEventListener("show", onAlertShowing);
+
+  let alertWindow = Services.wm.getMostRecentWindow("alert:alert");
+  if (!alertWindow) {
+    ok(true, "Notifications don't use XUL windows on all platforms.");
+    notification.close();
+    finish();
+    return;
+  }
+  ok(Services.perms.testExactPermission(makeURI(notificationURL), "desktop-notification"),
+     "Permission should exist prior to removal");
+  let disableForOriginMenuItem = alertWindow.document.getElementById("disableForOriginMenuItem");
+  is(disableForOriginMenuItem.localName, "menuitem", "menuitem found");
+  Services.obs.addObserver(permObserver, "perm-changed", false);
+  alertWindow.addEventListener("beforeunload", onAlertClosing);
+  disableForOriginMenuItem.click();
+  info("Clicked on disable-for-origin menuitem")
+}
+
+function permObserver(subject, topic, data) {
+  if (topic != "perm-changed") {
+    return;
+  }
+
+  let permission = subject.QueryInterface(Ci.nsIPermission);
+  is(permission.type, "desktop-notification", "desktop-notification permission changed");
+  is(data, "deleted", "desktop-notification permission deleted");
+
+  Services.obs.removeObserver(permObserver, "perm-changed");
+  permRemoved = true;
+  if (alertWindowClosed) {
+    finish();
+  }
+}
+
+function onAlertClosing(event) {
+  event.target.removeEventListener("beforeunload", onAlertClosing);
+
+  alertWindowClosed = true;
+  if (permRemoved) {
+    finish();
+  }
+}
+
+
--- a/browser/base/content/test/alerts/browser_notification_tab_switching.js
+++ b/browser/base/content/test/alerts/browser_notification_tab_switching.js
@@ -55,17 +55,17 @@ function onLoad() {
 }
 
 function onAlertShowing() {
   info("Notification alert showing");
   notification.removeEventListener("show", onAlertShowing);
 
   let alertWindow = Services.wm.getMostRecentWindow("alert:alert");
   if (!alertWindow) {
-    todo(false, "Notifications don't use XUL windows on all platforms.");
+    ok(true, "Notifications don't use XUL windows on all platforms.");
     notification.close();
     newWindowOpenedFromTab.close();
     finish();
     return;
   }
   gBrowser.tabContainer.addEventListener("TabSelect", onTabSelect);
   EventUtils.synthesizeMouseAtCenter(alertWindow.document.getElementById("alertTitleLabel"), {}, alertWindow);
   info("Clicked on notification");
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -213,18 +213,16 @@ These should match what Safari and other
 <!ENTITY urlbar.pointerLockNotificationAnchor.label     "Change whether the site can hide the pointer">
 <!ENTITY urlbar.servicesNotificationAnchor.label        "View the service install message">
 <!ENTITY urlbar.translateNotificationAnchor.label       "Translate this page">
 <!ENTITY urlbar.translatedNotificationAnchor.label      "Manage page translation">
 <!ENTITY urlbar.emeNotificationAnchor.label             "Manage use of DRM software">
 
 <!ENTITY urlbar.toggleAutocomplete.label                "Toggle the autocomplete popup">
 
-
-<!ENTITY locationItem.title           "Location">
 <!ENTITY searchItem.title             "Search">
 
 <!-- Toolbar items --> 
 <!ENTITY homeButton.label             "Home">
 
 <!ENTITY tabGroupsButton.label        "Tab Groups">
 
 <!ENTITY bookmarksButton.label          "Bookmarks">
--- a/browser/locales/en-US/chrome/browser/devtools/inspector.dtd
+++ b/browser/locales/en-US/chrome/browser/devtools/inspector.dtd
@@ -120,8 +120,13 @@
      shown in the inspector contextual-menu for recursively collapsing
      mark-up elements -->
 <!ENTITY inspectorCollapseNode.label       "Collapse">
 
 <!-- LOCALIZATION NOTE (inspectorScreenshotNode.label): This is the label
      shown in the inspector contextual-menu for the item that lets users take
      a screenshot of the currently selected node. -->
 <!ENTITY inspectorScreenshotNode.label       "Screenshot Node">
+
+<!-- LOCALIZATION NOTE (inspectorDuplicateNode.label): This is the label
+     shown in the inspector contextual-menu for the item that lets users
+     duplicate the currently selected node. -->
+<!ENTITY inspectorDuplicateNode.label       "Duplicate Node">
--- a/browser/themes/linux/browser.css
+++ b/browser/themes/linux/browser.css
@@ -888,17 +888,17 @@ toolbar .toolbarbutton-1:-moz-any(@prima
   -moz-margin-start: 0;
 }
 
 .urlbar-history-dropmarker {
   -moz-appearance: toolbarbutton-dropdown;
   transition: opacity 0.15s ease;
 }
 
-#navigator-toolbox:not(:hover) .urlbar-history-dropmarker {
+#navigator-toolbox:not(:hover) #urlbar:not([focused]) > .urlbar-textbox-container > .urlbar-history-dropmarker {
   opacity: 0;
 }
 
 #urlbar-container {
   -moz-box-align: center;
 }
 
 @conditionalForwardWithUrlbar@ > #urlbar {
--- a/browser/themes/linux/linuxShared.inc
+++ b/browser/themes/linux/linuxShared.inc
@@ -1,10 +1,10 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 %filter substitution
 
-%define toolbarHighlight rgba(255,255,255,.3)
+%define toolbarHighlight rgba(255,255,255,.4)
 %define fgTabTexture linear-gradient(transparent 2px, @toolbarHighlight@ 2px, @toolbarHighlight@)
 %define fgTabTextureLWT @fgTabTexture@
 %define fgTabBackgroundColor -moz-dialog
--- a/browser/themes/osx/browser.css
+++ b/browser/themes/osx/browser.css
@@ -1692,17 +1692,17 @@ toolbar .toolbarbutton-1 > .toolbarbutto
 
 .urlbar-history-dropmarker {
   padding: 0 3px;
   list-style-image: var(--urlbar-dropmarker-url);
   -moz-image-region: var(--urlbar-dropmarker-region);
   transition: opacity 0.15s ease;
 }
 
-#navigator-toolbox:not(:hover) .urlbar-history-dropmarker {
+#navigator-toolbox:not(:hover) #urlbar:not([focused]) > .urlbar-textbox-container > .urlbar-history-dropmarker {
   opacity: 0;
 }
 
 .urlbar-history-dropmarker[open="true"],
 .urlbar-history-dropmarker:hover:active {
   -moz-image-region: var(--urlbar-dropmarker-active-region);
 }
 
--- a/browser/themes/windows/browser.css
+++ b/browser/themes/windows/browser.css
@@ -1405,17 +1405,17 @@ html|*.urlbar-input:-moz-lwtheme::-moz-p
   background-color: transparent;
   border: none;
   width: auto;
   list-style-image: var(--urlbar-dropmarker-url);
   -moz-image-region: var(--urlbar-dropmarker-region);
   transition: opacity 0.15s ease;
 }
 
-#navigator-toolbox:not(:hover) .urlbar-history-dropmarker {
+#navigator-toolbox:not(:hover) #urlbar:not([focused]) > .urlbar-textbox-container > .urlbar-history-dropmarker {
   opacity: 0;
 }
 
 .urlbar-history-dropmarker:hover {
   -moz-image-region: var(--urlbar-dropmarker-hover-region);
 }
 
 .urlbar-history-dropmarker:hover:active,
--- a/browser/themes/windows/windowsShared.inc
+++ b/browser/themes/windows/windowsShared.inc
@@ -1,13 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 %filter substitution
 
-%define toolbarHighlight rgba(255,255,255,.3)
+%define toolbarHighlight rgba(255,255,255,.4)
 %define fgTabTexture linear-gradient(transparent 2px, @toolbarHighlight@ 2px, @toolbarHighlight@)
 %define fgTabBackgroundColor -moz-dialog
 %define fgTabTextureLWT @fgTabTexture@
 
 % Aero-only defines
 %define customToolbarColor hsl(210,75%,92%)
--- a/devtools/client/inspector/inspector-panel.js
+++ b/devtools/client/inspector/inspector-panel.js
@@ -649,16 +649,19 @@ InspectorPanel.prototype = {
   /**
    * Disable the delete item if needed. Update the pseudo classes.
    */
   _setupNodeMenu: function() {
     let isSelectionElement = this.selection.isElementNode() &&
                              !this.selection.isPseudoElementNode();
     let isEditableElement = isSelectionElement &&
                             !this.selection.isAnonymousNode();
+    let isDuplicatableElement = isSelectionElement &&
+                                !this.selection.isAnonymousNode() &&
+                                !this.selection.isRoot();
     let isScreenshotable = isSelectionElement &&
                            this.canGetUniqueSelector &&
                            this.selection.nodeFront.isTreeDisplayed;
 
     // Set the pseudo classes
     for (let name of ["hover", "active", "focus"]) {
       let menu = this.panelDoc.getElementById("node-menu-pseudo-" + name);
 
@@ -678,16 +681,17 @@ InspectorPanel.prototype = {
     } else {
       deleteNode.setAttribute("disabled", "true");
     }
 
     // Disable / enable "Copy Unique Selector", "Copy inner HTML",
     // "Copy outer HTML", "Scroll Into View" & "Screenshot Node" as appropriate
     let unique = this.panelDoc.getElementById("node-menu-copyuniqueselector");
     let screenshot = this.panelDoc.getElementById("node-menu-screenshotnode");
+    let duplicateNode = this.panelDoc.getElementById("node-menu-duplicatenode");
     let copyInnerHTML = this.panelDoc.getElementById("node-menu-copyinner");
     let copyOuterHTML = this.panelDoc.getElementById("node-menu-copyouter");
     let scrollIntoView = this.panelDoc.getElementById("node-menu-scrollnodeintoview");
     let expandAll = this.panelDoc.getElementById("node-menu-expand");
     let collapse = this.panelDoc.getElementById("node-menu-collapse");
 
     expandAll.setAttribute("disabled", "true");
     collapse.setAttribute("disabled", "true");
@@ -695,20 +699,30 @@ InspectorPanel.prototype = {
     let markUpContainer = this.markup.importNode(this.selection.nodeFront, false);
     if (this.selection.isNode() && markUpContainer.hasChildren) {
       if (markUpContainer.expanded) {
         collapse.removeAttribute("disabled");
       }
       expandAll.removeAttribute("disabled");
     }
 
+    this._target.actorHasMethod("domwalker", "duplicateNode").then(value => {
+      duplicateNode.hidden = !value;
+    });
     this._target.actorHasMethod("domnode", "scrollIntoView").then(value => {
       scrollIntoView.hidden = !value;
     });
 
+    if (isDuplicatableElement) {
+      duplicateNode.removeAttribute("disabled");
+    }
+    else {
+      duplicateNode.setAttribute("disabled", "true");
+    }
+
     if (isSelectionElement) {
       unique.removeAttribute("disabled");
       copyInnerHTML.removeAttribute("disabled");
       copyOuterHTML.removeAttribute("disabled");
       scrollIntoView.removeAttribute("disabled");
     } else {
       unique.setAttribute("disabled", "true");
       copyInnerHTML.setAttribute("disabled", "true");
@@ -1173,16 +1187,30 @@ InspectorPanel.prototype = {
     if (!this.selection.isNode()) {
       return;
     }
 
     this.selection.nodeFront.scrollIntoView();
   },
 
   /**
+   * Duplicate the selected node
+   */
+  duplicateNode: function() {
+    let selection = this.selection;
+    if (!selection.isElementNode() ||
+        selection.isRoot() ||
+        selection.isAnonymousNode() ||
+        selection.isPseudoElementNode()) {
+      return;
+    }
+    this.walker.duplicateNode(selection.nodeFront).catch(e => console.error(e));
+  },
+
+  /**
    * Delete the selected node.
    */
   deleteNode: function() {
     if (!this.selection.isNode() ||
          this.selection.isRoot()) {
       return;
     }
 
--- a/devtools/client/inspector/inspector.xul
+++ b/devtools/client/inspector/inspector.xul
@@ -98,16 +98,19 @@
       <menuseparator/>
       <menuitem id="node-menu-scrollnodeintoview"
         label="&inspectorScrollNodeIntoView.label;"
         accesskey="&inspectorScrollNodeIntoView.accesskey;"
         oncommand="inspector.scrollNodeIntoView()"/>
       <menuitem id="node-menu-screenshotnode"
         label="&inspectorScreenshotNode.label;"
         oncommand="inspector.screenshotNode()" />
+      <menuitem id="node-menu-duplicatenode"
+        label="&inspectorDuplicateNode.label;"
+        oncommand="inspector.duplicateNode()"/>
       <menuitem id="node-menu-delete"
         label="&inspectorHTMLDelete.label;"
         accesskey="&inspectorHTMLDelete.accesskey;"
         oncommand="inspector.deleteNode()"/>
       <menuseparator id="node-menu-link-separator"/>
       <menuitem id="node-menu-link-follow"
         oncommand="inspector.onFollowLink()"/>
       <menuitem id="node-menu-link-copy"
--- a/devtools/client/inspector/test/browser_inspector_menu-05-other.js
+++ b/devtools/client/inspector/test/browser_inspector_menu-05-other.js
@@ -1,53 +1,68 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
 http://creativecommons.org/publicdomain/zero/1.0/ */
 "use strict";
 
 // Tests for menuitem functionality that doesn't fit into any specific category
-
 const TEST_URL = TEST_URL_ROOT + "doc_inspector_menu.html";
-
 add_task(function* () {
   let { inspector, toolbox, testActor } = yield openInspectorForURL(TEST_URL);
-
   yield testShowDOMProperties();
+  yield testDuplicateNode();
   yield testDeleteNode();
   yield testDeleteRootNode();
   yield testScrollIntoView();
-
   function* testShowDOMProperties() {
     info("Testing 'Show DOM Properties' menu item.");
     let showDOMPropertiesNode = inspector.panelDoc.getElementById("node-menu-showdomproperties");
     ok(showDOMPropertiesNode, "the popup menu has a show dom properties item");
 
     let consoleOpened = toolbox.once("webconsole-ready");
 
     info("Triggering 'Show DOM Properties' and waiting for inspector open");
     dispatchCommandEvent(showDOMPropertiesNode);
     yield consoleOpened;
 
     let webconsoleUI = toolbox.getPanel("webconsole").hud.ui;
     let messagesAdded = webconsoleUI.once("new-messages");
     yield messagesAdded;
-
     info("Checking if 'inspect($0)' was evaluated");
     ok(webconsoleUI.jsterm.history[0] === 'inspect($0)');
+    yield toolbox.toggleSplitConsole();
+  }
+  function* testDuplicateNode() {
+    info("Testing 'Duplicate Node' menu item for normal elements.");
 
-    yield toolbox.toggleSplitConsole();
+    yield selectNode(".duplicate", inspector);
+    is((yield testActor.getNumberOfElementMatches(".duplicate")), 1,
+       "There should initially be 1 .duplicate node");
+
+    let menuItem = inspector.panelDoc.getElementById("node-menu-duplicatenode");
+    ok(menuItem, "'Duplicate node' menu item should exist");
+
+    info("Triggering 'Duplicate Node' and waiting for inspector to update");
+    let updated = inspector.once("markupmutation");
+    dispatchCommandEvent(menuItem);
+    yield updated;
+
+    is((yield testActor.getNumberOfElementMatches(".duplicate")), 2,
+       "The duplicated node should be in the markup.");
+
+    let container = yield getContainerForSelector(".duplicate + .duplicate",
+                                                   inspector);
+    ok(container, "A MarkupContainer should be created for the new node");
   }
 
   function* testDeleteNode() {
     info("Testing 'Delete Node' menu item for normal elements.");
-
     yield selectNode("#delete", inspector);
     let deleteNode = inspector.panelDoc.getElementById("node-menu-delete");
     ok(deleteNode, "the popup menu has a delete menu item");
-
     let updated = inspector.once("inspector-updated");
 
     info("Triggering 'Delete Node' and waiting for inspector to update");
     dispatchCommandEvent(deleteNode);
     yield updated;
 
     ok(!(yield testActor.hasNode("#delete")), "Node deleted");
   }
--- a/devtools/client/inspector/test/doc_inspector_menu.html
+++ b/devtools/client/inspector/test/doc_inspector_menu.html
@@ -10,16 +10,17 @@
         <h1>Inspector Tree Menu Test</h1>
         <p class="inner">Unset</p>
         <p class="adjacent">
           <span class="ref">3</span>
         </p>
       </div>
       <p data-id="copy">Paragraph for testing copy</p>
       <p id="sensitivity">Paragraph for sensitivity</p>
+      <p class="duplicate">This will be duplicated</p>
       <p id="delete">This has to be deleted</p>
       <img id="copyimage" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAAAAAA6fptVAAAACklEQVQYV2P4DwABAQEAWk1v8QAAAABJRU5ErkJggg==" />
       <div id="hiddenElement" style="display: none;">
         <p id="nestedHiddenElement">Visible element nested inside a non-visible element</p>
       </div>
       <p id="console-var">Paragraph for testing console variables</p>
       <p id="console-var-multi">Paragraph for testing multiple console variables</p>
     </div>
--- a/devtools/client/jar.mn
+++ b/devtools/client/jar.mn
@@ -219,24 +219,24 @@ devtools.jar:
     skin/themes/images/editor-debug-location@2x.png (themes/images/editor-debug-location@2x.png)
 *   skin/themes/webconsole.css (themes/webconsole.css)
     skin/themes/images/webconsole.svg (themes/images/webconsole.svg)
     skin/themes/images/breadcrumbs-divider@2x.png (themes/images/breadcrumbs-divider@2x.png)
     skin/themes/images/breadcrumbs-scrollbutton.png (themes/images/breadcrumbs-scrollbutton.png)
     skin/themes/images/breadcrumbs-scrollbutton@2x.png (themes/images/breadcrumbs-scrollbutton@2x.png)
     skin/themes/animationinspector.css (themes/animationinspector.css)
     skin/themes/eyedropper.css (themes/eyedropper.css)
-*   skin/themes/canvasdebugger.css (themes/canvasdebugger.css)
+    skin/themes/canvasdebugger.css (themes/canvasdebugger.css)
     skin/themes/debugger.css (themes/debugger.css)
 *   skin/themes/netmonitor.css (themes/netmonitor.css)
     skin/themes/performance.css (themes/performance.css)
     skin/themes/memory.css (themes/memory.css)
     skin/themes/promisedebugger.css (themes/promisedebugger.css)
     skin/themes/images/timeline-filter.svg (themes/images/timeline-filter.svg)
-*   skin/themes/scratchpad.css (themes/scratchpad.css)
+    skin/themes/scratchpad.css (themes/scratchpad.css)
     skin/themes/shadereditor.css (themes/shadereditor.css)
     skin/themes/storage.css (themes/storage.css)
 *   skin/themes/splitview.css (themes/splitview.css)
     skin/themes/styleeditor.css (themes/styleeditor.css)
     skin/themes/webaudioeditor.css (themes/webaudioeditor.css)
     skin/themes/images/magnifying-glass.png (themes/images/magnifying-glass.png)
     skin/themes/images/magnifying-glass@2x.png (themes/images/magnifying-glass@2x.png)
     skin/themes/images/magnifying-glass-light.png (themes/images/magnifying-glass-light.png)
--- a/devtools/client/shared/test/test-actor.js
+++ b/devtools/client/shared/test/test-actor.js
@@ -77,16 +77,31 @@ var TestActor = exports.TestActor = prot
       selector = selector.shift();
     }
     let node = document.querySelector(selector);
     if (!node) {
       throw new Error("Unable to find element with selector \"" + selector + "\"");
     }
     return node;
   },
+  /**
+   * Helper to get the number of elements matching a selector
+   * @param {string} CSS selector.
+   */
+  getNumberOfElementMatches: protocol.method(function (selector,
+                                                       root=this.content.document) {
+    return root.querySelectorAll(selector).length;
+  }, {
+    request: {
+      selector: Arg(0, "string"),
+    },
+    response: {
+      value: RetVal("number")
+    }
+  }),
 
   /**
    * Get a value for a given attribute name, on one of the elements of the box
    * model highlighter, given its ID.
    * @param {Object} msg The msg.data part expects the following properties
    * - {String} nodeID The full ID of the element to get the attribute for
    * - {String} name The name of the attribute to get
    * - {String} actorID The highlighter actor ID
--- a/devtools/client/themes/canvasdebugger.css
+++ b/devtools/client/themes/canvasdebugger.css
@@ -1,20 +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/. */
 
-%filter substitution
-%define darkCheckerboardBackground #000
-%define lightCheckerboardBackground #fff
-%define checkerboardCell rgba(128,128,128,0.2)
-%define checkerboardPattern linear-gradient(45deg, @checkerboardCell@ 25%, transparent 25%, transparent 75%, @checkerboardCell@ 75%, @checkerboardCell@), linear-gradient(45deg, @checkerboardCell@ 25%, transparent 25%, transparent 75%, @checkerboardCell@ 75%, @checkerboardCell@)
-%define gutterWidth 3em
-%define gutterPaddingStart 22px
-
+:root {
+  --gutter-width: 3em;
+  --gutter-padding-start: 22px;
+  --checkerboard-pattern: linear-gradient(45deg, rgba(128,128,128,0.2) 25%, transparent 25%, transparent 75%, rgba(128,128,128,0.2) 75%, rgba(128,128,128,0.2)),
+                          linear-gradient(45deg, rgba(128,128,128,0.2) 25%, transparent 25%, transparent 75%, rgba(128,128,128,0.2) 75%, rgba(128,128,128,0.2));
+}
 /* Reload and waiting notices */
 
 .notice-container {
   margin-top: -50vh;
   background-color: var(--theme-toolbar-background);
   color: var(--theme-body-color-alt);
 }
 
@@ -30,62 +28,45 @@
 }
 
 #waiting-notice {
   font-size: 110%;
 }
 
 /* Snapshots pane */
 
-#snapshots-pane > tabs {
-  -moz-border-end: 1px solid;
-}
-
+#snapshots-pane > tabs,
 #snapshots-pane .devtools-toolbar {
-  -moz-border-end: 1px solid;
-}
-
-.theme-dark #snapshots-pane > tabs,
-.theme-dark #snapshots-pane .devtools-toolbar {
-  -moz-border-end-color: black; /* Match the splitter color. */
-}
-
-.theme-light #snapshots-pane > tabs,
-.theme-light #snapshots-pane .devtools-toolbar {
-  -moz-border-end-color: #aaa; /* Match the splitter color. */
+  -moz-border-end: 1px solid var(--theme-splitter-color);
 }
 
 #record-snapshot {
   list-style-image: url("chrome://devtools/skin/themes/images/profiler-stopwatch.svg");
 }
 
 #record-snapshot[checked] {
   list-style-image: url("chrome://devtools/skin/themes/images/profiler-stopwatch-checked.svg");
 }
 
 /* Snapshots items */
 
 .snapshot-item-thumbnail {
   image-rendering: -moz-crisp-edges;
-  background-image: @checkerboardPattern@;
+  background-image: var(--checkerboard-pattern);
   background-size: 12px 12px, 12px 12px;
   background-position: 0px 0px, 6px 6px;
   background-repeat: repeat, repeat;
 }
 
 .snapshot-item-thumbnail[flipped=true] {
   transform: scaleY(-1);
 }
 
-.theme-dark .snapshot-item-thumbnail {
-  background-color: @darkCheckerboardBackground@;
-}
-
-.theme-light .snapshot-item-thumbnail {
-  background-color: @lightCheckerboardBackground@;
+.snapshot-item-thumbnail {
+  background-color: var(--theme-body-background);
 }
 
 .snapshot-item-details {
   -moz-padding-start: 6px;
 }
 
 .snapshot-item-calls {
   padding-top: 4px;
@@ -229,19 +210,19 @@
   background-color: rgba(223,128,255,0.15);
 }
 
 .theme-light .call-item-view[interesting-call] {
   background-color: rgba(184,46,229,0.1);
 }
 
 .call-item-gutter {
-  width: calc(@gutterWidth@ + @gutterPaddingStart@);
-  -moz-padding-start: @gutterPaddingStart@;
-  -moz-padding-end: 4px;
+  width: calc(var(--gutter-width) + var(--gutter-padding-start));
+  padding-inline-start: var(--gutter-padding-start);
+  padding-inline-end: 4px;
   padding-top: 2px;
   padding-bottom: 2px;
   -moz-border-end: 1px solid;
   -moz-margin-end: 6px;
 }
 
 .selected .call-item-gutter {
   background-image: url("images/editor-debug-location.png");
@@ -295,17 +276,17 @@
   border-color: #111;
 }
 
 .theme-light .call-item-location {
   border-color: #eee;
 }
 
 .call-item-stack {
-  -moz-padding-start: calc(@gutterWidth@ + @gutterPaddingStart@);
+  -moz-padding-start: calc(var(--gutter-width) + var(--gutter-padding-start));
   padding-bottom: 10px;
 }
 
 .theme-dark .call-item-stack {
   background: rgba(0,0,0,0.9);
 }
 
 .theme-light .call-item-stack {
@@ -340,30 +321,23 @@
 #calls-list .selected .call-item-contents > label:not(.call-item-gutter) {
   /* Text inside a selected item should not be custom colored. */
   color: inherit !important;
 }
 
 /* Rendering preview */
 
 #screenshot-container {
-  background-image: @checkerboardPattern@;
+  background-color: var(--theme-body-background);
+  background-image: var(--checkerboard-pattern);
   background-size: 30px 30px, 30px 30px;
   background-position: 0px 0px, 15px 15px;
   background-repeat: repeat, repeat;
 }
 
-.theme-dark #screenshot-container {
-  background-color: @darkCheckerboardBackground@;
-}
-
-.theme-light #screenshot-container {
-  background-color: @lightCheckerboardBackground@;
-}
-
 @media (min-width: 701px) {
   #screenshot-container {
     width: 30vw;
     max-width: 50vw;
     min-width: 100px;
   }
 }
 
@@ -398,57 +372,46 @@
 
 .theme-light #screenshot-dimensions {
   background-color: rgba(255,255,255,0.8);
 }
 
 /* Snapshot filmstrip */
 
 #snapshot-filmstrip {
+  border-top: 1px solid var(--theme-splitter-color);
   overflow: hidden;
 }
 
 .theme-dark #snapshot-filmstrip {
-  border-top: 1px solid #000;
   color: var(--theme-selection-color);
 }
 
 .theme-light #snapshot-filmstrip {
-  border-top: 1px solid #aaa;
   color: var(--theme-body-color-alt);
 }
 
 .filmstrip-thumbnail {
   image-rendering: -moz-crisp-edges;
-  background-image: @checkerboardPattern@;
+  background-color: var(--theme-body-background);
+  background-image: var(--checkerboard-pattern);
   background-size: 12px 12px, 12px 12px;
   background-position: 0px -1px, 6px 5px;
   background-repeat: repeat, repeat;
   background-origin: content-box;
   cursor: pointer;
   padding-top: 1px;
   padding-bottom: 1px;
+  border-inline-end: 1px solid var(--theme-splitter-color);
   transition: opacity 0.1s ease-in-out;
 }
 
 .filmstrip-thumbnail[flipped=true] {
   transform: scaleY(-1);
 }
 
-.theme-dark .filmstrip-thumbnail {
-  background-color: @darkCheckerboardBackground@;
-}
-
-.theme-light .filmstrip-thumbnail {
-  background-color: @lightCheckerboardBackground@;
-}
-
-.filmstrip-thumbnail {
-  -moz-border-end: 1px solid var(--theme-splitter-color)
-}
-
 #snapshot-filmstrip > .filmstrip-thumbnail:hover,
 #snapshot-filmstrip:not(:hover) > .filmstrip-thumbnail[highlighted] {
   border: 1px solid var(--theme-highlight-blue);
   margin: 0 0 0 -1px;
   padding: 0;
   opacity: 0.66;
 }
--- a/devtools/client/themes/scratchpad.css
+++ b/devtools/client/themes/scratchpad.css
@@ -1,13 +1,11 @@
-%if 0
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-%endif
 
 #scratchpad-sidebar > tabs {
   height: 0;
   border: none;
 }
 
 #sp-toolbar {
   border: none;
--- a/devtools/client/themes/styleeditor.css
+++ b/devtools/client/themes/styleeditor.css
@@ -62,24 +62,17 @@
 
 .splitview-nav.empty > p {
   padding: 0 10px;
 }
 
 .stylesheet-sidebar {
   max-width: 400px;
   min-width: 100px;
-}
-
-.theme-light .stylesheet-sidebar {
-  border-color: #aaa; /* Splitters */
-}
-
-.theme-dark .stylesheet-sidebar {
-  border-color: #000;  /* Splitters */
+  border-color: var(--theme-splitter-color);
 }
 
 .theme-light .media-rule-label {
   border-bottom-color: #cddae5; /* Grey */
 }
 
 .theme-dark .media-rule-label {
   border-bottom-color: #303b47; /* Grey */
--- a/devtools/client/themes/toolbars.inc.css
+++ b/devtools/client/themes/toolbars.inc.css
@@ -558,57 +558,31 @@
 }
 
 .devtools-sidebar-tabs tabs > tab[selected],
 .devtools-sidebar-tabs tabs > tab[selected] + tab {
   border-image: linear-gradient(var(--theme-splitter-color), var(--theme-splitter-color)) 1 1;
 }
 
 .devtools-sidebar-tabs tabs > tab:first-child {
-  -moz-border-start-width: 0;
-}
-
-.theme-dark .devtools-sidebar-tabs tabs > tab:hover {
-  background: hsla(206,37%,4%,.2);
+  border-inline-start-width: 0;
 }
 
-.theme-dark .devtools-sidebar-tabs tabs > tab:hover:active {
-  background: hsla(206,37%,4%,.4);
-}
-
-.theme-dark .devtools-sidebar-tabs tabs > tab[selected] + tab:hover {
-  background: hsla(206,37%,4%,.2);
-}
-
-.theme-dark .devtools-sidebar-tabs tabs > tab[selected] + tab:hover:active {
-  background: hsla(206,37%,4%,.4);
+.devtools-sidebar-tabs tabs > tab:hover {
+  background: rgba(0, 0, 0, 0.12);
 }
 
-.theme-dark .devtools-sidebar-tabs tabs > tab[selected],
-.theme-dark .devtools-sidebar-tabs tabs > tab[selected]:hover:active {
-  color: var(--theme-selection-color);
-  background: #1d4f73;
-}
-
-.theme-light .devtools-sidebar-tabs tabs > tab:hover {
-  background: #ddd;
+.devtools-sidebar-tabs tabs > tab:hover:active {
+  background: rgba(0, 0, 0, 0.2);
 }
 
-.theme-light .devtools-sidebar-tabs tabs > tab:hover:active {
-  background: #ddd;
-}
-
-.theme-light .devtools-sidebar-tabs tabs > tab[selected] + tab:hover {
-  background: #ddd;
-}
-
-.theme-light .devtools-sidebar-tabs tabs > tab[selected],
-.theme-light .devtools-sidebar-tabs tabs > tab[selected]:hover:active {
+.devtools-sidebar-tabs tabs > tab[selected],
+.devtools-sidebar-tabs tabs > tab[selected]:hover:active {
   color: var(--theme-selection-color);
-  background: #4c9ed9;
+  background: var(--theme-selection-background);
 }
 
 /* Toolbox - moved from toolbox.css.
  * Rules that apply to the global toolbox like command buttons,
  * devtools tabs, docking buttons, etc. */
 
 #toolbox-controls > toolbarbutton,
 #toolbox-dock-buttons > toolbarbutton {
--- a/devtools/client/themes/webaudioeditor.css
+++ b/devtools/client/themes/webaudioeditor.css
@@ -25,49 +25,43 @@ svg {
 
 /* Edges in graph */
 .edgePath path {
   stroke-width: 1px;
   fill: none;
 }
 
 .theme-dark .edgePath path {
-  stroke: #b6babf; /* Grey foreground text */
+  stroke: var(--theme-body-color-alt);
 }
 .theme-light .edgePath path {
-  stroke: #aaaaaa; /* Splitters */
+  stroke: var(--theme-splitter-color);
 }
 
 /* AudioParam connection edges */
 g.edgePath.param-connection {
   stroke-dasharray: 5,5;
 }
 
 .theme-dark .edgePath.param-connection path {
-  stroke: #b6babf; /* Grey foreground text */
+  stroke: var(--theme-body-color-alt);
 }
 .theme-light .edgePath.param-connection path {
-  stroke: #aaaaaa; /* Splitters */
+  stroke: var(--theme-splitter-color);
 }
 
 /* Labels in AudioParam connection should have background that match
  * the main background so there's whitespace around the label, on top of the
  * dotted lines. */
-.theme-dark g.edgeLabel rect {
-  fill: #14171a;
-}
-.theme-light g.edgeLabel rect {
-  fill: #fcfcfc; /* Background - Editor */
+g.edgeLabel rect {
+  fill: var(--theme-body-background);
 }
-.theme-dark g.edgeLabel tspan {
+g.edgeLabel tspan {
   fill: var(--theme-body-color-alt);
 }
-.theme-light g.edgeLabel tspan {
-  fill: #585959; /* Grey foreground text */
-}
 
 /* Audio Nodes */
 .nodes rect {
   stroke-width: 1px;
   cursor: pointer;
 }
 
 .nodes rect {
@@ -214,21 +208,18 @@ text {
   list-style-image: url(images/power.svg);
 }
 
 #audio-node-toolbar toolbarbutton[disabled] {
   opacity: 0.5;
   background-color: transparent;
 }
 
-.theme-dark #audio-node-toolbar toolbarbutton[checked] {
-  background-color: #1d4f73; /* Select Highlight Blue */
-}
-.theme-light #audio-node-toolbar toolbarbutton[checked] {
-  background-color: #4c9ed9; /* Select Highlight Blue */
+#audio-node-toolbar toolbarbutton[checked] {
+  background-color: var(--theme-selection-background);
 }
 
 /* don't invert checked buttons so we can have white icons on light theme */
 #audio-node-toolbar toolbarbutton[checked] > .toolbarbutton-icon {
   filter: none;
 }
 
 
--- a/devtools/client/themes/webconsole.css
+++ b/devtools/client/themes/webconsole.css
@@ -21,17 +21,17 @@ a {
   padding: 0 7px;
   width: 100%;
   box-sizing: border-box;
 }
 
 .message > .prefix,
 .message > .timestamp {
   flex: none;
-  color: GrayText;
+  color: var(--theme-comment);
   margin: 3px 6px 0 0;
 }
 
 .message > .indent {
   flex: none;
 }
 
 .message > .icon {
@@ -126,21 +126,16 @@ a {
   flex: 1 1 auto;
   vertical-align: middle;
 }
 
 .message-flex-body > .message-location {
   margin-top: 0;
 }
 
-.jsterm-input-container {
-  border-top-width: 1px;
-  border-top-style: solid;
-}
-
 #output-wrapper {
   direction: ltr;
   overflow: auto;
 }
 
 #output-container {
   -moz-user-select: text;
   -moz-box-flex: 1;
@@ -248,21 +243,21 @@ a {
 }
 
 .message[category=network] .status {
   flex: none;
   -moz-margin-start: 6px;
 }
 
 .message[category=network].mixed-content .url {
-  color: #FF0000;
+  color: var(--theme-highlight-red);
 }
 
 .message .learn-more-link {
-  color: -moz-nativehyperlinktext;
+  color: var(--theme-highlight-blue);
   margin: 0 6px;
 }
 
 .message[category=network] .xhr {
   background-color: var(--theme-body-color-alt);
   color: var(--theme-body-background);
   border-radius: 3px;
   font-weight: bold;
@@ -355,28 +350,45 @@ a {
   background-position: -48px -36px;
 }
 
 .message[category=output] > .icon::before {
   background-position: -60px -36px;
 }
 
 /* JSTerm Styles */
+.jsterm-input-container {
+  background-color: var(--theme-tab-toolbar-background);
+  border-top: 1px solid var(--theme-splitter-color);
+}
+
+.theme-light .jsterm-input-container {
+  /* For light theme use a white background for the input - it looks better
+     than off-white */
+  background-color: #fff;
+  border-top-color: #e0e0e0;
+}
+
 .jsterm-input-node,
 .jsterm-complete-node {
   border: none;
   padding: 0 0 0 16px;
   -moz-appearance: none;
   background-color: transparent;
 }
 
+.jsterm-complete-node {
+  color: var(--theme-comment);
+}
+
 .jsterm-input-node {
   background-image: -moz-image-rect(url("chrome://devtools/skin/themes/images/commandline-icon.png"), 0, 32, 16, 16);
   background-repeat: no-repeat;
   background-size: 16px 16px;
+  color: var(--theme-content-color1);
 }
 
 @media (min-resolution: 1.1dppx) {
   .jsterm-input-node {
     background-image: -moz-image-rect(url('chrome://devtools/skin/themes/images/commandline-icon@2x.png'), 0, 64, 32, 32);
   }
 }
 
@@ -393,17 +405,17 @@ a {
   min-height: 200px;
 }
 .inlined-variables-view iframe {
   display: block;
   flex: 1;
   margin-top: 5px;
   margin-bottom: 15px;
   -moz-margin-end: 15px;
-  border: 1px solid rgba(128, 128, 128, .5);
+  border: 1px solid var(--theme-splitter-color);
   border-radius: 3px;
 }
 
 #webconsole-sidebar > tabs {
   height: 0;
   border: none;
 }
 
@@ -437,26 +449,31 @@ a {
   margin-top: 6px;
   margin-bottom: 6px;
   font-size: 0.9em;
 }
 
 .navigation-marker .url {
   -moz-padding-end: 9px;
   text-decoration: none;
+  background: var(--theme-body-background);
+}
+
+.theme-light .navigation-marker .url {
+  background: #fff;
 }
 
 .stacktrace {
   display: none;
   list-style: none;
   padding: 0 1em 0 1.5em;
   margin: 5px 0 0 0;
   max-height: 10em;
   overflow-y: auto;
-  border: 1px solid rgb(200,200,200);
+  border: 1px solid var(--theme-splitter-color);
   border-radius: 3px;
 }
 
 .consoletable {
   margin: 5px 0 0 0;
 }
 
 .theme-light .message[severity=error] .stacktrace {
@@ -509,59 +526,16 @@ a {
 .open-inspector:hover {
   background-position: -32px 0;
 }
 
 .open-inspector:active {
   background-position: -16px 0;
 }
 
-.jsterm-input-container {
-  background-color: var(--theme-tab-toolbar-background);
-  border-color: var(--theme-body-background);
-}
-
-.jsterm-input-node {
-  color: var(--theme-content-color1);
-}
-
-.jsterm-complete-node {
-  color: var(--theme-comment);
-}
-
-.navigation-marker .url {
-  background: var(--theme-body-background);
-}
-
-.theme-dark .inlined-variables-view iframe {
-  border-color: #333;
-}
-
-.theme-dark .stacktrace {
-  border-color: #333;
-}
-
-.theme-light .jsterm-input-container {
-  /* For light theme use a white background for the input - it looks better
-     than off-white */
-  background-color: #fff;
-  border-color: ThreeDShadow;
-}
-.theme-light .navigation-marker .url {
-  background: #fff;
-}
-
-.theme-light .inlined-variables-view iframe {
-  border-color: #ccc;
-}
-
-.theme-light .stacktrace {
-  border-color: #ccc;
-}
-
 @media (max-width: 500px) {
   .message > .timestamp {
     display: none;
   }
   .hud-console-filter-toolbar .webconsole-filter-button .toolbarbutton-text {
     display: none;
   }
   .hud-console-filter-toolbar .webconsole-filter-button {
--- a/devtools/server/actors/inspector.js
+++ b/devtools/server/actors/inspector.js
@@ -2588,16 +2588,31 @@ var WalkerActor = protocol.ActorClass({
       node: Arg(0, "domnode"),
       position: Arg(1, "string"),
       value: Arg(2, "string")
     },
     response: RetVal("disconnectedNodeArray")
   }),
 
   /**
+   * Duplicate a specified node
+   *
+   * @param {NodeActor} node The node to duplicate.
+   */
+  duplicateNode: method(function({rawNode}) {
+    let clonedNode = rawNode.cloneNode(true);
+    rawNode.parentNode.insertBefore(clonedNode, rawNode.nextSibling);
+  }, {
+    request: {
+      node: Arg(0, "domnode")
+    },
+    response: {}
+  }),
+
+  /**
    * Test whether a node is a document or a document element.
    *
    * @param {NodeActor} node The node to remove.
    * @return {boolean} True if the node is a document or a document element.
    */
   isDocumentOrDocumentElementNode: function(node) {
       return ((node.rawNode.ownerDocument &&
         node.rawNode.ownerDocument.documentElement === this.rawNode) ||
--- a/devtools/server/tests/mochitest/chrome.ini
+++ b/devtools/server/tests/mochitest/chrome.ini
@@ -52,16 +52,17 @@ skip-if = buildapp == 'mulet'
 [test_framerate_06.html]
 skip-if = buildapp == 'mulet'
 [test_getProcess.html]
 skip-if = buildapp == 'mulet'
 [test_inspector-anonymous.html]
 [test_inspector-changeattrs.html]
 [test_inspector-changevalue.html]
 [test_inspector-dead-nodes.html]
+[test_inspector-duplicate-node.html]
 [test_inspector_getImageData.html]
 skip-if = buildapp == 'mulet'
 [test_inspector_getImageDataFromURL.html]
 skip-if = buildapp == 'mulet'
 [test_inspector_getImageData-wait-for-load.html]
 skip-if = buildapp == 'mulet'
 [test_inspector_getNodeFromActor.html]
 [test_inspector-hide.html]
--- a/devtools/server/tests/mochitest/inspector-traversal-data.html
+++ b/devtools/server/tests/mochitest/inspector-traversal-data.html
@@ -75,17 +75,16 @@
   <div id="longlist-sibling">
     <div id="longlist-sibling-firstchild"></div>
   </div>
   <p id="edit-html"></p>
 
   <select multiple><option>one</option><option>two</option></select>
   <div id="pseudo"><span>middle</span></div>
   <div id="pseudo-empty"></div>
-
   <div id="shadow">light dom</div>
-
   <object>
       <div id="1"></div>
   </object>
+  <div class="node-to-duplicate"></div>
   <div id="scroll-into-view" style="margin-top: 1000px;">scroll</div>
 </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/devtools/server/tests/mochitest/test_inspector-duplicate-node.html
@@ -0,0 +1,75 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1208864
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 1208864</title>
+
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
+  <script type="application/javascript;version=1.8" src="inspector-helpers.js"></script>
+  <script type="application/javascript;version=1.8">
+const inspector = require("devtools/server/actors/inspector");
+
+window.onload = function() {
+  SimpleTest.waitForExplicitFinish();
+  runNextTest();
+}
+
+var gInspectee = null;
+var gClient = null;
+var gWalker = null;
+
+function assertOwnership() {
+  assertOwnershipTrees(gWalker);
+}
+
+addTest(function setup() {
+  let url = document.getElementById("inspectorContent").href;
+  attachURL(url, function(err, client, tab, doc) {
+    gInspectee = doc;
+    let {InspectorFront} = require("devtools/server/actors/inspector");
+    let inspector = InspectorFront(client, tab);
+    promiseDone(inspector.getWalker().then(walker => {
+      ok(walker, "getWalker() should return an actor.");
+      gClient = client;
+      gWalker = walker;
+    }).then(runNextTest));
+  });
+});
+
+addTest(Task.async(function* testDuplicateNode() {
+  let className = ".node-to-duplicate";
+  let matches = yield gWalker.querySelectorAll(gWalker.rootNode, className);
+  is(matches.length, 1, "There should initially be one node to duplicate.");
+
+  let nodeFront = yield gWalker.querySelector(gWalker.rootNode, className);
+  yield gWalker.duplicateNode(nodeFront);
+
+  matches = yield gWalker.querySelectorAll(gWalker.rootNode, className);
+  is(matches.length, 2, "The node should now be duplicated.");
+
+  runNextTest();
+}));
+
+addTest(function cleanup() {
+  delete gWalker;
+  delete gInspectee;
+  delete gClient;
+  runNextTest();
+});
+  </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1208864">Mozilla Bug 1208864</a>
+<a id="inspectorContent" target="_blank" href="inspector-traversal-data.html">Test Document</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
--- a/devtools/shared/DevToolsUtils.js
+++ b/devtools/shared/DevToolsUtils.js
@@ -453,16 +453,35 @@ exports.dbg_assert = function dbg_assert
     }
   }
 
   if (!cond) {
     return e;
   }
 };
 
+exports.defineLazyGetter(this, "AppConstants", () => {
+  const scope = {};
+  Cu.import("resource://gre/modules/AppConstants.jsm", scope);
+  return scope.AppConstants;
+});
+
+/**
+ * No operation. The empty function.
+ */
+exports.noop = function () { };
+
+function reallyAssert(condition, message) {
+  if (!condition) {
+    const err = new Error("Assertion failure: " + message);
+    exports.reportException("DevToolsUtils.assert", err);
+    throw err;
+  }
+}
+
 /**
  * DevToolsUtils.assert(condition, message)
  *
  * @param Boolean condition
  * @param String message
  *
  * Assertions are enabled when any of the following are true:
  *   - This is a DEBUG_JS_MODULES build
@@ -472,33 +491,21 @@ exports.dbg_assert = function dbg_assert
  * If assertions are enabled, then `condition` is checked and if false-y, the
  * assertion failure is logged and then an error is thrown.
  *
  * If assertions are not enabled, then this function is a no-op.
  *
  * This is an improvement over `dbg_assert`, which doesn't actually cause any
  * fatal behavior, and is therefore much easier to accidentally ignore.
  */
-exports.defineLazyGetter(exports, "assert", () => {
-  function noop(condition, msg) { }
-
-  function assert(condition, message) {
-    if (!condition) {
-      const err = new Error("Assertion failure: " + message);
-      exports.reportException("DevToolsUtils.assert", err);
-      throw err;
-    }
-  }
-
-  const scope = {};
-  Cu.import("resource://gre/modules/AppConstants.jsm", scope);
-  const { DEBUG, DEBUG_JS_MODULES } = scope.AppConstants;
-
-  return (DEBUG || DEBUG_JS_MODULES || exports.testing) ? assert : noop;
-});
+Object.defineProperty(exports, "assert", {
+  get: () => (AppConstants.DEBUG || AppConstants.DEBUG_JS_MODULES || this.testing)
+    ? reallyAssert
+    : exports.noop,
+})
 
 /**
  * Defines a getter on a specified object for a module.  The module will not
  * be imported until first use.
  *
  * @param aObject
  *        The object to define the lazy getter on.
  * @param aName
--- a/devtools/shared/heapsnapshot/HeapSnapshot.h
+++ b/devtools/shared/heapsnapshot/HeapSnapshot.h
@@ -5,16 +5,17 @@
 
 #ifndef mozilla_devtools_HeapSnapshot__
 #define mozilla_devtools_HeapSnapshot__
 
 #include "js/HashTable.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/devtools/DeserializedNode.h"
 #include "mozilla/dom/BindingDeclarations.h"
+#include "mozilla/dom/Nullable.h"
 #include "mozilla/HashFunctions.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/RefCounted.h"
 #include "mozilla/RefPtr.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/UniquePtr.h"
 
 #include "CoreDump.pb.h"
@@ -134,16 +135,25 @@ public:
     auto p = nodes.lookup(rootId);
     MOZ_ASSERT(p);
     const DeserializedNode& node = *p;
     return JS::ubi::Node(const_cast<DeserializedNode*>(&node));
   }
 
   void TakeCensus(JSContext* cx, JS::HandleObject options,
                   JS::MutableHandleValue rval, ErrorResult& rv);
+
+  dom::Nullable<uint64_t> GetCreationTime() {
+    static const uint64_t maxTime = uint64_t(1) << 53;
+    if (timestamp.isSome() && timestamp.ref() <= maxTime) {
+      return dom::Nullable<uint64_t>(timestamp.ref());
+    }
+
+    return dom::Nullable<uint64_t>();
+  }
 };
 
 // A `CoreDumpWriter` is given the data we wish to save in a core dump and
 // serializes it to disk, or memory, or a socket, etc.
 class CoreDumpWriter
 {
 public:
   virtual ~CoreDumpWriter() { };
new file mode 100644
--- /dev/null
+++ b/devtools/shared/heapsnapshot/tests/unit/test_HeapSnapshot_creationTime_01.js
@@ -0,0 +1,29 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// HeapSnapshot.prototype.creationTime returns the expected time.
+
+function waitForTenMilliseconds() {
+  const start = Date.now();
+  while (Date.now() - start < 10) ;
+}
+
+function run_test() {
+  const start = Date.now() * 1000;
+  do_print("start                 = " + start);
+
+  // Because Date.now() is less precise than the snapshot's time stamp, give it
+  // a little bit of head room.
+  waitForTenMilliseconds();
+  const path = ChromeUtils.saveHeapSnapshot({ runtime: true });
+  waitForTenMilliseconds();
+
+  const end = Date.now() * 1000;
+  do_print("end                   = " + end);
+
+  const snapshot = ChromeUtils.readHeapSnapshot(path);
+  do_print("snapshot.creationTime = " + snapshot.creationTime);
+
+  ok(snapshot.creationTime >= start);
+  ok(snapshot.creationTime <= end);
+}
--- a/devtools/shared/heapsnapshot/tests/unit/xpcshell.ini
+++ b/devtools/shared/heapsnapshot/tests/unit/xpcshell.ini
@@ -20,16 +20,17 @@ support-files =
 [test_census-tree-node-03.js]
 [test_HeapAnalyses_readHeapSnapshot_01.js]
 [test_HeapAnalyses_takeCensusDiff_01.js]
 [test_HeapAnalyses_takeCensus_01.js]
 [test_HeapAnalyses_takeCensus_02.js]
 [test_HeapAnalyses_takeCensus_03.js]
 [test_HeapAnalyses_takeCensus_04.js]
 [test_HeapAnalyses_takeCensus_05.js]
+[test_HeapSnapshot_creationTime_01.js]
 [test_HeapSnapshot_takeCensus_01.js]
 [test_HeapSnapshot_takeCensus_02.js]
 [test_HeapSnapshot_takeCensus_03.js]
 [test_HeapSnapshot_takeCensus_04.js]
 [test_HeapSnapshot_takeCensus_05.js]
 [test_HeapSnapshot_takeCensus_06.js]
 [test_HeapSnapshot_takeCensus_07.js]
 [test_HeapSnapshot_takeCensus_08.js]
--- a/devtools/shared/tests/unit/head_devtools.js
+++ b/devtools/shared/tests/unit/head_devtools.js
@@ -4,16 +4,21 @@ var Ci = Components.interfaces;
 var Cu = Components.utils;
 var Cr = Components.results;
 
 var {require} = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm");
 const DevToolsUtils = require("devtools/shared/DevToolsUtils");
 
 // Register a console listener, so console messages don't just disappear
 // into the ether.
+
+// If for whatever reason the test needs to post console errors that aren't
+// failures, set this to true.
+var ALLOW_CONSOLE_ERRORS = false;
+
 var errorCount = 0;
 var listener = {
   observe: function (aMessage) {
     errorCount++;
     try {
       // If we've been given an nsIScriptError, then we can print out
       // something nicely formatted, for tools like Emacs to pick up.
       var scriptError = aMessage.QueryInterface(Ci.nsIScriptError);
@@ -30,14 +35,17 @@ var listener = {
         var string = "<error converting error message to string>";
       }
     }
 
     // Make sure we exit all nested event loops so that the test can finish.
     while (DebuggerServer.xpcInspector.eventLoopNestLevel > 0) {
       DebuggerServer.xpcInspector.exitNestedEventLoop();
     }
-    do_throw("head_dbg.js got console message: " + string + "\n");
+
+    if (!ALLOW_CONSOLE_ERRORS) {
+      do_throw("head_devtools.js got console message: " + string + "\n");
+    }
   }
 };
 
 var consoleService = Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService);
 consoleService.registerListener(listener);
new file mode 100644
--- /dev/null
+++ b/devtools/shared/tests/unit/test_assert.js
@@ -0,0 +1,36 @@
+/* -*- js-indent-level: 2; indent-tabs-mode: nil -*- */
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// Test DevToolsUtils.assert
+
+ALLOW_CONSOLE_ERRORS = true;
+
+function run_test() {
+  // Enable assertions.
+  DevToolsUtils.testing = true;
+
+  const { assert } = DevToolsUtils;
+  equal(typeof assert, "function");
+
+  try {
+    assert(true, "this assertion should not fail");
+  } catch (e) {
+    // If you catch assertion failures in practice, I will hunt you down. I get
+    // email notifications every time it happens.
+    ok(false, "Should not get an error for an assertion that should not fail. Got "
+       + DevToolsUtils.safeErrorString(e));
+  }
+
+  let assertionFailed = false;
+  try {
+    assert(false, "this assertion should fail");
+  } catch (e) {
+    ok(e.message.startsWith("Assertion failure:"),
+       "Should be an assertion failure error");
+    assertionFailed = true;
+  }
+
+  ok(assertionFailed,
+     "The assertion should have failed, which should throw an error when assertions are enabled.");
+}
--- a/devtools/shared/tests/unit/xpcshell.ini
+++ b/devtools/shared/tests/unit/xpcshell.ini
@@ -1,16 +1,17 @@
 [DEFAULT]
 tags = devtools
 head = head_devtools.js
 tail =
 skip-if = toolkit == 'android' || toolkit == 'gonk'
 support-files =
   exposeLoader.js
 
+[test_assert.js]
 [test_fetch-chrome.js]
 [test_fetch-file.js]
 [test_fetch-http.js]
 [test_fetch-resource.js]
 [test_indentation.js]
 [test_independent_loaders.js]
 [test_invisible_loader.js]
 [test_safeErrorString.js]
--- a/dom/webidl/HeapSnapshot.webidl
+++ b/dom/webidl/HeapSnapshot.webidl
@@ -5,16 +5,22 @@
  */
 
 /**
  * A HeapSnapshot represents a snapshot of the heap graph
  */
 [ChromeOnly, Exposed=(Window,System,Worker)]
 interface HeapSnapshot {
   /**
+   * A time stamp of when the heap snapshot was taken, if available. Units are
+   * microseconds since midnight (00:00:00) 1 January 1970 UTC.
+   */
+  readonly attribute unsigned long long? creationTime;
+
+  /**
    * Take a census of the heap snapshot.
    *
    * This is the same as |Debugger.Memory.prototype.takeCensus|, but operates on
    * the offline heap snapshot's serialized heap graph rather than the live heap
    * graph. The same optional configuration options that can be passed to that
    * function can be passed here.
    *
    * The returned value is determined by the `"breakdown"` option used, and is
--- a/mobile/android/base/Makefile.in
+++ b/mobile/android/base/Makefile.in
@@ -458,17 +458,19 @@ update-generated-wrappers:
 	$(MAKE) -C ../app
 	$(MAKE) -C ../themes/core
 	$(MAKE) -C ../installer stage-package
 	$(MKDIR) -p $(@D)
 	rsync --update $(DIST)/fennec/$(notdir $(OMNIJAR_NAME)) $@
 	$(RM) $(DIST)/fennec/$(notdir $(OMNIJAR_NAME))
 
 # Targets built very early during a Gradle build.
-gradle-targets: .aapt.deps
+gradle-targets: $(foreach f,$(constants_PP_JAVAFILES),$(f))
+gradle-targets: $(abspath AndroidManifest.xml)
+gradle-targets: $(ANDROID_GENERATED_RESFILES)
 
 gradle-omnijar: $(abspath $(DIST)/fennec/$(OMNIJAR_NAME))
 
 .PHONY: gradle-targets gradle-omnijar
 
 ifndef MOZ_DISABLE_GECKOVIEW
 libs:: geckoview_resources.zip
 	$(INSTALL) geckoview_resources.zip $(FINAL_TARGET)
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -812,16 +812,17 @@ if CONFIG['MOZ_INSTALL_TRACKING']:
 # Putting branding earlier allows branders to override default resources.
 ANDROID_RES_DIRS += [
     '/' + CONFIG['MOZ_BRANDING_DIRECTORY'] + '/res',
     'resources',
     '!res',
 ]
 
 ANDROID_GENERATED_RESFILES += [
+    'res/raw/browsersearch.json',
     'res/raw/suggestedsites.json',
     'res/values/strings.xml',
 ]
 
 ANDROID_ASSETS_DIRS += [
     '/mobile/android/app/assets',
 ]
 
deleted file mode 100644
--- a/mobile/android/base/resources/layout/tabs_panel_back_button.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
-   - License, v. 2.0. If a copy of the MPL was not distributed with this
-   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<org.mozilla.gecko.tabs.TabPanelBackButton xmlns:android="http://schemas.android.com/apk/res/android"
-                                           xmlns:gecko="http://schemas.android.com/apk/res-auto"
-                                           android:id="@+id/nav_back"
-                                           android:layout_width="@dimen/tabs_panel_button_width"
-                                           android:layout_height="match_parent"
-                                           android:minWidth="@dimen/tabs_panel_button_width"
-                                           android:src="@drawable/tabs_panel_nav_back"
-                                           android:contentDescription="@string/back"
-                                           android:background="@drawable/action_bar_button_inverse"
-                                           gecko:dividerVerticalPadding="@dimen/tab_panel_divider_vertical_padding"
-                                           gecko:rightDivider="@drawable/tab_indicator_divider"/>
-
--- a/mobile/android/base/resources/layout/tabs_panel_default.xml
+++ b/mobile/android/base/resources/layout/tabs_panel_default.xml
@@ -13,20 +13,26 @@
                     android:layout_width="match_parent"
                     android:layout_height="@dimen/browser_toolbar_height">
 
         <view class="org.mozilla.gecko.tabs.TabsPanel$TabsPanelToolbar"
               android:layout_width="match_parent"
               android:layout_height="@dimen/browser_toolbar_height"
               android:background="@color/text_and_tabs_tray_grey">
 
-            <ViewStub android:id="@+id/nav_back_stub"
-                      android:layout="@layout/tabs_panel_back_button"
-                      android:layout_width="wrap_content"
-                      android:layout_height="match_parent"/>
+            <org.mozilla.gecko.tabs.TabPanelBackButton
+                android:id="@+id/nav_back"
+                android:layout_width="@dimen/tabs_panel_button_width"
+                android:layout_height="match_parent"
+                android:minWidth="@dimen/tabs_panel_button_width"
+                android:src="@drawable/tabs_panel_nav_back"
+                android:contentDescription="@string/back"
+                android:background="@drawable/action_bar_button_inverse"
+                gecko:dividerVerticalPadding="@dimen/tab_panel_divider_vertical_padding"
+                gecko:rightDivider="@drawable/tab_indicator_divider"/>
 
             <org.mozilla.gecko.widget.IconTabWidget android:id="@+id/tab_widget"
                                                     android:layout_width="wrap_content"
                                                     android:layout_height="match_parent"
                                                     android:tabStripEnabled="false"
                                                     android:divider="@drawable/tab_indicator_divider"
                                                     android:dividerPadding="@dimen/tab_panel_divider_vertical_padding"
                                                     android:layout="@layout/tabs_panel_indicator"/>
--- a/mobile/android/base/tabs/TabsLayoutItemView.java
+++ b/mobile/android/base/tabs/TabsLayoutItemView.java
@@ -91,19 +91,17 @@ public class TabsLayoutItemView extends 
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
         mTitle = (TextView) findViewById(R.id.title);
         mThumbnail = (TabsPanelThumbnailView) findViewById(R.id.thumbnail);
         mCloseButton = (ImageView) findViewById(R.id.close);
         mThumbnailWrapper = (TabThumbnailWrapper) findViewById(R.id.wrapper);
 
-        if (HardwareUtils.isTablet() || AppConstants.NIGHTLY_BUILD) {
-            growCloseButtonHitArea();
-        }
+        growCloseButtonHitArea();
     }
 
     private void growCloseButtonHitArea() {
         getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
             @Override
             public boolean onPreDraw() {
                 getViewTreeObserver().removeOnPreDrawListener(this);
 
--- a/mobile/android/base/tabs/TabsPanel.java
+++ b/mobile/android/base/tabs/TabsPanel.java
@@ -159,26 +159,23 @@ public class TabsPanel extends LinearLay
         mMenuButton = findViewById(R.id.menu);
         mMenuButton.setOnClickListener(new Button.OnClickListener() {
             @Override
             public void onClick(View view) {
                 showMenu();
             }
         });
 
-        if (AppConstants.NIGHTLY_BUILD || HardwareUtils.isTablet()) {
-            ViewStub backButtonStub = (ViewStub) findViewById(R.id.nav_back_stub);
-            mNavBackButton = (ImageButton) backButtonStub.inflate( );
-            mNavBackButton.setOnClickListener(new Button.OnClickListener() {
-                @Override
-                public void onClick(View view) {
-                    mActivity.onBackPressed();
-                }
-            });
-        }
+        mNavBackButton = (ImageButton) findViewById(R.id.nav_back);
+        mNavBackButton.setOnClickListener(new Button.OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                mActivity.onBackPressed();
+            }
+        });
     }
 
     public void showMenu() {
         final Menu menu = mPopupMenu.getMenu();
 
         // Each panel has a "+" shortcut button, so don't show it for that panel.
         menu.findItem(R.id.new_tab).setVisible(mCurrentPanel != Panel.NORMAL_TABS);
         menu.findItem(R.id.new_private_tab).setVisible(mCurrentPanel != Panel.PRIVATE_TABS
@@ -244,49 +241,22 @@ public class TabsPanel extends LinearLay
         if (itemId == R.id.new_tab || itemId == R.id.new_private_tab) {
             hide();
         }
 
         return mActivity.onOptionsItemSelected(item);
     }
 
     private static int getTabContainerHeight(TabsLayoutContainer tabsContainer) {
-        Resources resources = tabsContainer.getContext().getResources();
-
-        int screenHeight = resources.getDisplayMetrics().heightPixels;
-
-        int actionBarHeight = resources.getDimensionPixelSize(R.dimen.browser_toolbar_height);
-
-        if (HardwareUtils.isTablet() || AppConstants.NIGHTLY_BUILD) {
-            return screenHeight - actionBarHeight;
-        }
-
-        PanelView panelView = tabsContainer.getCurrentPanelView();
-        if (panelView != null && !panelView.shouldExpand()) {
+        final Resources resources = tabsContainer.getContext().getResources();
 
-            // This allows us to accommodate varying height tab previews across different devices.
-            // We should be able to remove once we remove the list view and remove the chrome again
-            return resources.getDimensionPixelSize(R.dimen.tab_thumbnail_height)
-                 + resources.getDimensionPixelSize(R.dimen.tab_title_height)
-                 + 2 * (resources.getDimensionPixelSize(R.dimen.tab_highlight_stroke_width)
-                      + resources.getDimensionPixelSize(R.dimen.tab_vertical_padding)
-                      + resources.getDimensionPixelSize(R.dimen.tab_thumbnail_padding)
-                      + resources.getDimensionPixelSize(R.dimen.tab_thumbnail_margin));
-        }
+        final int screenHeight = resources.getDisplayMetrics().heightPixels;
+        final int actionBarHeight = resources.getDimensionPixelSize(R.dimen.browser_toolbar_height);
 
-        Rect windowRect = new Rect();
-        tabsContainer.getWindowVisibleDisplayFrame(windowRect);
-        int windowHeight = windowRect.bottom - windowRect.top;
-
-        // The web content area should have at least 1.5x the height of the action bar.
-        // The tabs panel shouldn't take less than 50% of the screen height and can take
-        // up to 80% of the window height.
-        return (int) Math.max(screenHeight * 0.5f,
-                Math.min(windowHeight - 2.5f * actionBarHeight, windowHeight * 0.8f) - actionBarHeight);
-
+        return screenHeight - actionBarHeight;
     }
 
     @Override
     public void onAttachedToWindow() {
         super.onAttachedToWindow();
         mTheme.addListener(this);
     }
 
--- a/mobile/android/base/tabs/TabsPanelThumbnailView.java
+++ b/mobile/android/base/tabs/TabsPanelThumbnailView.java
@@ -1,16 +1,15 @@
 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
  * 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/. */
 
 package org.mozilla.gecko.tabs;
 
-import org.mozilla.gecko.AppConstants;
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.ThumbnailHelper;
 import org.mozilla.gecko.widget.CropImageView;
 
 import android.content.Context;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 
@@ -30,21 +29,17 @@ public class TabsPanelThumbnailView exte
     }
 
     public TabsPanelThumbnailView(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
     }
 
     @Override
     protected float getAspectRatio() {
-        if (AppConstants.NIGHTLY_BUILD) {
-            return ThumbnailHelper.TABS_PANEL_THUMBNAIL_ASPECT_RATIO;
-        } else {
-            return ThumbnailHelper.TOP_SITES_THUMBNAIL_ASPECT_RATIO;
-        }
+        return ThumbnailHelper.TABS_PANEL_THUMBNAIL_ASPECT_RATIO;
     }
 
     @Override
     public void setImageDrawable(Drawable drawable) {
         boolean resize = true;
 
         if (drawable == null) {
             drawable = getResources().getDrawable(R.drawable.tab_panel_tab_background);
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -1313,16 +1313,17 @@ var BrowserApp = {
    * @param  aURL URL to look for
    * @param  aOptions Options for the search. Currently supports:
    **  @option startsWith a Boolean indicating whether to search for a tab who's url starts with the
    *           requested url. Useful if you want to ignore hash codes on the end of a url. For instance
    *           to have about:downloads match about:downloads#123.
    * @return the tab with the given URL, or null if no such tab exists
    */
   getTabWithURL: function getTabWithURL(aURL, aOptions) {
+    aOptions = aOptions || {};
     let uri = Services.io.newURI(aURL, null, null);
     for (let i = 0; i < this._tabs.length; ++i) {
       let tab = this._tabs[i];
       if (aOptions.startsWith) {
         if (tab.browser.currentURI.spec.startsWith(aURL)) {
           return tab;
         }
       } else {
--- a/mobile/android/gradle/app/build.gradle
+++ b/mobile/android/gradle/app/build.gradle
@@ -2,16 +2,19 @@ apply plugin: 'com.android.application'
 
 android {
     compileSdkVersion 23
     buildToolsVersion "23.0.1"
 
     defaultConfig {
         targetSdkVersion 22
         minSdkVersion 9
+        applicationId mozconfig.substs.ANDROID_PACKAGE_NAME
+        testApplicationId 'org.mozilla.roboexample.test'
+        testInstrumentationRunner 'org.mozilla.gecko.FennecInstrumentationTestRunner'
     }
 
     compileOptions {
         sourceCompatibility JavaVersion.VERSION_1_7
         targetCompatibility JavaVersion.VERSION_1_7
     }
 
     lintOptions {
@@ -20,23 +23,23 @@ android {
 
     buildTypes {
         release {
             minifyEnabled true
             proguardFile "${topsrcdir}/mobile/android/config/proguard/proguard.cfg"
         }
     }
 
-    defaultConfig {
-        testApplicationId 'org.mozilla.roboexample.test'
-        testInstrumentationRunner 'org.mozilla.gecko.FennecInstrumentationTestRunner'
-    }
+    sourceSets {
+        main {
+            manifest.srcFile "${topobjdir}/mobile/android/base/AndroidManifest.xml"
+        }
 
-    sourceSets {
         androidTest {
+            manifest.srcFile "${topobjdir}/build/mobile/robocop/AndroidManifest.xml"
             java {
                 srcDir "src/robocop_harness"
                 srcDir "src/robocop"
                 srcDir "src/background"
                 srcDir "src/browser"
                 srcDir "src/javaaddons"
             }
         }
--- a/mobile/android/gradle/base/build.gradle
+++ b/mobile/android/gradle/base/build.gradle
@@ -41,21 +41,28 @@ android {
                 }
 
                 if (mozconfig.substs.MOZ_WEBRTC) {
                     srcDir 'src/webrtc_audio_device'
                     srcDir 'src/webrtc_video_capture'
                     srcDir 'src/webrtc_video_render'
                 }
 
-                // Adjust helpers are included in the preprocessed_code project.
-                exclude 'org/mozilla/gecko/adjust/**'
+                if (mozconfig.substs.MOZ_INSTALL_TRACKING) {
+                    exclude 'org/mozilla/gecko/adjust/StubAdjustHelper.java'
+                } else {
+                    exclude 'org/mozilla/gecko/adjust/AdjustHelper.java'
+                }
+
+                srcDir "${project.buildDir}/generated/source/preprocessed_code" // See syncPreprocessedCode.
             }
 
             res {
+                srcDir "src/branding/res"
+                srcDir "${project.buildDir}/generated/source/preprocessed_resources" // See syncPreprocessedResources.
                 if (mozconfig.substs.MOZ_CRASHREPORTER) {
                     srcDir "src/crashreporter/res"
                 }
             }
         }
 
         test {
             java {
@@ -64,33 +71,50 @@ android {
 
             resources {
                 srcDir "resources/background_junit4"
             }
         }
     }
 }
 
+
+task syncPreprocessedCode(type: Sync, dependsOn: rootProject.generateCodeAndResources) {
+    into("${project.buildDir}/generated/source/preprocessed_code")
+    from("${topobjdir}/mobile/android/base/generated/preprocessed")
+}
+
+task syncPreprocessedResources(type: Sync, dependsOn: rootProject.generateCodeAndResources) {
+    into("${project.buildDir}/generated/source/preprocessed_resources")
+    from("${topobjdir}/mobile/android/base/res")
+}
+
+android.libraryVariants.all { variant ->
+    variant.preBuild.dependsOn syncPreprocessedCode
+    variant.preBuild.dependsOn syncPreprocessedResources
+}
+
 dependencies {
     compile 'com.android.support:support-v4:23.0.1'
     compile 'com.android.support:appcompat-v7:23.0.1'
     compile 'com.android.support:recyclerview-v7:23.0.1'
 
     if (mozconfig.substs.MOZ_NATIVE_DEVICES) {
         compile 'com.android.support:mediarouter-v7:22.2.1'
         compile 'com.google.android.gms:play-services-basement:8.1.0'
         compile 'com.google.android.gms:play-services-base:8.1.0'
         compile 'com.google.android.gms:play-services-cast:8.1.0'
     }
 
-    compile project(':branding')
-    compile project(':preprocessed_code')
-    compile project(':preprocessed_resources')
     compile project(':thirdparty')
 
+    if (mozconfig.substs.MOZ_INSTALL_TRACKING) {
+        compile project(':thirdparty_adjust_sdk')
+    }
+
     testCompile 'junit:junit:4.12'
     testCompile 'org.robolectric:robolectric:3.0'
     testCompile 'org.simpleframework:simple-http:4.1.13'
 }
 
 apply plugin: 'idea'
 
 idea {
deleted file mode 100644
--- a/mobile/android/gradle/branding/AndroidManifest.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="org.mozilla.gecko.branding">
-
-</manifest>
deleted file mode 100644
--- a/mobile/android/gradle/branding/build.gradle
+++ /dev/null
@@ -1,20 +0,0 @@
-apply plugin: 'com.android.library'
-
-android {
-    compileSdkVersion 23
-    buildToolsVersion "23.0.1"
-
-    defaultConfig {
-        targetSdkVersion 22
-        minSdkVersion 9
-    }
-
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_7
-        targetCompatibility JavaVersion.VERSION_1_7
-    }
-
-    lintOptions {
-        abortOnError false
-    }
-}
--- a/mobile/android/gradle/build.gradle
+++ b/mobile/android/gradle/build.gradle
@@ -77,23 +77,26 @@ gradle.taskGraph.beforeTask {
 }
 
 afterEvaluate {
     subprojects {
         if (!hasProperty('android')) {
             return
         }
         android.applicationVariants.all {
-            checkManifest.dependsOn rootProject.generateCodeAndResources
+            preBuild.dependsOn rootProject.generateCodeAndResources
         }
         android.libraryVariants.all {
-            checkManifest.dependsOn rootProject.generateCodeAndResources
+            preBuild.dependsOn rootProject.generateCodeAndResources
         }
     }
 }
 
 apply plugin: 'idea'
 
 idea {
     project {
         languageLevel = '1.7'
     }
 }
+
+task wrapper(type: Wrapper) {
+}
index c97a8bdb9088d370da7e88784a7a093b971aa23a..e8c6bf7bb47dff6b81c2cf7a349eb7e912c9fbe2
GIT binary patch
literal 53638
zc$|cL1CVCHvS!=1jlXSc+O}=mwr$(C-P5*hOxy0B#_a6gw{PFQd*AMf$S9nwIF%J&
zW@T38QIG}&g8>49f&z+`rWXhL`+xxb<AMH5vZ5-2bdqvn44^;?|HN3N=vF51mqFz(
zq5W4zSwT5TF;Qg|dRehY+36`6X*&7^cxgK7+3C4vCB|iz{o{vex^c-F*%=y1T40!q
zFq5=jC0bM+nB--@N{q$_TXD`aAD!-<fdA!#|8-_yf63m-{QsKNf8~Mw4<2(TLlYa*
z|0gTzKeM_!89F$aI{jZmEP_nTivO~%{3X(VKSadd-Ok3|(1eVM-q^;_+1WQn7G{tU
zDRj?*O^e2jAqaLYEbk|w12H|XppCE%w4`KJZ#FFAe&H~h<0bD2AHlRw{p%4lk?`OE
zmXVN88%O$-ZzZ{5S8MHp8rr4QHn?FMOJ`dj>jfaYnhuL1B-AyEh7yL(^HM}tdd%Oy
zItEC{iBYU87GqahUV;Z_Z4ltsrNV3v^(c_wf{n!IQ%)E%PXZ?-h6O<w9y<i@N{8?J
zFEWnohOVOhT^EPHODyvLkx|*x*~QdW!O8w_uZyLr^WU0>r=Y8gg{hs3rLm!lz0*Gy
zp;Xz{9z_tz4+9WBws2T!P@B5B>ZNiVWxrs6105R)%_LhTD<fcQ2x?yEZepMKQ2!Kd
z%X$y_Rvgp(Bb5jk^>%3XiuZAvm#6#n=ydHCXwt)qBsK^d797-?YMZ?=E*6blS!4AE
zA62`<ngn5Npe@iFZUR$pzfw1>Lz&k^VtKI4K%>e#&|`^@3*&)K;DyR)Z3yBOvGeK4
z4^5_`4U?&c@QIXM?!|N+S;>=x<hDisx~dH-Wo@521#b0{2&w7h5r8u6sflPhWh=S+
z6uOn%Bdp@ia0Tu+o}K*&tA>@PEp)BisRzh5&cK9#!<B3N4)p(JN0h?DS824*4=T~e
zqAcB61c}PCV+fd*G+{&>th0$w&m)jO0im{}!eG`Y!ErWWqHRmPNa6lHeoI0O&)c97
zB<+3&*|BeBGWKI*P?&cSp8(fmu;Igh$aMTmjSIMDHU~)9?Z=bnyi>R@*5dEHu$|v<
z+H$_MqLK_2s!{&oSb4INpW;?-%wi-e8rII5sY%HZA<Dc}Oux!oIIGSt^)el0Y8Ld(
z1pOU{pK2FLwTg13)AZ0V+UAfxWaQv9wUUF0#!R(p4MA*lNV9(+yd!r?DaIc66Myf@
z<rx2z+Z^Rm(swwAJ1LKJGOE$>(}){@vx}MJqr}CvG+b)^6$VX8x2gSe2H4g$!5>zA
zV)Iw2;xKwfhaASnGQ&Tk?(|B-x#}<4w*C^yzek<q|AyT^FeMuM^RHsTh5ea6KS4w8
zfzf+5y6>rm0Tonu(ragCm*Tl_;m?L790*6@NyUbmNdJ6)^w}W<!Z`Cj^MZo%E21H1
zlZQ$^r#MxgO#y5eVutEZvTB<vg*1~AYwQ>)revy_Bl1mo`!Y3FyoLz2d}_{I3J+>z
zr<8_KDm6^r6(NPO;SAmxGjvLAyre{Tki~o#pD2g_a8Q8k48hQuvXyqdUVpN=9q<SJ
zXGy^-y>@i|>X+hQ{i6H#l8XPYrmC~4lZ3sksf@k7wX4HFgpO6#md6o9`xZ;oU42%n
z0kpPRX@hBRXkDu=4Np}?sz4Dz%bSEk*U@*IXxe<L_mWvzEspU&iL>zyDbb7vcTaTA
zxc51qOi$km2>5|$3|0jxPEU9g?NjARMo>W+=!xmPMIwnc5FK;|B>?pzc`1r1S;!7b
zLrcRYYyW=vEl91uIZ<a{`m`u0H<#wNl<yMeaIwzG#yZtdtu^Z`+ub$ExD!ib+H@Y1
zH-jnd?UiU~vDAp0XXp(+WaV_&AG-Dm%g@?jwpsR?SSXMOU<6~&g&~hAk;%U0unymz
z!41d2^yM@iqQ<JD`gCL5$IpZh6Pa|Z)>>hs##rO;7VDkWwJkp;VD0F>T=tlBl*@9p
z^6l6}Hphyk{G`i@YqQnLVSLcquyQZ`l~bmDViZWc8O=hKq$<KFsKf8sBpLAwS&*zp
zsWAo};@J!y*kAVUrm?~!7#;l;$t>e6??Y^<g?if*N_VN+BienrKJ5v%+9Mtj?$I3&
z()F%i;`d!fdT*S<P0hhQ&X7T>H})Da&TR}aM!zpPO0V672Ln;AW5QX7uT+@DOdTWb
zZe$Z5kmHZMqj0R7G4JJ3+MVBuUie=TQI<*QBUqM$$vfiyXh$5MM8uh#!b!<!3lc1g
zps<(*`q~MA2?H9=I7l*8!T>5>GW<bSg4SetEt4nKA>Z^fhMTV-uh1Wf6%c(P!RZOy
z!h>%Rni*@MBqDGmY7uU5@shJdVV#$QC>Q{W7xJZx{<?H3Z69TID0GH`5Xj1JuH`$V
zNM|_zaN3tayDM@br!rNymw!=6yhGis5pW=&-+#MU{yj`ZJ&bK!oh{u=#Vl=11&xhO
zot<S3?F`LL|HJC1s!2Pbn&SPj&7!dEvL*gOtY8Ba+M*Byz*q`OTQ{=MDu6EqM{l2C
z*X`Pg&6bt+CE~yMaJ@UrEoLUA(|{bs78f52<~|C%9~{AE$ireF7~X5oPV2)*cqjOC
zdi&=$yTJFy3Oo?vQ8H0mVKWGF$?)Q_xI2;_-s_PF62D8-l%(SYbb<Pnr63o1S|5>I
z@m_o&&@7lDX#^W5?l6l7yM*!_xFf>cM<Ey^0F4FMBs2?0gf5IaamWD)XI9+^tc$SN
z56dqDWwj)Zl6%gTO!@lMOWxIm?1MZ+=`@vzyo^SSe$`q#E73YpA(b&Us20mDzX($m
z8oiCZDoeDxnn+Mes$w>~E05J?1xMLM@Tt`*%#1Kifk2i5_cxgbs##hT8`X?LcXV-Z
zRjL|<tLhsIOVn<;Mpj39gr2uXajM2-i&JAxsfjBayB*bgkJZQ~gUOSTAg(eGtFG;o
z$+A$PG*e2B6>^2VBNWPJksV$ZHmVcdO|6Bs7p*Z)W|3)S7``;1i=MZQbvpX@+rB58
z@lr-Uv9??G3|2gHvYnY2*>YzR1iX0|`jEnN&{3daOoUA3;{g*3tYO4_3dqdzA4DQ(
z;Db4~rctGs8m<e7%Ov)>jcd(e)B)-7lWkhTYzKyvTHTC4k)Jm31UmSJ*4#Tz8NUTr
zg=e;Ka6^0-s*mAD=(Uz_tz^g2&7SXkS4LbH2UG_)6-|v4WY5e5`81bRwDXDHyjStU
zw58j!<2hvljfQxkoFy!4NmytY40o8tur%s5TbN6kSL?T3y+fN~01wOrgL2s24az~h
z0#euv14#{z_a^vMR$gkYCTIpz0Hc`eM)kRvaV*Rb0R4EzK(t>E*^y}viQ$rzX!?HR
zsHx6ywVzJXJ&s;_;()SW5Al(#Oq2f2`wbP2k<V!paUt_{obxbV6cnDl;}c0*l}Xr&
zjfu{JjZrLIrkY7zC+SU&s0|CV$g5*j@3oNMSiHMwPx$NC+mF%k@sIn&nD|8VymYG2
zkg|^~M}(onyd(t-bhi4*$`@$SCwWV&BKYX=Ir&68)0FAwg|K4+?)*D@lSt~WlwOr$
zl^;yCZRbg3R~l_2m{=(I+}uekH9?@?(?JzplrU}FlVJ?9!2r4Rvdb)*>2kn0BT6%A
zpDlZmYM9Su707h7t!zoo>2)A_Z7M;B=Z~eKE98@^o`P!X%ga~-)Wj9h<Z9EZu>CCv
z*fPDA71SucX>48kHQ(k6buZkrc*OL+juhwm*OSyCgMqZFYN<f6Rr*X{h+n)2pBmzC
zpp!_WZdX8iBD=g$BxDr1rwLeY;zCB391ga>Yy+50x2<u?iP`KrVdRZ>R8w>vQ`~v1
z^y;=c?8L$0)tBxFlt}7uvKlZQ<OXAZ<%EzT&M{pTqwRQHycMPcPq2XA4%|?s%nfib
z!VAO)QmKRl>69sO!FP5?Zd0k`rXA{0>G{F0%<xkYKtcA2Lo&4XjWQf$s_=io&9GEp
zTfo$2j&62vT;&P@^a#o>xW#|p%o$SGBYJl#l-fMtu<P{kkY2IQ6u1?D5w#@dg-%e}
zz=V2I6wNdnv~6!Y<GZ39q8k=%Utp0@j8PoyI3v})kr3$UQFyTEamhD4P_Vpnl{rRd
zc7^Wc`V#sL;-7xEH>Y!D_D6Wtb!WT+oYx0rIFy>8Av5lSc}w3oY6(By?Jtnw61juM
z62w{dhJ!mo)MO5k_*xg#LG+99_X<Gw4gr1xOHXT&`W6Qmp6wGK!94;KAJIKLzrKX?
zDx45OT6}`@UYdg-nS}M@lSZXx)$+<gpJ=(t%_cn}-q;B!Yh#%EiQ_Ovdl36kmWWf1
z7*l_7y;B1IkWuL=T|}xq?I5?&^+T0n@J;O;wVb(ESoQqfP;|mLTtiJ5z^f}x+N|he
zK`AA#$$R5-ShrgDpi9!2SGKpXE4E6+v8kDe&O3Nt2>*Fkn1<IAOZ@A+yhHrA&Wrj#
zN@06DGfQ(<CqoxYd%OQ|UXpF)Q3a94{%oDD2J;666cv$N6Xz7{vp^%NGO5C$OZW)a
zIi!&u$8GDf-78y?Fx`g|4j`K5^lBH>Yz=d;G_ySBe_iW*e9X=11D)If!lg4N4A`Ub
zV&HBZ1;%E0IbJ(G2WEtDqAht%=3i_D?yl508g#=A8yqeCnBm7@Vrple%i%(Ie@C5b
z!<AN)8*|$hOR|;Iz4o#MgN7CEsyq(l=xf-x#bYh%UmaPX#24)@vurg6lZSb<w#_7H
zxV~2A*{{bvw|Or&^}L!@qwZecWaio~HNR_;q5cfKW?9CmTVvnM>)dOMnalI^vGE+0
z`=zdXTD)`PMPW|7?Xv~5O5f9?P&;8i_u-`6=+zkBoK~v1utZ&cL|<2VRh<=H_2;EZ
zOuReETx0{evfccE)NfBIPK8iTKz#O=PbAf%qas3h>DtSC6*l|UPo;HV^BV^q9d1ES
z-;TbX?V?+I=J&}>bu5P~eDF96T#g^{H_bg8TEd#bVcB$S7%;r(F6VQ;erg@J{-N0A
z{3a|T@OL<nQp9~E+Q{2=Ap?{?S|6DY*Au8gPW}~Rt{Y%(JpNK(;7REU%&|9xQ;<1E
z*)ZoDW0D~mUo6Q696HJ=g~}kMh$%)vEgC}6EQWUoT?aiK>z5~8rN8*e<wipaQciTT
z`Jtl@>LK|>+`XOeZ?H_~6rGG*qL~?oL5F2>iaQC|y-5dr4m2W1Y!fADX2B!$zqJxE
zoL)qzKa8J;+ENK6aLmPEowX2>lSIxXnYW-yNJPm}2{mv{1z?@U5EGL`@sf`vh!Tnc
zGE{;}%;V1F5~}b?NrGvT&5MvFWIwE=5?bJt)Pv5f{+3O0S!=#OCP7TNm$$!Q{~6ng
zzWA2Mf1Psdzg>*~9^3yK?@Acj{eAr(?oO=Qr8BB3+8^6&lOeaMVg)IwP$&?~-w^@m
zHZaulQl*Gw3ba98vi8ZLCLA{GE$Ha^Z(?7AaB)NG{9M69SOc@;?tcK!?i__P(VJ#o
zH@&B>bMLv%b60zRKHo6|zTPy4=wm88goRPXSaXIeqBz*z$RAT6(2XA$>D^JODO7XR
z?$g55V!#~5>YycOrJUq~<0^?}tvzs;7O#Y0cYlsx=nQrz^-wbKP?p|WGcuA&Dh<(w
zsN`7-!dRl0MNPqg2$z|5iKDZMca@{P#ceeU{S0GTLO~6^igB35VZnCV9K9+@%w)z>
z&YP0S&t`vw@fx$CM3?3owGkUW!6!{em7{IUa2I`PF@D_7BJp2r0Jt5(u$PBu)2KGE
zFuQGZm<`MDup60)^mMz>c9>DH+x@b@WUURkgd(jbQYq!JI)<^66k!VuY-N}drwqqT
zB00@!6V-e~Zv;5smtYS`jaZmzQAI7+98fF`YP#L*Tt%d4?0@A+j2duO3aM$>wWd#G
zPLZ4|?V9uz7)XZ(E2?vbSxav{cOJW#E}N*B*A$f2G>(UuB3mKPJD~^I)*{sdQL#*5
z)7!V=m^yWlMM*za1<{}6VYn9j-YoQLxZn~$chDV_(G1geI5YNmHmchwPiugcQ%c#t
z@Dh`LmR82^7Chsq-F99aFZWE3qTyyXShBGUNe_xMZ%KNxIB!T?a#a1jyIoL@=28dd
zS7y*@rltbLW7W*9#>mp#G~tHG6L%eQx-<x5ZeyI*bSLFH<Q#JxfdJ_#se=!$lMFmV
zv!0<Jc3|XRBCuI&BsfOGKktZ7SoJ0`Hr7#ih>D*dr0Ekj=ZZIgN!_>XsO;1?xJKQ#
za8K8_bkFCf;3z#7|0XHua*dc7xct%&(u*REfZ4o#jz^EFk+WHs04h#VZ?F|r@xUex
z@6T*}TFQbQC%V%o;oI!8);K9KX8kn9;L7$@V4bdElPS?l!d3)NQn8;S%k$FXBcu0;
zKj#tbQz6Nd{dlKIUK$q9F~F6ER2R~s6iW-EU5({rmu8Mc=$q;_Vq;Z(%G}qIn2!YO
za?spUiW7HS=-$Bm`^a)gGNKyXkX$qvPfg4cpZ-W5vcY~f#r35euX})NodDZbBQ&;^
z_b>@rZBo`7o<k}t>HYRA|2M;_B5)2zK=wui3<3wEezGv{+#daSKLx;vKk?>(YE<>$
zBA!3wp__778s{!!t1(`Mfr==|uI>^^6tUH!hBp9F@ZnoSXz59qHC{CO?hC|!?u-0w
z0xE_<Ft_Y<U&LM?`SPuPCz$^%IXmHYf-i(Jtw5fkFm>~Ciyf^ok)9oWVf7U$JHN%&
zGvp<5m!yqfEIde1fBY3|3vK%+bSG@$@h$9o^ck(uhXD~9py(3eB?P38Bo9|b*b15F
zrl^;)<VC7BSH&mBfn|2@<5h9amlZY9_sksR%VR-Xm@`DMMS(;xLx|@bp{xTH7ipB@
zB0OT7Ug{M&jsRqF?itC;5?wSW=kb>gN!8l<J%vD<o#Xb-sNnX9bcg&5B<EEiH{`qF
zvfLE^E`~VfwbAyD7$x27<I*JsA3=d>Kp%t!-vCO9BMie*w0w}9e7ytwA;&I(d7{u8
zx-jS9q0Zs!s$!3ne|;*f#-dklx3OMgytDh@7W^N`e>Rz=o{U{;|MLv>Z=gu{?@gwR
zz4?CzgrUhF_KON=WBuu4)b&iG4l)_2xiF&YVfIWEVJ6VXgwSRbAGImjb<&oFXt95y
z{6ld@h6z7GKZ|2d+u%_&niKN!oNu}EAF2JnzkkE;BgrRA?3;n4JJ1AfRZu7f(~9Uu
z@Ca?EIuHpa&KpF;mqWN?uR{-QvJ5eApTad>NM2{?*?JFPH|Y)?)|U_QyYE)|Cd;vR
zx0Pj$RT)F^aK?0&kA@U3x8mzA;JX?)9TykJiES%(wbeP7k07zx<`ybk=T#D_jHuA*
zo_EF>p3@~N;5<x-tn|XsAgJUAXo7}~8u@&vxO(~U9;c0Jw}wVz=CuRl$W|$g!;CcW
zgjrHH&O?-rP}N<BpSV+g(%6=7B0QVn@Y#l$%;j<82rv(?D}CD_h{)hz<CP@}X$i5!
zdUr4!2;v|rN)$(k3-MwcLLWotG7pXZ`LzFSu2T%sK1&m6RTtIB@b=0ttHWOc>n)`S
z-j6z@wz~+UqXniOzAW*bW4yU5p;0zcpwp6%et0mlq#sE&E8go83gi0)JzsFXfp%2l
zFP8HJw<>8i!7UWx_e1F$nj+ng=pnTRid~|PRO*4*Xq`d|nQQK$Co&C^S60C?cU_3s
zpbsuX^PPtzKk+ln!Z&Q4xdRN^bg`a3pxN0WO|Fg40htH*O%-VNeLn>;u0Oq>wvZ;I
zPmcHl_G}w3cL-hTrg#citC-&SY4+nR=101_xrTPAI<y|C#7^*(-#T6%;=a&U=`KlL
zo4D4pv<F>J`Xbz-6?f<&8=wSxQ96_xy?6WW@Z}HiKSOfX=`so(5(vl+0SJiV-$PQt
z(8WT~+1b?A$mahXRlFPHsw01|uA+M;b4EF@w+0(g#?o$JNGby)QSVknYU_Vf%WZa8
zTa(&T-*$CZ4~IFS0$zQ=KvF&+Ftw<LTY&w3#e?*1=xVo7FTFtaa@<<(PIIvAWw-zN
zp8Mhe&Kd1L<cu05$Qe<>gRmQ>>Ln6Z3_AwMY_yp)qKrg44l5?$Ym-qzsGlg|DQ>4+
zYctn~HDZhj`jExNPx_nRE5Q*)A09dSfaJ#<C_DP#<R^}pi+16UoSJ<5;Emli!RbdF
zMl1SIg)xjRgw_w=sVaVF!RcdW?;)LMGx<oL*pJ=iV)fyUz25o$bfgR;9KI9g@}!LF
zhCztYh}Lo(chK3=0Ca|#QY$!@Rc-}~&N#Y=|4ful{t_k~dSp=^N`6cq6AwQvFQare
zPDdjXv$No6wNYe&-Jrr@ggr&S!f%loTaj^Bqe*iC|Dd24%f}<g+2wAnH?V#$;y*fj
zF}2oY^<fE1^&JFUup)bIGs3?X1&yk_)&$KLq?T`fBM&W)Nln3a@zv6yx!yDEo3m{t
zxHe!rrNb57;5A+et-7c7np)G)bmivGZ<qRswaUn5$03xsbz#_lz;<=B5I$CVwdLKL
zi+S$=Qfy>h=G^;h*HG;xJAT<XcB6y4&MdoD5VaL>{m!6>j5)Sk#mu&uGQw)>kD4UZ
z0bfKn7X9gQQM=-e>9|_y(_(_jU_FaMelnj<P<K>%bI?20bz}kVI}SLDt1cK)cX}F0
zvhA?mSh)6A7U*d>f#JceLjWjX9TnQDg{xyerxFPuk2(Jw-2C0-s!XWo>bi8lh{xP}
z1(*&?GM){Z{NTETOUUlZ&dr>@MrkT>9;LTS^ia+oRo8F>cf`Rr2<^FYzsZZG{t#AD
zAjoNwdMTpMHu;T!@H_#Hj_IH{;>k-e60ZVxG)A2_#D?zdp*5n6btJlLr#T{j7Zn9g
z`yjPegayDJ>9MPRt33OJ6EGKRqV^-MhJ7oI(vN(y?kU=z?l$jOf0IS)S7iz;*X&A`
zdm)ov(-CFra}d^dDSpe1+B-t*c`Fu<7rPfn_aDqxtvOOf_y4Jn-r^yic23V@faX+I
zjS2Q_UE}~<4|~`Y6zrN&P*B^&qsgpmthx7M{!ySxeUe;uOpz|JU1C_5vRxvd%ipML
zC<fRb+Edvc3ybQP7Q2b=KG}q*JcRF&bOOtb$7~)pTTAD-0uWTZg`=H;d`sHFu*{N6
z_LdxwNuR)$xkei#*{2(Um+v0Pl6R@N)3G70wsZi;JJ3~jq1CJA-C5uxtDETw-tu(q
z1NWEccCM;85O-U3+2ad0e}fwhJupGQ5(@k8^z}54tvxpMZdGq7HwPzW14!5CvO|>b
z0=X0Q@GFlUzWDFw|5%#&9Zh(~pO6^y_IiuCUxzWBGy4g{m3Ebqi%HRV&XjgKTwDZ*
z;7ma7l2qpOI|EXyVcB(WO)G9>7&cbvJgs}d*zZ{a_aA>>yty)ILh?LzjZx9ryc`Tw
z>iG6QSb<$F>eE_^mXGe51=U~GEM*;CO!=Wu+C-x{thoU*M<0Fea!=ZKi?tkndBD|B
ztHX~w_}XoCr3<*JO)}jyE;xM>smD90afUCU1M0o12oJGN;arG@Z=3z3s_H|4;hZo)
zg#!aAE2z30nG$Au;=-y@eM7*>ERQ)~3YMB(*4GedBgq=Th8b<&+5bq(E6%nrWisQ?
zK*g4MQ$xj<db6O5%!aZf<tFzVp<iwM@Tm);s9R=!p?Gn$fOiBK`-9J%4rX^jx}8zD
zop~wAKP#AkLY^+x9;`}$(_LyGv=9$6jVN?A5?bOJra>+QtD30`bzcSV!d$b{JI3q$
zlpb%yfai5Zl~=O*rI{?hX)H5C^emnc#CUx*0w{%Id*241==kX`loMYX+0YmxjE+Yj
zjR)NySnM2|S=p&@yUf>8x0Z6lD(yBZocbbfU&wtztiUUI$ELs%=!mEq++!ZN*Ud{w
z`GI2ldN&V9Ugck1(iR(oh?@zGIOanq%a%`Z^zn58)pd?Uty!3W%sW1!bvuo#d3MJ8
zfy%_1%$-Z?hB-y|Hp|=xwaFAom1kjOR>mYutD9neAA>2ohw+==XI*%YNFN+{(Rvx9
zsMQ1oG2QV(=tDPz<uY^hg;{B(hpfjU&nQ;R!ZW3l;PsR8t67^s%VFdZsdQA8_i`aS
zpE!^qd()^q_Wg|D8u=urYh5s$?~)I{@N`N-osYoG#6ZPRtc1DDY&4nZ+e&q_t*6b9
zU~WkqE4;u{N72)FxL+l7k2CO3x~Cj7bBZLA;2i$&Vtt_@U-H?r+KkYv$R3{wjmK?Q
z3i-azA?tZAa$Ww$uXj>Js|0@OGJf&;HH~1;9HO|3Q2b3H?hqdZ;2j=+{M$#3vGCMZ
zAGFCo|8g(Px!bmbiwXpEMFj*z^xxdj**Uuy+SvSKOU>1U^+7vs6`<_i*q|MvK^mO2
z79sHr=fFXNmrPhkO1NVrx-fB1in$`anN1R@)ryu{=~K{NP^*bIqEl6roCmC1`L?|j
zwzjses9D=zUibFCzU*#&P`~<{xp8EhARRLFf0><l=bZk@x%JW4`}$ZCkF+56M=Ic-
zO&_I<C5hF~3IbsTwj7-($0=YYsJ{b4yw9Ek2MnN^+9a_igX)Ycmt^AXljLC(@N{To
zox?zavZk7ke`dnWJv?3k%^AubEP=Y<%)#Gb^U8Zkm2fE^yaQ(q9f9ghngUlHIlb2;
zlqqFZIqJ-?!7$uC3WZ`$#EbxE%}JN|SLUZrICn;Pr^V#r7Z}w&Kf-v{(e68Ys0Pd(
zKZ1BvD|@&Gqy=M+UX)rUlqmvgkYP?gJZqm=seA$l^B<g>^VcNBr2}S<o)>MP?m~MM
z4_1L{kMI3<$>wGjRlq%9?N#4MLbps7+kk3MuYs)&qS1Ge3)Bv_2Gif(mEJpKvZzC!
zfm$8A2Md90Pu&E<zii$*g@0Ys?$fi2R!@EPDCZ#~Q&c(7{=jb_%X;IyIiV?$1mwWY
z%h{!jCPh+(x>IeV7T9Itp6Y4NQ%31w?^nNBz4vJC^3(BmY8_Z-1i{BzU$Ar7ceNB&
zx-N~Dtz>hs)!KKu2=A1&%7o6OUv@ubMG#!pShk{=)i{GMz5Vu}wLE9CjwX;4e6Y^+
zN%Sx;Pc+C{z>{}bb)k527_K;%Jlok3D=OO{7?$$q+(nHZer8;<X^)hJKX*J>tku?a
zohU)JjfXn!w1Z{;HT$z@DP~uJES1$A+j=@e5fcV`;ukkx*;dm^hoS}V0Z77QEvs=^
zYt(ttV*JA85gS+Mx~X<X&+~o5Pu9kb7;L&qi|)kr5@Q8kB*gPXI<LW$TbJ^+3+7}Q
z7G17rdlF;`LMU>$9cG;Ak`b4-Y6$IIO1w=&w=$G2(@|rZNxbsxdz{9|4w4j}Srxa*
zk^)7nD^xRYsXh)$5*bvy2d1H_jh;qm<tV4}7Ps^0G<s`U(M$?)k>{`+!O(hP_s4NN
zidHHN(Ax-v;z34fIjbkn;)oweqF|PcsG8W}G6kDWHZ0x8xMkorF?O11DsL=zC=kMx
zP&K)vf3_D7R3^8BCYDT}m>VPYQSr76ljovIgv_{>lEnb2jJ17Pt^pJd8wPGTlG18!
zP!Lf~yjey&RIo1ad{K&Fsy^41aR`EbyDuwHeJ}h0g6%G4AdIeL23h=4RVy#l^BEhK
z8m^6Z7^H@7Psf{9#=Hm;bXbLZ7SCeDm7HrU@M6p<jNSN%UPERe7cx$22E0m3Hk)2@
zxCFqyJDGrav1whdoGoh2?x{pR{FrB5F$;4gpXL^qmKMqt2*)ZBe1?HAuW_k!<gF#}
z2@h&yW*d)q7O(Eu1k;dfWdGqnG?k_8gM{iTb$PNAVzajRmTV5AVa5dWA}R|u9^<Z5
zDXd~$#-y@n$udg#>PF0hrr{{u7?EWe3h?oWn#AQcs3{W+(lhr4!w?P}uXV{pNg6zP
zO--WBnzdn6#hs=r=v^o!oHLhpQod6xS78$R2{+ft7|xW2!iAItRFh$>u*c_(eeFc>
zz}_M%h_px*j+lHN@_n+P)_cHNj646u(Lx1*a7v{HvV6^y*NTiCoAG*CL2G%74K7*?
zrM8QvCK5YISjkdIbSa~vWZBg<=)>U@;YE-UH0XR@(+=C+kPtusy?Zg_&{@ZrY7O~a
zY+CBc)YoteTiQAy8OKy42@NlC1{j4Co8;2@cWCR(A}+g$u|h~4m1Z+%xRWt0I$M*Z
zPA7BnTa>u7ys(QAV0R}yIXI(ATGu(bTLod&fG$3kLSBRxbKW+3R=dFfSh@KUA#LMk
zG$-o83sa(5Axl)a1_OrXb%uFp()D9%l@nViI%Iyb5p}XQkhujTKWA0aSvqVLrBIa(
zLu)GxgCTVUGjH&)@nofEcSKkx4LTj&*v;Lp#YBRRu(_?NV@2*1;c(@t$11aI@$o50
zs=v@(m0RYE`YXq;aFK|wc+vF<JGHLRTGcCrK=oX#k054D#bL5&uBs*5PT}0^cg<k8
zYG0te$~(nw@!jdKBePWd18voB-o2>n_hG3S&>G1zU%_LBhx7u`x+JKx)mB&43T3qK
zrb+L2b}+Y_kQ@haWG}&kE!Do@{-Ou<ce&Kpd);yR8`I!H_v%l!@2<($JHOQ1V|xkb
z{K?m76vT>8qAxhypYw;Yl^LdDu{MKdT~|KZlyvQC^C#(Kr`87@iOWWg(!zpP=VmfX
z#=aS81Ae&acxtt5WgPl5QP%hpzp@sheYqFQ>858dtHm;zhW&j%j?dKIvweQRy(CQT
z9e&C1$N@yM+)-!`wVskC3m%3(ZBuWEGtP+o#gD}e&~KV(=vYk3b?J5sJ16D~hXfCn
zq>acM*$0+g<y3B$x}J2yR_(BuW)_Qgn#`^F%2rf$QJSTnL{yr)Twr4hXWZ!qPOWz$
zIWe?+acFlad+-`mOMj~65`=GNE!SpchB%@Wk>a7Ik!R%vSe%DI#H?Q}PPN8~@K&8?
zrAm;G=*hvW(nVQzj+BKpRjJWPrVTS^DkeuMgyr1Sj0m4U)UCRqja#_7#j;!dI2H$w
zjj!~HAXI;YPR&OfBRuiDS{2T0rca#zAoH!_{UM<I4kb|fu=KzVmA{Z3^y^1Awlrkn
zz$v!PJY|(**iU+8ztixpBFAOoykqI~s!!TmWNL9${?R$APu<jhN&{K~d~3@nt!hJH
z!%Qc+OM<G?mN<_hwd6Bzy#q{@Z+?N4$W6siJmq=QYPV4pzeIhMO1-p`R6~qO3@_^b
zNpA(^2m!J*y(t-7y@tw9&`kD^BWw1uhu<F5C~d-go+#jr+V&AxUP=yS6P+4HD01S%
znfUAw-cK3i3mJoWKlQnd*g1%i0rw`ZaL2im0>9SKzY`|~PVy^0mHj}C`Q*qe9<t%`
z`$q)Cu`jf~E1rn|2pzPmewP*;sej6iE*4L+ruxGZKH7uvu!wUTe>MEJ^|F(i#YYk7
zp|SInFBMo2hxwy+ym$Xh-9P6}(w^s`{o_6RJTXChrrqKS@;Jua_VxG;?zkzXvQ$>~
zA;&*T9SnfyIEg3cuVlF~&J%P_N^y+WT%OiNP}7=hIqGt*aU;UN5G!;5)p$K5tkzp-
z#2VnaF%`O#-|>KL*Q%^G+e`L%etsmAd$}<z#{M#>0D~=Hwz4eD898sbhBtcx18(j!
ztqU<bt+2PsfD!Z!t2=vQO4$jQd6?9f5O)U!OVM6WZyh97dDCDg`5ue_S=Q&E1!ixV
zsgoo_ke7MoJ>;n7b3N}Xsc4x@v+Kjz=%S_Th6lya*o?<$p0XOBm)~nt$=g_GxAdjP
zOF9;EfX<)7oE*Dg2P-b3AD)|b?K};**b?s^Q_UygnD|x3Y^ev0>b2jbI6B_7Wv&y5
zmV+lqJ|ri%GHbXQ`Q7zm!kg3t7g>IgZ9+&5`nC{ENAe0|09u00JuByU9>&#mOhckB
zEmm*oy?)QxceSieq|O3j@o`dYvz$A{$+D3^wN4a75XLgc`JRfYArmC`>_tl;Ooi!~
zlBIUx1Z{9CUBGXs&AgT%>`s_0?m9VIl8w=(_hI5JbvLoy2qy30luGKZV_+I?BnO9n
zYEpfm9<#JF_gb`)QdsyToA~sb954I&vLMx1=%hlLd?I~=2X}%1cd?XuDYM)p2^~9!
z3z)1@o4%60-R#e4B1^;IEbz=d0ht^cjxev&X~%<tf*@A!C664Eob1c9#-d~YC7oge
z>l)aQy=jyVB$AS@my<59A*)ynfSCn|h2HE*>wGQ|*Noi^J!7Hs{6W;6yS?!zF-Kfi
zP31)E&xYs<)C1EhT)N5tQb#5$KSbtk!E$B7RAfbd@N=oIsEoQ%bpqckm}8IFS0OIz
zE%}_JYs$E354oS)xaSlt-gmC}0FV0|b^agV$H8b8G<Y1DdIUtzjIj*$oHA0L$A%B7
z>iA{Q;Wh~Q!rnOV^RpvTv1N<c35EnSWhgzlk{re*+l7+t^R*%`+2g}6*%GPd{gFBZ
zPkwoQ0R)LBP~Z|jomE8zWOc&Ll%(I2S%Ddnt$PLS1<+Sdri`U(5x<Ut`vkK#)d-%z
zA8BZ+ASx>I%lO1c;$st<;keU+oybjUi?CJTCotEY>RdZak99=#OBe);e7LjwWV{8*
ze@LIPudfBS9=q`DK+l-{nDcePG@B{Sbm7?bd19-1F*;srgg8|dC$tmN2O{M_lM@j7
z=^E^!r9A>PV{uRWD3>QP_h$VV-Q)RTX{O59pKnJ0h~at5^_@Ox&{qy6HOuYr89eEi
zr3*`U+5(@TR_&4Y9{nk}xA0-{(}bJg3H=>Y-#J9Co(>A*X-Vg{mzBOkMr&T)+y<U{
zk<I?nPJoc}+e_iRJc+ourf|ZdUFa&>f}|A~XKR1(nl+rh?7amvtSe-e1pfqT;T^3k
z)@0svS&+hY5#8cr-kna=2G#Ay&#8vrdRUbK^aZ6)@LlnrMJ}r~9P?j{C?pWo1O<@9
zBO;rkdnKTZ*2LuJ#5H$8Vj+E^h(k5i1J7F?j|ZJm2#fCfWjde&Lh)t5k8omOR&>V=
z)_&3}$}SW`97~Xve%gkWubR}>k1A~h#0A}lSYkAZQZMD<)nW+Vc|{kzQlR6>panGZ
z6hzJ_1+u{W-4%IW&H=kgD=i}s5L@=~KS?|_I@1sqjtXAECQMPwz4Jum>*T^K1!|X?
z8v-0`YrGOKrf485%2u_>EA$;O=^%(O?C5k#){E3z+B_E;J6h@bt6FC;pQ5N+-{Y51
zel989B5SduH9Omu>%fPt&2w@ZQIjx5Xz;=o<%eV006o~Z84rZ>r$P|<@tftvR`g7&
zH8WM4k@A_I;(4Neo^II7Z#gDaFB9SY0z9MglCNGsSaLP^q=CI|d{{6Mw9=`Hr+e~E
zJwzkHzb2}wru0{=Vm>`DMfsMfLHNoqO!97a@eoS*wL6V-G}{KX3)XHOWb;&{^aVA1
zQ-k#d&xUGb0x^JZ-nIw3P^%7fi8uOjJNQkD?ZCY~arGQWJ7|JmF8VzMXL&F%T=JEl
zN<R6lv0uO5dFSalEK>D@(u1G<L5kouC-g*wS8~)AJ*WcacE@jrTlBQ;Gq0?hQSQL0
zqp1l$+V2lr1-5c|*uwe6(Q)(HeFjIyX_~M)s39AQ`Lt9%yx{Sq>?}~r^TQgVveY(V
zwSD3f9@OOk$Tmf0AqqU(3Y}^1q)qEjv<jXIOgpCn;&1H_%S*Li=#o&Ft#}2N2wS!u
z_@_O3+aT+y$IN?7Nu6*QdO_*J^Sw~_pGZy-y!k&690%N>(TjHwFZW=hcfw^){k%tw
zM11KE{n%DpNC&-<PS=S0>;+|R#fNz#03J{;epoF8Lm#LOPlliHAaP?r!|p&mdq>hf
zTksAqL^%EO41*VIh991hdJtoLtkHVFXkYtj1?uN)9-V1!i->38cTFa#Yv<x;JU0Db
z>tQe9nsfe86;Y?<^SDpSxSOJ9o<m`7c{*mL9J97>DC_xZ9_PqiSB{GxmA#!sjLY%|
zJ&=Gs?|ElNT(3~}_~L;%rYwjSSx769U`vEhR{K<nd2Kh1<B3quthwL>rH0O)!MJcM
z-Wb<B)n@8O=o~$}p=zg9l6~udo~A$p?FYQ=>qL#8%b~(TocDi7;GR%4dSeVcz$v`Z
zsjk?_KGQ9cm(dE-0(7CxdS&}V)=`lNlIHm|oGHFw5Rekn&1YJ3{A{yn<n2C|x_3qQ
z$pjnR6Sz(KFI^H=$j>)Yo@@?}ox+ISxE<oJij5XZl=zG0OY@C>oZ|+gK@N9sg~h_p
zql2dW07iO}QfEHHC6eCH<Nk4kzh53S*$6sjk6G4TvSi;6{xyamSd8z&Wgz&b`N9&Q
z<AIvT@l%Q;cAaEz@NA0}+6%Jqo%c)wnr^P}HGydlvUD$al@K8J2T02Qhus&cg>MM=
zC86LssS1++EJdN`y47Cs-e4O~!^}5AHTlTx%%&rQZ^AC;OHkE-9m+*9qTmWB_DjGJ
zA+a|_dz;~>{Qmy0Rqc67B&y6SQP~A0#Zavx+ss$HECo$dbre3xxIfqiXQF83Vi=D8
zf*<w@FZBS^Z`9-MJ)#SL(?FmiO=RhURbcI56u?VgZ~IK6yA7g&lFT2I)1{h-<j<$M
zf}4o-2rdHN)CU+Fi|<0EVRO_RLzd+nswW1^FqkjvO$r#1lo{6U_JBA2^SvcvrQq`E
z$@Jl0a$2qwoF$EK0tJ_6BYn!+pBz}@nmXBXApG5*4*J(%oeb5fa|<vo-`U?|v2m~a
zSm&P%U;3NVxCZ!=Y<?No&kd&uH00$L_vTdZf)g7vUk%O8*&pY(L+;LZT(iF}W_jJ&
z32$e+owlKC7@hO7nbvb(pko9*X?Y*lqq%=P*b(gf6s>@DsA)P~`13Cb;X4B|k;7m>
zK&jCGZBCVty}gUG%io5qp{1R&i=mUt|4BO0)ZS7<;u~xNuR<BHVFGgiLCYSIQ<lOl
zV1*8Cz)CVm<1UGAU=R~YtDr?aOQW~^!2P|M-p9@mR_`Ob_rdUc*?+;U&Lo)QVFl4W
zGn2=8cDmR2>wV6i0k|iS(DcnwU5vqutcSr+O^oKmWP7M52AuZ6P%;dX342Q8VCc(>
zcRwloStAuGosp~<*&1cl)W$%05b{~Vfg}E{VI+L)`AuO|{7qw!@>${CNm~pv2}KFS
zM>(r-V+n+}@GcC<aa4v0IF@O~fTnYry?J%nHka%>BU9xWer55kj|lBrmyU)AkEPay
z)wYr<S2SPi;+wy@$X#}6cC$rOjg8c<I&G##5_p$ZALb0vcI0Ill&z{-j2ow&Zbm}B
z3uPu|){;Bh<*q_4i=<_l5re3k_;d!&uv5oR<416{t_qz{J}Z1S{w7OT*3763+lT~~
zgFM!BTwVRBl**?=m;w(8@C<n)J~HCW^VIY%8&!BNIRwVmg63je7k85lgZ%b_ACqTo
zs$F?lS?B4-5ZP8c+tRqye(Cx`jEc+*_Jpn(mx-4Ux@VOM{f&j3tIE^`C8V~hS1xu5
z5(e0^WlO@5*{oC(*QrW@+5yRSa1c=)l?P-yn2SyVH?UNt*iVE-6gPB>_2fH|z_=KY
zU_`+Tloxa#7->Na7fP=)9MSD6(I=3jaX$08M!@(%!2IJfYHidNl}D5?u<YsK$CkGW
zG_*Jj|In$ZNhs@l=vu37+#xKu{vi$c+#TD!(@;FdP`p?e0jj6;AO}p}h`Y+wBTzNh
z&?@s)jRA<6`E*Vm3{DyTa^)2}>}EIZnGzI+F9hao4Fp>;K+ZD7)|O|C4-68rDHs`i
z?w&9FB{<;cpZAut*c?zA!C$R2&#Kfe$^ad&9ZZTTnpTB|7*);D@upgmwGplMvP^t|
z$xT}2?}jJ>YI)B3qzy!sXl#{Rhek*=QeB5Aj-aHjx@#?&Qge5z%;t{b!@gG98k*z%
z=IOl3`%fO>dZ@L6rLMbgNTHRP@+gBqtw!?gI!CkW3z;|7*rQ2NZmZ2KM+5#s9-nH~
z81KEQK{SyAtHgl5D0Zdbl4Pi^Je@gQLx9eTG#N>6(F24|-gh&_jtW&V3-(G`_z!|D
ztI`)_<ZUK8<|-l$(s(wgJkh#yAJDb4KdXq}k3aV5Vn;7qq8DlBukg9U?t(B}&x#jL
zp?K!yiw|)Ofa;fI;!%m44#WRY@I;=>6eb!k*X9f+Bl(AC+{K(6%nV@)1g408G2u`Q
zqmBbJ#jk-B=}#OjhH&gZ>r-5ghLnTL-t%Tr`T*zuK=B`Bk@-lQ!9>tPC?A7HEpW(f
zxgBJzGlJWBnwb|S1nNbY_QaF|rqB;%`t@Uv>;pOIYDhR{G3o<PIHV(*_4NS4H`QZ8
z9o6nowh4zO!Ohh^(JqIKL~@sc;YnU$e1}Q&X`#m@YIV4w{~GJs(}gy^C+8(5+ScfG
z?hM}&)!wPfQ|BJ?;p`K-FW`0UwCHZC-#@pA=Ad7T%qQr^`03M8Ezk`H76!Fs2Y}oo
zc<DIFSI#YK7!2kfH16S;dBGG(#l0r;YmdA(oIjxMh)*jLZ&y<)El1=oXwU6%`yKJ0
z&7s6<JK56TCMgyW5a9orVk+ukYV7)-|Cpt!dm7-WV*inCny_PE3b9LSqoSfEw_ThO
zo!Utwl~l$VU$I%tDq5YmVbxr}3fb5ofPw)4sEhDO&_qOQ+Xc@dA_9sqMsROG`0ocn
z?eAV^WZ0XxY~lT{vR`{&dvD)-$Gks&IU@?d81$k%9MSo0BM)c?1AgZEZKI1|BR~}H
z+i7-=#kYey)Dzkx9^!kLBcXRNL`dO19q9_H92tOf?a>W+n{bj1c^^N0n0WLz_z(pk
zPQD5^Js4*Ck_BMD?=lRDgT7_>5GGs?F;77-((FN+dH@2#k9jDE#=bnr0>nq6#zMYO
z1#{x$qjKY?u9TTST!8YC3FF@GL+<brb3aU8GzIuEhc`H}29h7Xe1P<!_M?G)r~()u
z?^1#KsHf!L?^}twLar|#zQW+-RS&b@(j?y72=}0iF!#{O_h1h{-U2gThKT$^2qEuL
zKUo9vsVepsaq+Qlu5s|s@$uIAxVPKAEj%15%sotG1S@WtZR=MPmz7ZQ6{loMDA=hq
z7Hvxw)6$yUEGA;=3{3L^>SitC#f8346i&z4=T4$}X3pAXcW`HUt=(N(^nX6+_6m0w
zlLim*g`)8BfFA}el`++3s|m@|Xq;r^HKI(!6>f9S)NAc;W=Sl5Q-`w{x<Jt(+$>F_
z`QlG&EMe17PKp&eduhp!v^r)t@|u;rkWrx3T(V3@#z8AbQ$EM}mWfd`8<#&`w|O#`
znUTk!A+B68$>6wT5;V7w$;5?u{`fgE^R9-b?#au?_wlR|HdryZW;=YY;i^wkifB?c
z>gp^KC(Rq1k+xl!30=4&8aUG$MqKDxH&6(YGs!`z1byiPev01Oiga%5(I6ZsWayfA
zo%hA$yD2(mE=z&cJ37MEWwW_l&ZfMVB*DTn#zJDUECb*y^vo?LD%Hj>9_mG@X-Q-<
zhP~HYhdzOm__%i--CJ($pj*UZOP)U9^@^4&Wtv$$;$efR3ks06Oe@XiDz_nPn`KZI
z6!j6*P+goq6wVW|)k4b((k4nYLcZ8kkwcw(D$6LIeV`EV`&l7>mWGKK^fR@GR%L$i
zQ%GsGek%dBTRNM8uZtWld6|ZeB$Kvl%@hmcda3M#?OuWfoZNA~JQG!<q$~mfC(%KK
z+JZAr2)y-3^cP{VSajB4jKg{xw(?VF(p_hwLC+dHq3w2;(My$GJ{My_WQucCj&@B+
zN1yl<+3Cl1XLM3abwx!$rGBE}T4XbfI~8E-GNQ&98@p^JU!r`Xecy)BYAr_jPb>KI
z8vO%$&G(;FDa;<Kx`NJtJ>o5$Cf`Eg>WpEA$}SDr@!fh8iHbKizaeg22M^BVCKP3_
zx(4)?F7{B&knq>}42PvG7iCVn1Q~2KjlH==OY<4paU8t#o3k-{Ro>XW$icm4D@;v3
zYPTa(>d^-2ky4MwsPz3(YJ`0$bSf<B?*IWM&28m+T`ev3drIEoL)Q+;k$h2Ig0TcM
z*{Zi_hfh`Z%bx57$=GxYR+iF3`?#2FRbCpKi`2+-Kye`t&NqGcpYbgRus_P|-{iP#
zqF$_tSM1Ca9kFRoO?Q1H16iXf@HX88&-UnPZ@&qVKlORb4?Snm1`OJxPFrtEus(mk
z`#5U1M8!1FGfbb>$&g^DFTR*h|6-)kR7EQd$=p!{%1{oJ!sUCQzn!0Hxn5wtwQ^T7
zM!%AbFwo~IR7_RkWkD44vsb@+b6kqL1&xj+$B#Ruk8Q{+qIP2I6ys<O%Z7=i({ZM=
zg|V*m_?``FmAyVll;o=oe<e?vxa%Nbf2J~KKre$QT_GTlx`6ZMOm>q^wwtuB^@Ue{
zvK%>8p9Jf5LT`upp6Y$R=rqET8>y!TE*-1~Q!Q13xkG3CjH;rRPND8ss->m`NTa(T
zU>SCI&f{4#`*ivZC}!ua8XMW=K%mX!cwT7)Q+g#6c?Brkyp|Zs-az0z)#Q0yxi9-f
zAB!q)(i(T_URh>ur>Z|7&~W8U^?J-b?<&c~19tl^qjs=V^mFNZD$?0c1!P02%l5g`
z4^4$_=&PzIbYnUdLQ>urdS)-8Kz4O_4%B{UXba|Tre?S;gD>d~Za9W?^B^E|eY3GM
zTjG2;$&bQBMUGOqRvwW%5k4-YH|0!`y{>9|{9HR;FP7^Y@dz-aZH7CX?67)?RuSAP
zvU6@<82_@we(Y>~2QM8~v>)6wnllD3_bhdjw=zq?Y|D!}_cS~Hg4NVYczBVP;${(E
z)p^RbI8{xA2SJm@L1{}J^D|_MVPe*PDc-7!8Q~|3hf!{nZds3xaVw?c35XTl%Ll(X
zLi_%x1w#_yYctMJNl}4bO(wXXr;&*FI)hl`;eDDYarZh?mh2xFt{0WCbDI@*>fF-b
zy?sev<L_6k2nch`i%7)z!6gq&b6OBHQ)ohqLY*6Gk6>!t46x4(^&d^cJ=K_H`N856
zH<hEjZhV=LX<?{pKtjm_+&{B|F+t*hsWx3`M2q&s_cyp)lz0-XXx4bhIEzJ7RS#8)
zt3_KB!{X+(+R|AwIjIQk>BMWDbjt%AP1=}XsG{l0E>Pl)E=pV)hLF&OE23KR#B5^V
zxKi3#TlyloCPH@bMVo5UwwD*8KTH()VbC;lE@)aitg3BTQ*v2T@>m-hxk+JE=Z+}n
zj)-MD#x}RDYFam~Wg!+C7SDx|9u6#!I4pmdEj+A$xfsLW4DxB5f;6H_bJ+#NU#@WC
zw{iw63ZPOR(AMPyL(P)6BKNL~aIy~#dv*YyDvME;>I8T@5;vW-0rLjWZ$}?@z@;k_
z2nwMnv!^t(S48n8!%;VygV<A@`d~YyRE&Dcz2HD=SQ9GRc!NB<o$v-^(QbAw{)C%6
zY{^UuH3+k@)vo*^sc3OwqrV4hS!gYadFP9zu?Ur%9J9~*P?LLg^M*%S7cP9(wBZaY
zb>_^~?DoSjpFW(%)^b%dM1WU3b}KuJs8w<m>7ee7V&)Q^W8OIa1uwOSH){rxiwd19
z4X<efXM2bQZR=L~Xmjz&djXQ(l^~3fi?$$&yz^CCNM|bdf?9Q!!O+5=B|0ak)LN@)
z;|qnEYH&)d^0IYfvqhEH8ll`$AChL~MAeuU3W4DV4Z1Rf^xWKWL~EaH9CqBBuBRhw
zKe7k)b!lF7HNyXJYw9X-2mXSq11EK7b=96d4uT{2F1}xMFJ(l0pv@M(%LL-%=ns3{
z8`9q=423Y>9_y(sR9vMXKFU4XN{<<m3Z~p82)?4GXc)1fGG-5YfB`zhzFh4j+B-Qb
za8BOp!By9!>ptC;CD3=h{oNF(4{bV7S^GUGmwF$<v)@%UpJ~1Qh=23W%%$(~Mm=}X
zw0&Uhm>VsbBqp5>-O9ZQ$^Ls&>mu_d_!ZM+k8SutEA7s;6C}kcgP|KqPxJ}h+l`M@
z$!JdRe=zorQIY^#x^{Khw$WwVwrzCTwq04aZQHhO+je!S3%Admx!*nK%>8D~uUwfK
zKO!^tj(FakJKhLdeXx!*-IY-A<^=lr^}&9?Rkuz%EKnqBaLZ9V7kbG{iaurmy9ei5
zCAuJ6Q&gR#av@<!OLi_MpBIzzvyt6V&2X}7J=p`MoT*c>PGcR7&H8EiPfT9d4*Q}f
zs7W<*<&B7F@LRWynC4t-MuR|SV3LNcCQ(;9{?<U`Jsa87^;Yj-kde_$%19P%bPX+&
z7m7Sg3^k>}n%LzEuBY(L?<IZqgM6k|q}aEs3+LKWVBDK$!i~7a?Y#>%^TNB`FaCc8
z<6!Kf%7(vBh5mvu)qi(z{6F#dAGL!2Y{k)la7P_Q`+|_$ShQ5-fGQeH0)bhIoAHmX
z??co?CX7SOGYzom%0fTCJ6GGfRy;^CEL{s<l&DYS;FUW-&Eg<mkC44WC6{yayq!Mp
z=6*ACbK%;i75deKFn!(S@!9Qh3n$O_cvlFt5*ba^vQLMGbH~))r9)S%a3_TZhOFbS
zPRVgNTKVZ7z16KYd}-fG@bY@^31+9DNLD{_C+6W^8^OLm4ZTxPu<)Z-br`-&_QAVT
zXNM@&t)dO#R_V?b?Dqc97s|6X;@CYm@TF2C1ffg=&<KsMph(ib6^cOh8b^RoQ8pZ^
zTEs}yOLqJar-T1&G!YwHc6W%>?x)hviAFGNM1?;(s^X2Ct8g#LlfS17%~x&6oTGA&
z<-HO+E15C-=N=5~S5oe;gi!hML3(Mizp#upepc!0E!)3ZOzSp&jN`jS=hu5a+N$D>
zv#WTg%ilvD-dlSB@tUvWTXZn`8Xl2*U<U15Q-IKmShnGj*W6usXzyn?8Zg-D*})C}
za&>umwN8zA##NF#H^|7#hkVnFJpVd|9+1GsoYVBw#+o;(1Q4Kz?dmS9ZEmbA<Q*&>
z5MAHhU7t@4pvwfCCZXEGjux-B0fxD}fB^NjIbkSHb`d=s*;!gcBAG8G2**;AWG)y5
ze-cr-(aoF1jwS<JaZL}8zmpImh{4)Vg!1v;k_dL&*c3EdtrkCInP4CJ6+r3|`XJj<
zd>M}PP<h9JuAn>9`8!ykJP3((kh_2}sI>SHDlt@TNkS^jKY>BEl2>YLz=1cO<+Ywm
zdsc!5+m?BB<mt7J#WgotSWFa&**7riXTM21Xm@F13S$dB300)vCJUAa#Yr2Q$p??f
zh9jWyEKDzF%0L=}^SQXnoQ4M^)s?I3z5I&KDasXnWGWu1{7O_$@vH$sQvF1TOAaeO
z$ppD~1jf&vEydYuv^<Q_MlOVpC+iX<Alap{kkN}Aq>{@JH(LEDZ}oJ<F}_l^CF-Gr
zhec3t5>J1tZr~Gw%S(Qg_ESa7;NaCrM*A&W5(`7MV*!m>|7QZ5*l|--R;BxZp#2Sq
zswAc)b8;AFwd4Wjds^Q?lx_C?ebTYNWCfn2sL>!qR2ULoE0a0fA8T6nC0!2LhpAmY
z`hs>xq3h;p`<uyxE|^UkFv~XZRZGl%T5Q`9S?rj7GPOb&-Jfv1LyOL;HQZRNU&-7>
zvXq8w(M*&qAJDyOcQ|mp!?$5hI(d8URF-pQIN!0<W&1C$K>+>(dFZdIefn4GM9UMQ
z>xIO^?e{i7@BS_JSAd_T!~r~9>Af`^`i;sRJ>2(*A83kaTdnfSu|^ce%wgR&4_0jY
zJA;+KlcUn$qeJG?0dwOvn{2&&tC)78q)`+aE7ASeWC)!=HN=Bzm4##^4py$7bZa!4
z5RHC?Nh!p%3q_{cM1gUq0urArYM78LMO4|HGOJ?nriNIJK^qDy@bLOiA++HHIivP8
z`Dk^Ka55>;bm9rtdI?Ze#r$xodJQCL7DdvE^Cr$4>QCN8dI%*4YA#b__+o59QJUo;
zQKetIiW%kMCWh^OEo{8_?A3F1f^JcaNJ8;xIWjSejroP9#77l4hNqBtvS~*7keORZ
zycWTht3RzW&5A8%<Bi0I7KWhfm84)T43kkYU^m&@Dfe}bHTkq?=}gUEGKg?Uj|zfI
zDnV5xhC?Zf7b=Ua3dE}BhqM%_>%w`qv``{8hsly~*@@>16^%GhqjN+38i_Ah6l1M4
zb9g6UNLEctB-l5F7x^5HS*49|Q0L3ST?)ci72|9)P*V5UM5|I?4$-;xyM{%S?BcG8
z(3$0*NA1EMv7cnvqcb|*-&l5p7MEWfXYcjl(RmkLoMRf64w>ljmlLbQ<CoHqTIq_k
z0JT|AF=FCMP<mCY9wzL&nClPFSLH@MEABC1n#Qj4M%37hRaZ3{yxa8;5MaaEMxZqr
z;)P=e0~2k<d}j2aWl76am3nz}7^x#QJ$Dp>CLS0NPTZZ!)vjK0h%M*UL$L^x9*dos
z$MQ6d*VE^oZ}oThq8P{Ul)<{}<VLk>jN9-$@@A^O+Wv-XYI8)PT@543!Hdy6vt1n_
zw5JD;o!paPaQHM%owsyk3NrAbXj4-#@_;uF6SJnAJsW4He2T_Y+NHYZ3rFK6<Pmq7
z)IurZ@t|p!N9e*;26b+JrHo%}AU28DL-p}1n%0O_FxMrI8JfI45Q$N`#Fp9crw0mG
z5$%k){9~=D%nA4FDWfhYNgoxnZX?j*a=Pi|?9A-kw5?W?Pepq-nq@SJ)f@=Qa%0Qu
zGZ#3rY2?{n91NL~r6?^sV`T=t5>bbgykdT|Gh}YqmnrW-BKky_i&&%7Jb?~lK_k?0
zk-X;D+{WZ_tQWzT0y|}Tx1w%2_uHpYj>|4Nr%GD)GJ<^5p?7Z{vuZs9K?Ed7;pq(~
zEK}KqjUe%xj}MmIL4!H$+uuCfBWc#ZRX&BfnDHF1KN#K!3kSEp7w)j_-DW(uUDHqC
z${j}XZ}dNb)C@pce%uj-{eX28>B;B>qd4%Tu&Q<RW3c))@R?ubLrEFzy<*=T6UT7W
z28YTbBfz6yh<l=C4x+y2S(6b2geU&09SjKw7d3PM97I5Qc_YJgV3XI^Wk%ZFqCx}6
z6xI%4-WL?WgL(qR_XxBwDK79Hz?ODcA{OUN`$&;>sQQDHDM(B_qy_5)7U-bgu@@kl
zP~{2=M4_mH(dF_JC?Xd%62w&F$d_rq@_H?h1=}?@l$z)?Si&Q<mhv_jLQI7F3n*z$
zu{9XOlTjdL4VD$=_yd+v+T5X8kDAG%o0(H?#r!X^xjboYs*49N6hpvi#7XFexvqqm
zpBHV^jd;5ok-+my>!4Z<nQg^k^a86nf~fB?wQO#qx$%j26uG@)A2>OsV$t`BMBYe+
z9|#Fj3N<7+Uk<^C!kP(2837#KzP#PG3DQKII@0FA&?e0e6nG)I3vBoEDa5VJOP8Q>
zOvI(uoWR>3CzUgB&cR*icdaQsSwhze!g;p9zZ3I<Ds>c$(9K7PidA6E#lg7F67X6S
zrE%5T;-&h&xJ+@1ComeQ@0i#dBgSjy-`v>9d$}4PD%YN2#tu$kBh@f!C)7BiT|TU!
zSs(^1beIBuw_kNMuBn==-T%I6=uE9i^t`R<1F*1_I9On(7S~(M`cRx_44mYTK<PNd
zFlhm6FRXbYRFE>*7vCaT<7lnTafe@{xUX=kr>{WixU8h8%I)ghST+PQ`RfgULtYD$
zzNd2q$rMz2_#v2fsgK8PN1Vp>WJx~i@Wk5pdee4x@J%D4-?{mBfNw0A?=IefN?H4G
z;gY&CxVX8pDkbVh2h6azy47ZmtdTITTpuf{FRr6|gmwh>IC)()c6Xieo{ssDw#@Y}
zjN3fZ*JY3IPTy`n*BZ@&zoUFm6`YXL{7{uCN|qVME^#99!6`|t)n965uyJEHcwx{i
zj)qH`laRJ6y>5_dJ^*tk+NXx{K}ys>Y)r#<ug5F=d1HUQV^&J{xrRs~Wwg6p=A4k6
z`DuY0$CoQ|D|3{6)kHxQQY`bG4y$4C3uk<LAe-)Gn(k$R@+sZ|ic}_#pFP%g>Okqj
z5vj`(`Lg)m{~=qSL2}On2Lft>|Nl3K`j6K0|Kqxrt#0Lpvy8UAime&JBZ>Rthhiuw
z10nUA6fD$FIUy8oe?dkfxq}f|?U4n-Smqo>aT4-;guJc+k~!ewG&cf7b7>r{Dvlz!
zSl8;BW#21tUogKs6M|^t$%X^6-&%YxJItp!jklbC_?~9Jy&duU#6EnmIvg~H+(f+9
zhh9W@2nWLQA&iiWjlzgA0<eT(jhNgOJl`lrikn54i4MXbwTFyh3+)T+O%&q#UkdMr
zIxvG`6U<9C>`_OD_S#?xEC&(p2H8F!`O)v~QDej2=P`W)M-AO|4x$diDRQC?D9>{c
z@0+Il$i$jv#qM-K$w}Px@_i=ixNX?2)(X}3<tEwC)QriZC`oMEEwElFo5E#hsNO+R
zO6@gmjx>!(cOA1qa(LOt89$!_e1fu?q^25b9`lmvJpgNz&L%qaxiem3Gi;0EyoCx3
z-A@v8&#Re^z6Fd^cWv{X7LWE8N<{dejd0|-_$2{}r@?A|TU4&L3TNi%CUcbU0Gr5d
zw#oVrJm^^RR3@FYVAH}4EqYJINJTe1mAUtA+{PXzBhC{A3&*LaXB;D?P<OEj$GJNi
zEcN7!Dy1LL?|Fv|fi|d-WUQ++^=UKFI;~=6G%8*VmGwQ0ehm!jp9*pjTZS%FI{27O
ze_TE1*xR93Q641+xeYx7-W*3+oQ8kAlo@r3$q7ayr{AJ8og`T#(u=I<osta(LZi>R
z_=GIOsJnM5Xdia~C^ylCc8Dlk2_`eZ#;q6wF(6x7YNUK`aWWYikuBEilHFi?kLE9D
zhQVDN#+I$eA7w`6UznAFi!|2^T8~Vo_3u4ddwC5<kZ)WYTC|M~UednWCY|<5xqJZ_
zF4p~OcsO;6;<aJg_LVWRYgLDATQ!9U^z-UI6nOMTtpmx?!Rx9GS6S!hubg`G_b^=(
zp1<3~on<E55Ngle@$Amrm4~zoyl`$Qg1w*tr<bqAWqu*Qn6;`6ojc@sKFI>zT)IM)
zxpqb&kUrE#Z|}VD2o4aqzQPufyo(OyU!6b+F4K_sO|DK281y$v=;b7E$d-P`EN){>
ziP@`-l5=46|8o97J56r~nGsgYCv5rI$F*C$U-~LDdip9fx;u32Pt##UiJvGN&8ni&
zXp98q=sSUHfm+jJj~h7cS+buAa+EWWQUW2mNZVs>7n0C0ntCehS4&g}d?3Ps&qOvY
zwlPCsda$|gdm+ch$%<ZH(X}^Jb_-4wa+x?SS3PoAI!y(?B&8lO3Abg529iY`?sTd#
z-z?qJzIr#Bj!BZq8p&hEepfWD^8mGBjP=-VISrLQ^+t$8D)D%=8pzVE#AM6&YkVZ|
zO11SvX<b@p4olgnQ|1C~`oh5;-?3I;$Mrl8!V0J17MNTAD=hltq{Au^PJKQw3c7|u
zQoP{W&4YyfPLN7B$Y=5!u+89cpWkDc52&xcDDF?>TVMWQ3a4Lj^oqh6CVIrwHJ2+c
z@9$F8cl`w|Q*&Puxz+V!8{#4d*QNFNV^FM?U{-kZ=iE&%r1|fu_B1#xm^w}1r_Wux
z6i@Y5T}SL=SeTe0qQ|nbx)_9Ud_Lg?a~r$VPB{HdZ5xk4RV_Wo<dhek;$zXVQ|GX6
zpS6+o&GpSlbdj~4G%bFR<PHyT+VUH$U?nIUa4jmN96^p`^K3z@3s_=;`35j<3T;k;
zC~t^jz4P5Ly8?m-jssaCYEQd+q!Q94?NdbFq<2hO6B_Q&wR~oC7%@+*$wO+22@MZG
zESjaTNma&3#&46M()tW&(uuu6lg73WX9ngkY~l?{^ZaYP#WanDZ#1W`(2hwBUSd8o
z2a{z6Uo?K@;^g=|RV;Og-Cm-Oo5nN9d~W*|(;|Q=`YP=GqE<+?mJm0LUd7@XUAGk)
zpRlu48_|eMR6L~9j~_{vaU$;MtFc+{x23AREN3)_;Nc_RE1GI1`I(u(WwZf>?o5~f
z>`yg3L{oL$ueLs%wBBkh(k8Y@RHrWApZVD}bwU+f5z9&45(&cEV+FA7PHEi`V_7K1
z(~=J-!fMYv)!zZxuk5b-)K8Th;3^Qi2v!cM9e6>Oz%ONoV`YhJg?jyQp4mJoC0B>F
zc_>%gk|h8RC*B)F`Y8JG^iD=d**2wPMJ3sNd|y?LD%X8ILkoj0KLZ2+V!^3uTkJ1Z
zPk2mB@6KG`7sWzF=B=JY-xmm-BRxg59DuUPmbWJqacCvb$(90s*&4x+MDZs&ylPMM
z!KMt*t5ZBTc5-j+znxjOB(#ic`T+!_1_A`c@jp1T{8Prx$iP~}!pYgu!qDaa8tf!1
zX-ne>qJGVoZZA7mIyARzXg7I;SzT@%XiEzsgAz4`pc8mg$RrTSb*#fB%0_-m^()-v
z^Y;;`@-PDy$`HNR(w+X$Ijv3hV)y}d4Oenb=~qJ{$jd%W;m-PWJt>mC+OUqrs^l{4
zo<-ymt7&%CBER`=RZz>`Js7c;T_Lhzr{4_W(QbrC`B}{0O5^z<z1{EV6M9XHSdMrQ
zs8l?}26taP-Am4oTR+C_tu(a!q+wB^;)nB+E$@W_M;;JcK_1Van>acwu!=%Px2c_Z
zZnlJXN-hrGBa|(!Aq_0{Fm|hGo}fkc)n1E#`zGzoQF3`axryKz)n>&a|J9gpJAU~y
z3vr#T4M>y+5>cPG57!jrHSKr3pu3x2?A3^tq{v1%KYM3GG77Y6<HQ3CTh(Lk{yo34
zfH{vnDz>mdxiQTKyd5&aTh{3nH*T9Zy|^}s!V`|%lV`BdlPTy+)FnJRO=!B})RM^(
z0u7O1IJJqX5e@oVP;^v^5lNwK6TX2-722b$_pHb%Mb;O|i?yQmz@DeRjD)*4`C2y=
zUpvUvUO2D%I_>NAP&UQ~atH9gMnZy-6b=?75Rfzi5D?LSZ@&7UmI~_OeyC<xzNU?x
z%-pb?=*SuraV2opH^k5hO-n!HTsK+zX`pl!92&USX||`V%}k+GY`QCc+cx8?7U`jB
z$ELJcQ_LNxs_<x4t7(5=d|)h{W^P|0sZG(p#k~C4IrPds^*WtQ_RIAH>vR23HZcmR
z1L2(CqQ}-YIi#>xJ#vs4DS!qWRn6)Hq2dchh&&-NoDHJF9}qY3mKhmUWjREl%D9t6
zLpW46d|QOZSG>paR%6LkzW4AJ9LBgOo#(+WxE@9I)*M#9Ym2I-dd-NKe)R;}nHA{_
zv@3H5-c`A$%~GjTmg%95%0f<1hR#vB!vot@z2gPjRlfrPlOKQ0k63(-k193cAvqjH
zCKQZJFENNUbs1&Eg~Gc>iLs)&YOT&P=)@Y_KYI<|@8Y&gvn4C<Orgzp_+C1~Q~q;s
zPg3Y6C%;827$K>_YndKXnRyeHGmQgBECp35Rx&#BEQ=RD3V&T_uH6`{zamu%r?t*u
zyM7+fR9)II(pOM@dgh?NrHz{~H{_wlF{N=5+@mi68B4Gndk&(xErT$m%WYKBPOH;w
zGg61=>g-@OGS%kwGfJfP@KDQXRjR}E=c{-%>Nb0{nT!!}FN4(@#M62eMqKhzBXdVK
z(qqEh?TlI4sO)dt+h+9Xs^U`27dXkutjVIsmU^cC9VqOAfyM+XN{KaOT5vP$o4zNN
zDpbo6Y|KexIC>dP`C{wA{M(U@Y7rt64%-o$b=#`t<h&d192Q5z`S^PjsOd>tqY|sN
zk{lBr5AM!^I}TQy#~1^I(rDzfsSj&kTRHzrZk~a-sgHpqq5->!bu}#!cFW@sMWquu
zt>%ZC;1)-oL=W~<w{%b8UwJP4PDAditL~(eG9;9N$MC-Zm(?bpX`0peWE|t(YHrcz
z#}uSh(XPvd@lyU1Pm03;tU(#5np!G3DQVi|V(3kpQi-{^V-=Xt>m#1%;p(nz7Lf`M
z@f55%`YZFbNC&vqLtbnEV}XGRi<?nac(&WNj-Q-@Fev?DDYh@bjP$A<zS{Qd+fBXA
zTW$mkZuSrii{6qWG7vzTwa5?+g+*_{5esv4>L@49BM_~^$~IJ#A+#(#&@VdQMRSM-
zmwM*}M|pQv!6BX-8W{D<{FT(Vcz@Mhb;Ja&x8Kg>Lv9f5LvN5kgn^)sApK9&UPSh6
zyO`8SE=w0+m9&a-kXMteCV0#deFMX#v|FnFmxwTH`LB^&)(<edvDZpK@4hUY-{>Xw
z7ZLJJ|CV1BXop%xa-TJo90nEgy5qYnf^%{qcKuC%PyHg+ne#?r_DtN%rYh?ZT&04&
z<1@uM%^@wE-60iPEeL}_c_Vfuja>&mcME;#%%gU4M}>I=tRdF|K>J`G3QD`sh03Vg
zYDuwmM~(OnT2=dvtM;|3EN1_P_2kJr1;fQiwZC%xbbYSkZPbf&VA<w|awap?&ZBq?
z4C6-H#CnvvIy40?NvbH=->SYvg;LE@NBU_)3nzS~Rx^1{>b+}Rra+TY3z@CTUQu~&
z<D#}Mjgeh><kJKF0h(^}Vo&KCXJrgjRaG47vVuuPn{9OosS$ls4-Y{EA=Y`=lEO*9
zr>%)Ay%h|2@^M2-J89wLA_}EaXXfIfJ9mBss!&Sio0G9njaLj>|LgQL2NqE|k<PAM
z4L^JJx=o@goyAgu_v#v*z(uUF1%C_HY<{NgD08Z5$dK3{yvLS8-jsH<tXoqrF3NDG
z0mB*Jz%82u7yp+g=EXMi*4WFTYtQyhI1rmYJ2)r)LFZhkHfL|OWe<eGz0W=e4IiT(
z|HbbgH|vo;)}tIw?W?oCJ}<~cH#v=WE-yKv!fv~ouawYP_f^~dt{{Qd><%xc!F6EK
z=A+nRP4IYaiPYPo++q84x78gxkMtfSNCC4r;h5MQC!;l}{g|hQs~h%rxJQ%bT|lHn
zv_#JEmcw2oZa=cU9qo!&%T5)kFOqqr+8|K2XszX(TGw`$wEHT6n}W7^yQMX{7jzJ&
ze>-lSrd!chBq7WNOJ2R`u<UoI6_{oj@smPu<mkDQeMVC1PA69`1hZhCQRX=?xc`t1
zhcTC%vzkO6K#AA?VFfNKwhBLi<k!YZj4_9Pk5OmKFxOE1R=`vi>{=c#AVR6{V`w(^
z@{??qNU0A%KKIVU2C$>hUj(z33vQ*!|5VD{!1mPGEp92dayS$^yH_^9_C@NslLg!I
zo<qUzT<Qs1n8T*ZdwlZCc~)yhucJk7gC#|#Alz`n+V%l+&K{8s()x7KtP*dMHgjJB
zl6wdN`qF)RHzXz?#2NCF;bUU<cQZh9H6(G3N4X`F>TG8kn@4Q7$BEw^4Bm+W^~g^|
zd5MREZ+|6Re}z<jqcGr*H02Ss<q>AdB?Y2aIOH*@RdNk!Sf%g^YG{Q50MUxaR^DNn
z+Q)rFCCt7o#LCd$mgWkBx@UDFFh?LBhu-l`sQysHI;k{Ct4+~=-lydgj){ZEbB7`@
zuJX;fmYpIV@5uo5-b>P;k;toCO_%s~Z_8BaA>SHwCEl8Jog=tG(IwoX@6dM_aCUr6
zF+Dc1mS<6@B+9va8A1t=Ak2Xj3%n1;jX#7cX3sH)f37F8IXJzGIh`oKy~CZEyYH3}
z1g7QL@x*t5L1<4Ny*eZki71H(NQTGVyTDcMm*;g^+!?ku06yuCq^z+6knmSW?NNLK
zH?fM8iKXrEq32Yk>JgxKamWbKN=3%b-2!Exy>AHiEr0(TS713iTq^$M3HkptuKy3F
zp#4v#p#9${VgDB~>FobMZ#(6gX?e<NNmU6+*~zI%n(?XGL#5~GS!GB$S_K9cMTWX2
zriMBuCMA1UICw<{CI*&cDvF6&DOozo7Fl{JnQ_Tw*_rVpDynJf@hREnW8i<X6L9@I
zqo&m*!I{4^!T!s=n13G)T`a7PX&p_BOf2l3|7jYmvD3DLgowenT~cVEE&cm_q^(k_
zbm5-W=o;K2;52<|1ieL)&(G6WSF!6K2Q%6XX)ZEI;U19c1a&Hql{c6eGWP+|*+&mS
z&BSaWdzYn)uI43s4`%`u;|!E*Ec&z6LVsg&yyCvh(^0xu46+RGCTj+3E0E<l{natN
zE=9Y-Gq9MjeGq;(EmB_5iA(8ukSk&04e9H_;g8MTv)6>z1iTQgX;fM_sg;~tlPW)Z
zob|8V_-g$x{yZ)7>Ey&u&LdDT7x7W{USQcbkbnIS{`m$1gny+yBWsI)xqaXt!{f%D
zQh5H3R|W$DV*Ibe1r7hvB5vd?Y-eL*U~4R6VQV66XX|S6f1AaVRdnr;1yOlHU?Qno
z!fdK{=Matyoj3W?g(M*7&4ntE7KTPmuvTsKQ(=V*{RVam=vn562=-!`b~NJ@QktF&
zPIoxHZrhzscDDKb{Jy~L!$?4&uFlq25&L6);LRq#2zhYgdEkNJi2~e*f9q(Pgq=K;
z!fI{b+5?sWm-mSVwbP=LmTpjz?B1IfIa&j%f1t|7XK(!Tm+nH0xCSnq+b!I58&~ip
z4AvWNUOZD)6^&hXxle^06;0RLrhYen=iZ)?i6pC4>X5Q+<CDOSwvVK{*rw}FI!(2r
z7HCW|uXR3SwVH4e03;$waTgj|!UAg~7p&-(d1=O?UuYTk0u8M6`lkAKAsA7+&ytd{
zswhJ)IRjcKEQ}fSeCj=Zb@Z^$)sNa&o^$1ph6dJL>07WBOh7mjP*oq+MOb2X2+5Se
zh%FL8XZE_P5;Us+w)wRzInZYVm~vT77J>RBnZ_Y;fDexq!JdW)Sn47JT$74~Oiqa`
z2Qyze$jfC4!Q~@;9B~N>yE?7T`oAw2_D?Z%>2Nf?c_a`vG7F2keUYh9;WjTlS!upg
z{}d29+eIRhp3Y~L?8Md-V^eDb`XeZZ>Si7dp^r`7L^k?ELp0)QTUsK6rf{ZOF{j{<
zm>Nmv8%%sGMpzE26p49=l0)#?4&?pqA~dzJpa)ddqAy9A3g)RC6{TJFPF-K8ynJwh
zvb%q1QsqoM6bBpmDds4D#t47OEBTRCFwbzKfF~fQK6O}4zxAJ8w*C={OutNGOa6x7
z8PI=e()~v${!<7l7&topRjmJ6mko&${Kst=qTlAtS}?B19bs0&vkIu7qWvgCu4S|q
zz>>f1>3IA@k(G5i?D-z~2~2k`Kiz@H5JMq_MS{<)ZCmzis?+MmWH+UBZ>*-tE$}v7
zNNyAU>QNyq^~;OC?d2pQ)8OLz<gzLnv`C@lgHw-WB!MtDt;XqO=NLSq^LQai-SETW
z{Q{DrZwbi@P7rUiGq7FYC~t5~uiW?O54hj7>E8dAc1l7}cx8Xn?gbnOi06OuS!FGp
zoGfh3<n8~V%mp3Il${NnP5!ekovbUrsE<1OJ<HZneQBIW*u#X8)J<p<=I>7yNY5z8
z(yt$=j!>1(x~;r`zDwVAKZ5f~s3%cCazB8u7s`}VO6!CpJ(5Cp%_%?omc82azm4$n
zg3-_zk5q>g!xC9Ymn*4|(^AYtDW^pkafVsJhc{f{q(vA<8J^Y>bL}_hui;WVxq_Yr
zAh-3H+Yis+2X)pPDu*kksY~>>7^4p|R4W}6DRG2eKFMMPQYa@Ph+tpP2ZdS)1Z)$D
z8cbCwas@5gdek>pu1mc)ixT%6ng^$4ZE=(k;7M*^f)?;Rj5%V6D)=5+bm1zru5v`h
z<*7(j5A9lA7OYqO#1$KkQ$Nt?GjvoUacX33C);TO46T(+y(IKl2`T1+)-D3h{?DtQ
z!K5p+4wzK)OuNf+?QRH**n}qGWQm;xLd|AQnTk4QK!cAxfSv8qBU-Vu>8P$`OtP56
zfjnCcujd%w*|<n1&mmK-XW>CYr3bcJ!C@#k7|g}GFdXce{Vo7$l(=Bk+t+iLK}9M$
z^VIW>06^x&l|csIh{Lzg2;kHvT)}>)tDI_J+Q3U6b<u2CTLP0xv^|Yw@$NrNq;8=h
z7xWX1h?9s5i};$)g2<EX;R-0<d!KyZPZ3}Y*BGB{)(untHopOZL(;6Uhf^*dR6apN
zY}FzPY_1rn;t0k?q=(fV`bf#o`hWs1CXkuq(!pFBct$uv9*Z#jJHQ?fB&3`x>DH!A
z9-r<Shs}N*h@3RJ2yq;P0pH&a9BPC#%`vJ)n4kR^(@x+p8h5b`H4mMKS3ogl_N!Gs
z`Q{47@TxL&(OZ}x6<F4Q*nf*?vTnByr0%oDSdU$GZL4ll@37bzEKyHXbCy}06$DGf
zoP*RH=?#V20Q3PvZ9sH^`ALN88R1_upsPxj=^w7oL4P+M-v3Dk{72|3J3IbOgTL?E
z8#w;oyI`_aX5~=?QNK((Obl%D9}4xG1GVxMj425vq{52Aq3V%PV8eGxu1jDwUB_=y
zUTgctGa<b0fy2p08vT;)r(LUstSmX4cQRjkJZ?AbcAiFO>34xp@2C0@Pv9^u=j-!~
z=KTSr&1qaIsu|XbqY*KxfB@R_G5t)Ulw5xOxe42CL(FoCQO{+b8m%21#b!z-EeERs
zKExcAKNMwPp$ldbx7nZzF3%wHT+t0)-o!jeZTP~5s}3}^)-b!Rkgb{y-GKEwk?oeL
z3|iR%e3;UjjBfNCJCF9AWGPrr+AYP!cJE_}Ea*jaxj}0Z>FxM8U9LmGazum=MqZ*G
z5z>e7Dh%Z4&gV{*j#ZO7Z-b>^Id=i}{mZ1fmk4JvQSmA!V#?*8x8a12;H_^UEWoqL
zAd;YRc*Ae{ifMt369UrKj*ztyrIDV^C(9L>a$DBzWm`!+DZ&6_VEOtQqo93{Uoj^8
z+MO|WoIS8d<;%SIi#~`IhlQYIai$Wwr_*%~gBBf1RkY}X?)1%=_|Lsi8JL@n*!>2t
z0CQ~9_w0TqUZEhd19V<ZI2|bIPJ@kfV+$?BUu~e@GVr62)gV-3$`bLp<{<VshYC)j
z4<e!bL}Cv5rS<`7&p$ezk+iJ6?r*m{Qh0+H^Rr22wAY=EbBJo1dxX3u>5%9VJ@b|=
zymP;V`@|WiM&phT(~eQb9wkxVP}Mxhem1SxVk0T-{45bl;BFJfCwHtI+oPMGBo6gD
zvM9$R&WR4|Es}|{cFe!Sdnf*+V_3U*`^{{lU#givAs0HGkd&#$z{;w)FWbPAkoY@=
zc^ljrdZb)G=7Et1{=P8{#s=TWm>HEo=ttoZFJa^o;kNz{`M5W*e~tAs61WHPzf39(
z{Qrcke~R_LE4z!0iLJA!yOD|gKNVr)r=>s`QA6b4nG2g+v}~v^25y>EAy$(E!vY!F
z>Wcq3W0%CIi!d=?ShZ8N-Tm;UV3d?bqYc#DI?CDlvyJlbb^i{&2Rn@ny~bp)DY`8h
z)W>-mSjrptp6@45P>!L9<oT)MfaDqr01c7mGzC@7g>lUsCMf}TMzttDne-PEu4o%S
zH6+Tu3*H+_rFs$)9YuN!4D(85iYdp$84H1KObdUy;M7N;Of8V!8=;XjH!ttiL2OEO
z|5E}>CdHTjwqnnir&%ERyBH0$xMxbGucrNe^L=uy{6~^vu#r$m-easf(v|OY@1)3t
zQA?W$jK?R8>9N2RD4uTiZ|9uF&cz!ULA|Tbh#1mJHkV^~wcq88l?(3~#T*nyy3DYZ
zOlI3>SRUP-*E9F1?YVWl+f8-`5RDCBQ`v)4<q>dJ4vVg<eE-H9{21onqYywqp(y{u
z6-e6F&dv5emZAT6<)1d;Z4E1T)MGT?UgJbfG7vxrP=H!#Mx3z|!jH(gCZd8OfB=q6
zRMUomn+!NR^Je-w=+&^4_Vu>j9GjX~J>-UGfE2P&*OFdc!S9s<`R`|scOIYj-P~$k
zGgH^b%<Z~x{y(RgkJ-0dJx+gSZic^e{C)^<?<CiQxz*&65*4BtA<JM9X+%jrJb36?
z>*4C@l*mhBA{Yq`AYrZUmBE6!F+PPb^k@Xo?@!7&x5^y!4s3e;^j015^yZE7GO-@?
zVd@F6dl+vu_Qu&Y7`O%8^Nwu&3b;Ll==x9?h<$zKAmArF#Kcd!Gs1GI8+e8CBlqy2
zh{}C<F~Ex5Gn4uA2>k*4BK=BQ>7g=E`!fqsp{mGA<HX+z=OipRF?c;SB;Tgi;=)y4
z$O(5F$^5$UDt-k?JCgiqMPtDHx_)GYg?Yy;?cI0U)wz=_(=Sw@y;gAVVzTa?M?@DX
zQyg9YUS+5eGrV}pfmJ=#KBCPB1ss!TPHAg}#*@uON4n@WCD|vm*`b>C7(0B0Z_we~
zdf1=Q(9(8-te+Jo#_j!2uxU&a_{)u<!%f-#Qj_l2Ne`Gz_aXyatMs0bkHdqBSbp1S
zB)6x>j5Q`I<Zlg!hZQuLg<NdzqD_b<VW<I-_o}oM%q8ofmmf?+JIESti59YHJ*u4Z
zTY6jm164=b>r9>3@k?p89l)IzkAur~TPjdiSRV1-4#1UbFB#X*m*P4~v~y~`)_9d-
z&Tg?MQ`&l3yY`iCSO+p>&d*ZmsSUuSV$ppYRb5vuF4|7CGgZ)&c+1y5f>>0N^iAhB
zdJV^-d}D}Eu`mLAyWa@snpqv&()$S{HeF4R3;mPmdR!js6F&M-h7|fBY7;T%?3h_6
zmk;Jz9Olr^dFuUeZSnc!pes|M4Vx{^g<EE?XRFYz`QrU**6Q|nt`uwGv6N>*t$~8D
zP%Lz|%3O)A1mWj`udSe?(@<RMpK8@B%Umv&TMKy0O*+fVH%qG1DvMaVLZ1$Nhc9?s
zRik4KyL*ysx0GP=hgbpG+a(pTq}zp9Y%W4hOGP%(I1aouI|l2P)=0~=$a2&iLAz9K
zVC>ZH=)%x5h7toweJurayH*_VCds*+&c}IvDriHE(~Ccwci#yCRB8R3P>s+tMsod5
z?qUOv(0YB5(7vPnXB(MPZQ#q6VjYEYXDvO(Z}j^w$X|JTu~$L-`$93dpAU+6Or4*z
z?xOvoT~u|xM8h>n@nM&2zt=ztJ1X{AKSEMh!PttHv0|`S6I<{}a)*{pi9JDTCES(!
zwP`+VK2!&GL6;1ZEB26gklLO>o-G4nNLylXOP0axrzbB2fn_Hx2%kzY=zRh@4!W7l
zS(Y{|XiKdz7t0py=<mevuCz5=o~+T_Ju9HQ?Pz%NGf8gBN-I<KQn#=Gb6Pw-{@m37
zy=+KcvF-3+)_9NDv-%WRGj@zO6O_T;(!PFD4wCPCy$TTOCJh<4tc>RwHp_Kh>6K(G
zAZT~T{o)5bJZzY8i}TW_7T_5AucqT@ut?rMm7W*}jPtE77I3B*LpIE)rucWjN4~2O
zS=l*XGTK%hQWWBo`7wi8G<v)@jmdD?$=#MPc;=3ojgPRelEc`+{o8&?gmpWgxuEf9
zoN1<>?g^8bVPg1;TFlEcDJ*FK=Ah-aJku6Y=Iv-uYl_STS+TEEf4_aaX@}8|&jK_~
zc>>pJ=SEHCK2%4Y1UD%Bg)uDl4K*rGWBcKnnfq`5nH}x)AVPF)g2oZ%`r7U+@r81B
z$YkFH*9G|<M-lfTLW%+9keA~Afj<k@`#u&od2hF#fzoxI4GE!Wv5moI7+h~Zukl4F
z4g5>Y4^gEG48e=%IfDUa3Tz<{=8LFB=8vcY^A~fdY9f_T)VcRRcSJ6e<IIP6erWPU
zP~Bs)MI^RKWeHWg<3=AqJt4`GPiXKx8xrgZTDyfq)E^h)54D8ygjLg%Ts|KvW8sj-
z_V9B>M}*c{z)#p4o1A%6VbewDgs|Adt54-U43Ah;$q|S@#6r>8WesN_!^Y<|mom4m
zjo~B83nI%W{w}T8%o0p>NAEtUatm_ld7grMzqf#mvjK*%chWyZ)RaGDvy_x}$5u@&
zGxcfIAZG|qcGBRVn%TDJQvXfW)1zPUs4(o5!!?Y7T86?y3NFRPQ=Di1DwQ)eMrqdN
zP8rFcwckr>Q{?WCD=CL=ay2HoWTJWIRo#)ds&@B<%l59t{`<|EpkUqwo8Z}hHbkz-
z&ewzsSRE~<k7gUiE7SBINlja{Z#mGk*6JN6vsBUP;?wWV(2_ncC@;ZjjVF{#YV=)V
zkfnge20J>QjKEYVutczn_N&JQ-9{6dtq85@<xw`Q=5XoH_fLf!gaH>+@Guw+61|eD
zZi#w7wARQ~1|q#thkJ0c;Y@dpu8_n78y)1-yBv3jZ=_o#ny(wquE;IFEJxS0h62<V
zeH7ba!GuqIuzhAdz;_VU@M!#FP@nTW=BwrwxFS@AI4xwoY{O4@!>0Q3b}kiNHV_9>
z!8C&Vrkne7Ce89a#O2nzJPic{=mWtJ%DEtDW&2Qd1K4Q&rAr7v={^JB1*s-y%RXjJ
zNL1|N3kuN}&K0JK50q^wJ=LIw{BCW)w*@y~ROsRR-&8uT6?*;jUuN6<tJ2y3=NjeT
z)k(6djr^hls;}+pydoE-o$?)+2rQ1Bi9aDMQkEe)217d0y%E+l&AHZs>rn1K!hYnh
zJ_*Cut61WkO*W@GseNIuS>995+4h&NCchfrPjH34m?)ML<EIC8gcDMlF~oWbBdAGa
zJt>X&_=7*FdXgH4cP>z(P&mkX%+5BLDf>1|KONtE!0U|(E?|Ao1{d5iqd~Ucs_@c^
zu*%k0r?*ydgKmY3&wN;Q08=~lW@~EWwzyU?C+qM*N-Z?ol<66l7r`18YjV2P+#C7j
zm8^>jP@8jA!uThNCv6?f9*Koxgv%dzVDE9AA%u4{BP0(d2TeZheGEvqbAj{=x;Wr3
z*k!mD<QbNhYP!{)F$T+#0nvoY?QDlT{qcH_5!u+j(EFPME){blv|vyw@UPDGn$)Ns
z%Vf8}#%DFyF4B(~JcY^Mc+KZnCGWMcIQN<xKP}rW*|RfxjP6>-T!V8@m!O%>)bGHx
zkz26TZr6|nQ#LcHacuTJl#zF+DE9GOj;Dnft%m_L7BzY;I@^wLvmEo>MzO<$s8M^o
zgYG&j9JWdM_P6bAuJw72u)>PPh3K(%FjTs_FM)(CWuNWd+BhmMI|;2@r1}P!wy|~@
z&L#eIf<b~7v#JGG^Kj}@;?cv+^U$X?%8B$w0X=rzEId9>E~rFzDTUiW*D6{THE~&d
zp?5)`KZ2fa4y0T|h!T>4{0(?Oa|Ngr&pxup5}InJvWOgh+{18-Kah9O5na!?maPoK
z6utI%*^2N4d2d9lM1o>4Qp{z8_Q!VMGK4C&KS9QRCRXi1Np3xI<`_nKm!26O{tQpI
z;o5Gzb0!!U>XMM3)hRGb$zi4_jaSD-@UPalkU`{pES5|NhJD2h8M11EHki?Ho@w}z
zCz|$i0Cyc_?9Z#k)axY;{v4N}hm101L()1%6LBJOv=o1X;=5qE#_-v%f6b61!)5aQ
zzZqitm!tXrCmEt@YxUnybhqlH(qA3V%RBzlfJp!n@jfJsVjK~2Kc6^^xVTsqRV$=H
zfAy#G;h8ZYLni6h-7g&pv{)((U;ppDk=21{9QKa7F5Yx#Bq36V{ga)W&6lhmpPT8U
z&)e2ppd$xuLD)lRE{1u*$}EP&furI6q(F-)5eL=?D_F<%!yNo!T;UHSx5<u9GGN#X
zkj<5ClgQLb&vXOBVTb6f{fC0$Q|Od*ZC5E$TMTs>?b-vei@ir!q8n`3@no|PuvyJ5
zHb<)*s||3xVVF=2z<%KrpL~5xE@3>_B3rj8IImAuJ*S}8u-OXMz@%J!#3edqW%5GF
z4c|#-3Z32&YFqP+uJToo{+gF%f&_^C)oIJ)f^XY#ddz2P7HyI}a$3%=$=QyNo}Od0
zlw>Qf5_|S~UY(IL;IjH+b0;Criz(ZpRX)OqU}481&vrA4QSXq%abl;znbD9Pv+wSL
zpQX;jb;quuiI-AFFOAZm1WQco$KvElR)qH4ZF<3Hxe+JIK{S=;Jo!{tgzZn2C&F?e
z!PE!?Sh4!N12Xi&wqb^s*~NZ_Wz<cerA5LN8*$_JeKw2;1D0(|W<Unq4`Fh8^jljm
zx?iViA<v)DBh5dS>!}$<2nOKaH2`s_aQUiAO=B-hqz_0E1wJhGpH0;BbTU1^j3DBg
z>Uo2kuJ8voUh$9cxZ>i7GXrIqzmS;zfQI;pvHuC=dqyiglc_}32QmZlBc(I`lG34k
zqgIp&D=>4QYvYpEGnU+6ZT2E29_V@Nvi!}mXTlNN50nlQ*U%C>mPxXA>!RNd-Xk!f
z((iOsoY=?jZC{b0;1wSg`4yRldFyW)?>K}8Ws|zJA!<&b==eZXNUX6YKeS%kk$|kK
zb|FDe2cd&gM0g&V#+HJ|546dtv<yMOuRL9@iZ+-maEd7gl5HgMhbvNb<TfgpF_$({
z?qLu$+z8!L<HKm?fJN0KoCn#^+SGx!>f_%OD6!|bRst9hP&(XyxmV)fvPb@(iUHYb
z+D?mVh+j#Vll7v=utWR!g#Jb-Tj;<^MGBCu0uug3lEQhS^{V13@j99(3xB#lVY;5G
zkBbqSln08YoZp9p&ECo1g*SY~)r{90q)QURXL6Qvw(Z<{c^?S;zTa{DQ}1nXxfw`}
zxMJ93T=cnj&iY_YL!L_9r%3HV9-+2|Xz$&nM>e6h08~bTVtg?(7v+I*EJWQTMFs9O
zBYC6t;uO2l{fHH$4lAe#(qfV$UdYCkM`tOTDRZp8;@y=eR57+kB`jtdLZeA~EUKl3
zR>;pQy?EueaLY6&CAiw`k%QzOLW<XhCX&qA=Mbd$8;Et-tV@pRWSQ75Bv=kiigObl
z+HU<45`b-G%{i%-6!nntD$C3zsjy4ao(6&JH3@de4s-3~g{m7GDUL13jfTkff@*YF
z+En(Zt+M8(qKpuS?Ip79F<az$r0u2bL}aCNpeRQ1#$_;J9Q?F+M671$3<@lHIh7Q2
z7B8(Xl)maN%c-&!y5}4wOAm|Y^H1L&Itn$)qYYTB2Q(K~134H*RkiuC(n9h+_APxN
zb2PE&cvCg&YD+|VOIhQpz%~*H!4yrkimSxdhKjVg&ut_I6nMlleOeceJkD})R<h!M
z7Oj|+fjQD0$shS~e%_QUdta90G&egA>zir|+0Cjr7v@2MJ1@9pHx{1P)w1TxAg@>q
z*4=>Bx0FI~;A?-Xt3yiAV`=sM?BO!d5*#pPZ@n9$T>4cuy{6DMXqC}m+z~(%C@;SF
zJ(wyzL|JKg+Wgp&=OsUO5qDRyM`*p!guY*(rDu!^#$7KhrWp{_4gDM@E@n;zeRGf#
z^#>YXU#9=htALQ3k-V{Y*&d1a6#R-#?4?Ny_j17|^s_;4p!{8VAc)XAY;NQ=#uMW&
zE1_L|0{Uic=mkvu{ZlJ9JeOaFD*fuOTK(+AuDg*`s-fPF`!OkQI!aSj2d=-SG`PG7
z(sMdJV|bx|fgu}qxLMTCxpX7wn2y(_<YGT~33bkvAuZ}&gcd`Ghpw(F`eQB!<{5EW
zQ$ymZN|R0(_3JNMSn%2^3NuFr_E+_%1z(@fe>cQ%s;QC^qeJ5o!8^rO7p52>Cgv5v
zOs=F<bz-|dK6VD}zEdOwn&=m{SrzukB2MqVJmzNEAA{^n)HumP)4jWD`i_tyd&E5u
zS^A1|6YJ2M<Oogh2ybpFH}MPpd}LnX6>KVrZ=?>BY;&{+!$Zb5#0hB|dJGSrq7Q?u
z5wIA%D)jq$58v5{KXgJc^u8(jM(vo3#6M}s)BuDZ^As~`b%{j6(gNc5Zqq+`(oZtg
z?bBYvpv4(L+ZN<-Ngs@o&}vkt9r$b2DYNrZE!8-0f~UEDT-RI0IYm+={n^S>CBN(f
zQY9x@>INj{BwFc!L2@RdCA(jpqPZ=D@MJmY{#Kdxu4-6K$5zWff2q%L9PFAYg>;I-
zHdu^b4;!+~YZ1s3=E;H4zqtdJ<k(&se>atb?|jYR<P1`r9naMp*kE>UIM+R_(tB~D
z(5$C38l+i0aw=+^TzkbkSik8pvCfz#V~=zjpg4yf$Dd{Ujo2OC(p@vo)UpJWLrB`M
zHnKKEcjLJps!KEH>uMN>g>R5ki*%y-r8~l@L+){6AKxoP4>nQj0X1wN>3XUIoHYtY
z->lrP=NekU+^;9sa#oy1wSPtYrsd)~K<&!z6y+$_6N>8*Eb%86P9zh0sdKaTrTD~m
zt(8FQHQnao)ba5sA^+$keQO$h9Pchc`i~6ugTQ$D7)p`QjO}7Nb|1+f_Yog_uu}SU
z4j-+=bC4PqJl*#Dx*bPn@+~jp1*ZZJG)XA(uC|s3OJqY+uuY1UnlibXK4f}=#N~Qm
zRjIc%rJZ4I9JBoK_e1aG1y=QrFZzF7)w8U1W=nqn0hRpM&fEV^HT)MCN><YSN9QeX
zqh_P4tZY-pfm;-%7^N-hub;%`0;qw|@jS0=l7Q<mQ#Dg^((l6FBKZ)$SCIF@2sgGL
zNH7+z_%qp^r#X|nZeJgtpRjv~zr2m>&IgA}LK8x509WNI3t5cD6<#*rtw=AR!abD9
zZCFp-Lc5Q0BI(1XTgQr-Ru;F1MOHoI!3O)!<6|1z4%v{~Oj~ocTg^&B?8G@g11UzQ
zH9`f;Jm`@H*%JgwZeH3i*7*uMCb;9d2ED5&mQKWAr`zFqldw*9p2}5U$fSGGejABu
z1@$NZ_6s(=k9Iu}9nipO3yYyIm8oY!2XyX_RFkK?C2$mvm48Ov)eQmxwl9pY2RpWd
znX4F8zCvZAweAJnhKrk|DSHla*Pxuz1XqMZ_RZf_8Bq0fJFa;m=-}R5uv0N762%QD
zWQp5JJqPHnQbUZ)h}C&Jz=Dk#O`rYx-y{Qq){~5Vz5@_YPsKoAUm@F?*l3E{!sIFG
z3^<1irZH%oOlW+C&Z36bdxs-Q1|)c*)#_7Hs!KoMED<J5&a4e)e#ev3Ao`Mt7(D-5
zsbAaOHZAEd438rHKezP%{UaOyQwaPYpQ&{}9CfrWvCXjsk$Tn9m~ArEMUE5`PQcGO
z_wvX?GFjYBN(V`MEoc-gV);0;r1`OMZ7J#exsc*wu#6NR=E#5|7AP|Q6!zEq863N=
zJ9We!Zf0!hl{Q9t=F=U{7w%JUv-So4uRo*wAg>HN@_8r#Smpr4DD)%66bH(Hvd+4p
zLgGQWyy5L~vijgjNuB-%cOH^MO{`q$JTx)j&3hf>+))#(S@L_}9>mc|rk=FDdV12i
zm{enL&H!6X2XE1?UonSh_r9v;U1V~;tl_o$4H~|>K;FV5mkwR=0th|nLz(W<XWr60
zJ+%0C<F7Hn*QV<$vW1Su9xE-*g=5*}krxSE8qL2K_L{Wt<L8(vG2oVKv@(JdqkoBS
zn@F-o1kv@4C0U?BM5bs_SOh(i`rJ7zSD1%DIXNh@LMwOVXFJlwL?LmiwlqbUuHC2=
z&%aigDj)ZcWCI1k#}(6NNNe>&NLi>`OXIahEQ=mE6*j}0N!3E0b>p<K^~XeC0BmC=
z&!$!=v+7u-d4Da4z0XL5$)thFy3gL3Rz#k%UP9f=3VBXssY{!wNMl&pH4YzVkp&AS
z%0dzO)CNCu-QpUxSlnkSxxPAsB*$%2ZAT40&0MX!lSyzJ(w`**ZIgLlOqfPLKNA9e
zI<qX)>C`AXa0vK4-Q0vXMS+?aNt=m|9JFXszdl?4Qb10UR$W{fi5@5_hbah3ByeU@
zyN@$bFN3_PbZxhkKC|SqFRDm|&XB0CQja-T3(;EOj9<^Y1EzL%p6m$tYN07h*5bV$
zW3zgi&s+gpu54elEsZC{$6-&gBJXT)0pm7Ek=p1QY~|?gHbyUPBCS4pF%z$A2-evP
zl?5h%Y{9~PZ-*24ySIBnG^4TpIRmsO)TqjT8n3T5wMznRE(!Gu@)V|2Y>+)Q>J&=f
zyr5sKLi%wDyxbgr`vq6F2{)V8mRhWU<}I!cRcSV#G#ho8-^Gx<ehyfGh2FD4>5`wf
zX=(0-6zBu}$>g)Yqwcappx_7wLB7%a=CakiXdu++7r#@)Qb+3wax?K(?|-@T0pssO
zAT_=@VP|e(RYU!N<WIRrVH*;=G5JvGpS^Q}g6MYO$T}}SVvfd$?_71)4(|r<Q$D3{
zh(nv&OA18$2vnaXQx0+y<tyAveMJius|}=-p-uyO`(#x!`4H<TXDr=oeZ>>^*pAXK
zMO{{!t}IkPVT}#Vu8~jQ$&s=fVYrqN?Cd*(`6D_)H`Z3N$EAkW6<YegT6+tyI+As3
z7<YGfm%zr|T|;n9aCdiim*5^GxVr{-cXyW%90GiqJNN#a;mn*n_ng0Z_S3sz*IG??
zbye-R-dYRoCqc>R4jX`yI33+F)+$pWy}Q}Du1X0fwcu<>n*H2P&F*0&MiVll3?Gm#
zy3ObuN+#l$aXg+`4<URu9$^WO3vaGM9?3ENXj6~f>Pk7`zW_e1p%e;0o2ZxfVjOrF
z%}pFmRZt`Ji1fF(EFtH!#;Gq3KX3-?A%e0%OwEI9r8-!^bfBUdQQBVEc9o;sbje}V
zp;54rCPe(MYDVcTA|8W*j|lCr75JUFeDUD<foMLMt@O7y#ANq;5yV5?J}f?r24}5t
zE#TD7xH(OlQ0oE#dI@?b5Ic?lxvD_DEr_@$^Y>&j`}38uUCQZsF>&8jEwY*-RgP-m
z#UZRn+JfB4;KW;UGj+ryqVyhZ=x+H)w5!SoaGU~cop#4MRL)wRGsXe{UHiaP9!|_V
z_&>|m1&iYON1d5=+ySAFjN#gqRk#dWUabLeIuw#$cx=;w7bP}zBZz|vC&R_R1D^Yn
z$+tM7kgVhGP+bz72)g<+Du@MvqqeX%B%+Z;yP$_)*3ZWB<hLZH((ydvggpFI0_41#
zNpC0}#scjlq}u~CYV47TDewU_J&i~&KIP^J5l~aSOWPc0sYkafP@%SaM$j*t+<mu)
z%Lfz<w{qfrTF=3xe!Rhp!a_fiBhTC*Lp>ha(-s`rver&pn{ypYzAp@AbnIJiJ)85b
zK4uIZ2;*^*9f&5PCmEOF8%%VQd8Ru$rK8E&8K<&R@L+%$S3yQAhE-3A;W3eRDQ1mK
z=c&bD?+;GP2!$N<Ux1my&Lh*+j@^M}<@X4lAba?6lL%TiJ*N$%qn|K6Knkf{o62y&
zbY+O+^>eL&wxe2(++uB#r9T2KxG<iO>B_Hx-$?T8?jFgugM)g4Ei29wuht=$W(`&`
z6SRhz7&!jA3Ed@LFkBM3Ukj~1R0Wfr<X5y^sU?pg*QOyr`{x=md#&EwpIvP#mfk)z
zqjP87m_EUg>p1EBM9&Qfj4~1CYGD`I*C@R7?jBn{NRd7d=a^k#fVshNdx`s4u~dty
z>nmHJ&@MoUiATx&?o)>FJAUf=Qj<2M-OJ?LWE_WN(A-=}wtA7Ga`Ie)Y+O-a`AD%<
zDuV0kuTV&0v4+=L>oJ{7(vKgsLD1I)!A1K88G%-XSz5u)tTqhA613M+Ogvctm1ovN
z&>Ax7G=)=fS@a}#PEOp@5_Wme{rhMd_)<NK;diCRkMQF+@4YRZ9<JldN(h^oDuc8_
zmZ=pQw621Cz@GNq4y*vY-Ng5FtFBQEotNp440mUzTU4G4)CFMf9V#-y?Zd)RUr2<>
zA?+``|JbjG3$j{x{2J83{u<PA{Yk%WXKiMv@9^s4{MQMS8FA9`T>@x<<KSQ-9{lgS
zb5A<Ka8Mn$Nfjb!bIGu7g}D;}mcekK&@WP|6z_flKT~a^6$2JTw&~6e(>d3#oC>VZ
z87hEosx$>Ka9u6-sy>TT2cP0OK`o*p!+45GsG2(m$S5|aSFWHCcMw2mms_dNvyW*=
zbB%Q9ONm@Aj2vWQAw_9?aIG&)KDJ-J2wYY9;mf@wkwr^?mrd>O6KGXyt{6nBZ|5kZ
zc711T;xRoh6ci9?R(9PfHgcnWu!vtKa*%Q`7JWcIFLSp-o`5<B5ruLQ6&Qs_6Z|ps
z>uwwW^;`%S6-h9U?^1xCx72Lp4KyZxdD%jk!w;il9UAG|##wxr^|}IhHRZMMI4W)U
z5nonJ83_R11Lp8u-@FkbZ8-choFO%;);W|IjnDXTu-{+l7L28(SSCb_o$~r;jtIkm
zE7qXe<HHtU6as$<NA-Xn253cZUTGZJLeP5(Pk%g+0!hsj9S%J(14&I0rG@@_?@U>A
z{U!y8$wIYW3IqrU3>*kZ?C%WJg>~%>C9UiYt?W%5Oq~q>JQpcn@%MySW)Hdzz1aFY
z_1>^VhL-#XJ)%e{Js~nPq3K&-h;*YxOQ)p1jxFzv-lWvKPaZeo*ynV(GO!S+!pZLY
zV@>;Gyv{fK71ry(EZ=!RLFJhw4#|Ca+Y;cF92(8Ctu~5$J%bFSIcYfbLO#<{!d=vJ
zC&1xq?+!RmOMZ0g&$U)0TX%%);zQ1ydZfZa<fF;j6x6({-oBf<P|hARWcZ%IY}FFa
zycybgjWrUrEm2_!yPlNrz4_Qp-~1#rhrZ0WjIK*AfO$rlA8I^F#}wW${u@>RcXOXk
zlRM2=pdqZW#c1s4u0*~t=b3u8R$<PgItX19Vo^;FP9&DvKFs6ea}gfc=x&J7eip(z
zRB_{nJl#$`0f~nCdojiF+$#owAP4zKd}NtAl(G(OM;xl<2hxw`O^>9xLsu(B>@n5}
z1Xj95EA4VjvENuxAx)Awz^GGNqzv^?H6bzqtv}ZRAN8`>dn)USNrP6e%>Wi+(R&N0
z5%}}*&3xTAVUT%{sXE!%VaErODE@rxL%E2I2<48s8Is)Lbnt|sN2=c$c5DnxWsivD
zx47>2@O<ERa<ZT$vB;yL@F~+OW*LyUm+m8a#$+BZ7X7Fzka+^h<Vm}k8Jn=HRrXVm
zOK$2FplEk(<9Xzq8Es)3kcZoHQ=M~Dt&zVF#+1!@5h)bDfXCH*#$*`t4M$O5>20eN
z!QkGxz>^5o6Zz>!7oG5_<TKR>Fl-kXGGE>$mXq*L(gdMLEcPxwjzJyas57rDI=iCv
zKi1a3{8~(76d<5Jn*S|W_<L>r{~YsNlxFL6XfHY9<3Y({f&6($5C`?+fP{R$Gl?iA
zfH6V^1-nSd#rY1(B&Pr=e9fJqxmGC2{p6`yRHh;-8KO{HcCKex;<?IaaejKern&5H
z?Y``0u6fvTlaewbgFtb!y?w&#UePwUbbN7M=e+jwt_f9yC0u@Q3gN-~{--D(;oyD+
z&J%sovmD{^PL3ki>8GipQ1xxR3<pzfF6@)J#crLHIhGsK^t67i{X?bBAh~-Uq3u{M
z^oy@NWBYzQ?{=7Xm^HRZG7!FF5k}9N@<dNBR7{f*oNqJl-h$oBpoK|tX?MqaYSEDz
z4;qI>$Xs8rm<&#PderwZJHRl8@1R6VI~MER*rwF({(v3`gSl6N@u%73R^+P@k*~9I
zBFO5t-%-rI(8|EDuj{*X&=|U8)ycMvlpA)*k*jN!2*EIK6)C*zg^_k_es6?v*@QEH
z<WR+^)o1UaMXACmZ<P3GQYgXskq`60gSaAQO%&&2y7;k6e)KV`Rm>R;a??`3xyZS+
z#|l-)yqQOloGR3|qZU!y^;VeA6$sA9y={ucd58=R*DqIW_bxSR`*s-(-_g0!T4(!5
zbD@7u=GOF<@ma+WIz{@+^ca*v1(%s<4@C5qVofJ2XIy+DTfvHk=(co>jgn(F>myZ&
zYyilXGwaWV*^I#S`(13v(WZq^uj^#ATX9b}N_Q`J$7<`k+tp!5s!#ScVmGiL2yXQj
zrW}8wvB5%MMxTY$2ZYocn}4x1gK;mijMP+cXDP4^Fs;Sm<j0Ea#cin<sz6{~0f87U
zos*au!kKSmHuPE2HkuiV3FjFY#_IHnbT9{GRGD2bp_ky)v&_sftXDTXoi6Pru`u4N
zS}{APDr;YS`buL~r`}Scl4fgyt~0<wqet6P$~~yBgyYz@2%Wmp_epah!dbMcdpD&f
z{3MH*c}2yLS*?)?#j?aKJe8ifq?i+}RO-aikkMjs=$#fwCb$t5+M+Vyie(+yNN*2r
zB`9m=Cc_9?y;_Ds$)Zxb4;mFB?ozdXEDdWdA5IUWS{6W7h`Km26Eh-3Qy7EpOdAaj
za$7oCi#-20dBrgnLz)e?4yT!`USqOO2ugvLbkxWs0~>zmyeFG`jUWI=kx$pU-dMy#
zQmP_AiiCmRJ!Wv4S~_{}vjv_-@05i?n74GQfX#q8!5#EB1Ph>yVP|&DL7yIiy`(&a
zG9QZS?#)o<gf3`rz$o?<&NPG}Vxvo$4J;GHnU3#77}>Te-FbGqPk<5XXxEa2Q2j6(
z0_Qi=fy&wtrANUz1{ru`D^%P0lr{il1DB<aDlDq24(HVzGdnK@b8$0weC+NHd~jY|
zf;y+glCG=$4*>`eUzAw15_rU&?b<lOh;$Gg)d&^hHqBt%5jl$$BNiCvW?>a9SwVX?
z3lF;o@@#T+IuIOxwH~I)vdJ+0Z=5Nl;X%P4-3mXA<pXNq<*o|d3+ii7k*$o;QPx8Y
zh^`JKYJ0;d;s*%O>wv7whR_FNf3no6K<MWdnYYZsFD#e_H51L~2W~6ex2;%(GsU{5
z;v_1^mN$ZBe+e28NEgOG;utWn^|HfaA!SYovdcs&^_`p5Ju^y8wG{0Co{?CWGaW<k
zuoN^6*lu(?o9K_<=DMwyKtitnN@nS)O@>yT`nf+tXbHHKhl8SL@KB=O?3j%ac||e4
zDuK4zuoE3Xt32S+;8a&1Cf^5-QY$kW(x^gB$TWTn927oepf8=_Ocvk0GE+EqphR<I
zWM6|GE}O<}PceNJmm`>s1}-pmmI6w<KRjd~RAcvkGR~k%Ky8QIYve;Q9Ts1=U~ix`
z^1-Q)kadKEXqrMdbW}8UPwodSEC<Y0%L&2e>1>7xONdoLXQoK`A3C$>=O<y^1&NEg
z;S(HI6Nrt&+1;(Egl_NoZh?>>*<5n4&HE{Ax3~|eV4Y1{mp821r?P_&0R>w*QT~D_
zv3)on4Zjnt(ZcbQW|gEA2lL$E9c!q2M)p0zwI^0gyL5cZ+C7GU##;wUAC98;x84B_
z@ehOX=O1SWD8o^+v>jonvu|U4{kq_CzcsoGvEBs<*Z#TV(|60CqW;$V+(0Je()#((
zVZEOXA=U>W0}tN$pYI6+S+X)rGf4;cn7W2mg^hkTlo)2=kX1<={xT^sv(cS<weU?H
z7p_i1i2245(R*;i{hrVN98;L5(;4e05x>FrZjXTthG||1{;p^<kDiSRs0Is2gdsM6
z!tDwQP!iM*a<BG`&5b&RVL$&ABlsF0+(x-j#}10Det0jxj?5KfkeTk~vP31DF<gqv
z6Y2DC@;?-@HH#v}My)uRSiEq2k*U}YlCEg|qr-r+HjUx=`s7Vl^e5z-<~O$0hZPG$
zzIme9o*h;lZbo$00G2lP?;!ji?_Hr%%3H5MK&Vx;=wRXah)p^Aup?Q$6b?FkNyy8@
zK$q%Mh|yZK@i|Hr13AnX+>d*i3;K=FAoY8Vpr9tEv{(E{h%D-q!Y~*@Q#wq)H<00)
z9gWy<pfIp$YJ`!Rn#-2LQ;MfrrmC$(^o2WvZ=d!u(-<k?IKZwJUkpQZbXA!BOf~4a
zmcb1ktl~gHaKvO6@3Lja3d+qmHNsjBg-8oeTi&cP3Q&W)psrS`F%;XSgeX1ri2TTY
z2d`itG+2=D&gQ72j0>{fhO5{XMxQn;1@9G)+^QH9L9T@`h974#u<s8pT+Oj6-DR`2
zdY|EIdQ;dT4i6b7e<=oVcCq0)7}RULPk*xchIYr2l)t&*x%Wl<{_qh01H)76VN`Ef
zlprGXjcuz<cIi0RS7mj6w+VW0|K>g89E>5}3T)JqI2e=djpj-Rn-qQ$(B@77^q(6n
z<#|^Q`CndG0!t29=I;BVQ%<|70)pD55Iiw6^YhRV=0L8M7;Oz9YmF=zPH8@JxS%zz
zSoPtQuG(H_`!`SGtMH2@C2*my-{TwIsx-BUZx1dTD1-{Dw+OCLIyt1|s9^|BX%ndd
z2FzYsWm(cEM^Cp_R@CO_)JSr}rBpZ)w@Aqjrt2%e>B7E@oGxEv7#Rp9W2v{zkKpy$
z3(VC7W56}2wd`tlM$(rd5mwl&rIr&(k<(5yQO<j4EV_m=(>hhHq_!0_Ux8@jxn>n;
z#QX6RNUp9*<0%s^8ucn%!+ot-Mpqm_VYv({wb5+V4y1;Q!GvZP>5_!pqaE5|OAPla
zXDb>Ra|+`v?34qARi0|H$s|o)%8e}_yB3VqOh$nJu|sUju75BhFJgjGO*SsYx*u4%
z^!@;K1M)CeU$`jP-!B5Mf$)=<5lOb?#AT_PJxj93>2U&O#61EVcERV?<uWV7%vjL)
z>jJfYQefzgyBYJa+zY{<T#u2x;pO;zH?)JDu!3$-aKOih4AiLUOzuPrJY_lMShYB(
z2C{g0-4UxjkDY$<`Q}FNxpPUi%1e%zjDl4(F0wA11JTMwXHPwS6!2;K#5PLMt?HR9
z3>YdJFzFpOw6b>CX(H2pjzT3*>Gk?4l#n|jqJkZC1<Xa*C^uZnOSlDhgiWZ|`lp5r
zNN?x6h%ty;o%dXc&UWCx*v6_p`4`hCxbrDIb2QOz-BL|#Ek&IteK!X*O?I28^Sh=-
z#Wf_=>ipm>!&(Wih)Oh}j?A+^<hz1POFt`w3_&Y_L@i~D7oU`)JI>dtoKAD2KF4aB
zU`-ubZDZNOx&Yc1lAzECItQsN`2y{biNe@t6o*9A)^b1`vLKE)odhs8&-n7yZg?nq
zdVm1uS}Ckd^{{~^QrRj@`5muNwB9q+L-lFJ#!L4VR#QOHG11jHD6TXAF8j5jpyFc9
z&e0d40v)a|Nn-Q2iVBMAKJKP6!mfmoy|ewN&bN~s1;QR5+`I~`C+=|M1J|d8jS03W
ze`a<;^RiqZ?cPr3QK)k@Z9=VwZ*CEA9V10T=C6ZpQS-9Y^&Q{dOt2uG0Dp53eSdhn
z!*G^UQ_{v}h)iV!Rkk<(^KQ3YsEqzwE^OsjC3-ID$!1>Y50%&Mt<=qf;zcKn=)TQ(
zGr`mqSs>q)dc)N~a&amwmd{VW4B?54U~TToN+>N&wm`43rsmF|Bs|hQ6v0FoVT>K+
zEDG_o1dqi!nMIDDALnoef1Nm&w!$o)0LIQ--Y6QQA3~2;<`=oFqWu}?Ir?>yS^Wq)
z(JgFuCFrTiV`pYq+=SX;P*Rm0;2ltan4g4nIAnN<6Xn5ElN-DTNtUTalNt2^Xg!i8
zifvM<$Aw;74s#MiLs~T^)O*>K)=`mJTbAAdRb8S=MMNE!SNik{1^lq3Hqr~C_?Ak9
z@B?H<E@N~yRCK;vrUZ9ma;}z?ZKk;PiUhYS>FJi`%xH!K`FVcH9nk5fxG4jF)Ox=O
zA;0|mMM-VedI9boXmhN$Jo_c#p~^GuY9HbBDQDa>$|J8trIkUq>Y@4Fnq>T;ts6+2
zc#H*8fgp2tX5c%v3<y)jgX1f*Lp<Rz{y_Am3A2*aYe6fkTve%x>FMn0Z2z{o;EX5W
zIX9FJ^LtJ=2wud`m)w;-0Lg1SXC}l+cd&=exy}wzD}3=px!sQnguIYxx0C=e1>UUK
zGPa&JpJ!+{fG?LlfCRhZa}#la1rU_QMl-Gyo)qXidT=es4D}s2JzEB~mHkdV!nh~$
zH1L+3rl2ZWKisz3?Dp22Es?rq<x}b(XibDdQW&mA^Ddx+E5(D~oG|w$9-at#&KW>F
zYeR~1x*$+-G-EsCdi@xE2{i0>W*!Ye0i57-6htYA^(kO2BO;pc45hw=bKT>(8|;(L
zs6SbuZ9ln-ij#SxmS}bUKzYD0Sy2+0-prz`>}Jh&NzwVXpeIm%H<HgmR%MUcR$Mt9
zJm3w#HZJKpMBplneIff$Z;3ol^BpwxhvrjlZBc8|7`VqAh)NPGF!-_CVQWwrTKmnU
zU2<;LSn%PyuePdG<}*OuC^sC`Z2^L<Y-zB8qcD{U5+M;CRD(NujOw8ya~AKKo>#z<
z9H*oOYTprkIQ8-=xbu|5nijwQ<P<=GC?k)><9VdeQBk?cQRavCwNhiDUCK4=R(A?!
z{!{1a`1P@;L#XtDF$vL5wn+kSxRVYvME)w-A$jd|7>}R)Y`>{x9poml^gI04Jmxxs
z47Hr-xsqL}yA<E9;T4AWit!*OGtH5_waB;{ND^npsP!MfCYH5an%b!4Azb6RzfJ16
z98m;pCKf6ZyO4uO3s7J}pNPXG3AHRrY|KKzqMG80rJf0;N+qr$mdO!aJ%a<^*au8L
zLM5#e2k;3^c*szy7d8Neu5Ws{rR`5R-)lV(%un7nMXqgXU%gwG;@?p{=>N&}6d>;>
zjk1Q2tH(k8Npv14ncTph_z~a++sZ1@k<l(}P0F)gXbRLq33%iVxVfDPo1M6(>ROd%
zH4sjKtcC~o!jb=AY6~~90MYou*A`yIy79G->}$NK?;7GkFx0)4SBjSizZlBhz4`+*
zi_N4(JLJ-unAOP%_(PEtvt%l#i6yUh;?(6nkh10+1EbNU3u*5*Z(ja8hT+hM{Unnd
zNbMPU)y@>7Hh0N;^BsDvn(ET%`T|S}7G8zq85atIf)${#pL^H9oF^K2`ykanp)%_r
zI`cnFsa*L|kl2&uVN6s26TBc~yAldqW>JB^z<yq~HsSQlZmj}a0()=uMEit$vnS3E
z{J=ru9qE|ocHUhNf;oJ^-$@F&5;&f5m|bz;?LQavfCyAAe%JsVV;O8{Fi$yj3`&{U
zSiCBF7K%7oE)eVP6e&(zLa7jb_gGX{R7oETl-ajEvnDO5#1Xf%9Cx`~vmgCIf^K?J
zc(WTiRf28Qiyi2(&r4&4EZ>;HaSjsgE^qrbFHDK1<+IM201EILEF2!gEDOjw|D?$S
zGtrZ9s=T+aC139Ffi)G$vz$AlGkt^|EHm#I2Vg;TeEX}U(4$ELmiR0n%^wcQWL(g@
z!p{lw#3SF&i5(#TnWlV|1HLdn`$+_5NuDhG3FA)Hj)ZbOSmyq`=TI$Bg@+Wwi9b`>
zShX-CoZx{_H>CGPy2DxRWa!;g2Ik8*1-r5DWG{qIlez#zVWyMo!kMzK8ly;&{Qgc?
z@6puG_=K$HnUz$qxaBU4sjg~^i6O!Q%ytHNuAWQDJVQz`BJf1D8!JNfFmqQUxi#6B
zXeZwZyQ44hn%w&J8&Bwz{cQBVX>x4FICaFz3UK0I8qaMbxD++v559q@WpB1W09qRN
zf2OEq_qW2IxWczS<A0Mk{SlFG>I(=E5H%za5cA&&tO^=A7~1`w24Vku+^X#Jf8|W~
zzck<;A3)$zg^a`c3BV@g<c0tgJfH?eP#r>B0nX<5v*oPLq8Frh+8)HAQn{goors1!
z4JBWyWBmZKZsVM{E9;#5Yxc`o9qms*@B6|a(5G>#lMg8+RRJZ$k*@F*7)lAsbWA%(
zUNwWfC0j0R-7dYD@HNDZyGur^jw6&>wHD@%>&Ah^_QMzH8*JS>4%Lq`pNZR!G{G1o
zx*wcsjKT|B_u>p2x8|EPce`TU3}hfR<-&=*_YFUV_gjPX-{v*%xz?*Wx|SHmn-N6d
zg=13?Q*0emAM3?;R4n2GV+t-0FfwVo_O9Da@9K1~Km}~Gsu;0hf6!tvu+xr*18v6?
z{@U2ZIFq=nV9Jz@!{#32-XrxcH=O=<J^IJ^{aW++QxV0jDulE9Y$6^5fn={T1Y;@w
zW^(-CZY6p`2KYS<vkaagw154kb$IhrXKWc@X_uKHe1tT()kAyu3t?&)dC;!N1M_*^
ze#fO-`r3l7B2%9uI{Oc`KG~oq{cED`6WjVM-HW?bL3R#TRqTRhxvR=c8uEL9$HDCJ
zOOEbV*<Hn<Q*S=*2>tQ19FfcCmgO5_LSGuGtKJcz`j^TR>bQsO0Y1`UAX7w1MU#<3
z3&b!h4?(jeC2;>M0+BG4xrzRxiR3_#MX}{Gsx2@iDU{&@&d^w>W|1#fA3hLrm%{Ck
zuY>^-5QK?`i(&vlHOSk@W!VQ*9^wy8Io@JYMhmxxK$X}a(w6fGl}Nz(4pC%*JC}`E
zIp<=m=5b~oqGIcXW_Cf)2I{nl#dE~wmUapld;}L~vC$D(laaiYtDxBJA%@9^HcX9Z
zR%r<ojMzpFoLZcsl;8&rax`#ovGb-l<9WM?6P@5V(k!{j`QF*SoF*M_ayi8(jZWfz
z)%kSrzgg%1aXs^YXMrf5%Keu8JdIeNP^UeVM3w5NyhLwEy+s+)hl5HAj0y+w0)MKO
zXyKf;+I#Tj4($1}2+?E@<oBEi=K@-xWw1N@{WWg;Gv58Nk#l~2FW|3Ri$vww2^9JT
zv4ZMB_S8yK$-()$#PINjro~fq1vaXg+EX?kyFr6EZqwkJ>Uf`HH4&WC=8O)Ot?W~D
zJI#aZ_v32xTAUh(7&T9L=hLVy0c2)6!i)y<7OJJ^4Nd_siRT<bPCt%T7Ps2zx2aN~
zoKJlO*Wbf)8&Y}fHg{EU@<4%|YM5uP*QWAWb95DR*DGIY(4VmxgtM<827Kg*qy$bW
zfcm%~xV)J)?;8FPfg$}AP#{#XZSFDv6f}=H<;s^;oGN-U?Z={Qih&J-`3(Sf;ie5H
znA2P<@Ll5~?&uLl*4pjSOS`ppccR~&W<)w9N*9aE4l8yqHi`~TPp8PlrBolA77lea
zKkIy1PWX;1^OJHvybPc+Eb2IU>U%<t9rY1h-^&9ow|g!D(?~i$v)iyJr`4A<{6hqx
zv*2&s+$)Ay$M#M6w^u{1E%Yl8lc&zvl<1}fMSJ7hK|D{5a8GksvI%{XI&yL;b9qCN
z6KS~lCTY1GW$Kq$wly9h0i4cIPTAS|Fp1f>oB?3dfPt@6!=KWB+#|rDHbPLz*Xs_&
zN9yfNTZ&lneZ^7(bdbhM6X<Th7I+CQ^NC3X`6n3H;t@Zg$G@-zjahhbZ?X`XSLyZ&
zpU*_PFy5o(W@41tF_;nvo<l@uflzXP5)K;`-++%3@5)KpZPM>SXx>QmOUodoWS(He
z9~J11NcFw4%JFH8?Xp}s)D_!mPBAr3mMxhAjL>NI<Tb}(t)B5}iQ=%E2F5<X{;`U?
zP;4oE0s{iVfdvBM{%ft6zcUG1rlRSLqm1^904Kwgvgen>N>L^WhYkW?R&PqrA~ikp
zX;8E%)RflA2Ra4K$i^r{<i-EIeAoTsF|4JQv})E9{xgDOmM@V(WxjgXme$Rp@wv74
zW4h<vcEv|;NE>i|369`pl0@?KUi`IEiN<hw@=}t~!mNu)UTEx6NwxkyB({rtq;`Qs
z_FKsB`Cy3k5S6?EwjRBd+^w!eTg2-x5<T-Ic5u&m1?D#>{_J>*dPs?pxkHR`lMaq;
zDuX3^p5z}XB#HFV5`HA=nR%?Cz}#dS0kp=kjHq>(KI^GRVh(BWd~UE%q+UoXP*9fD
zR4g<6@<HK>guTV$0Fq2;6s%iKl2?Um<?B*v4s%2>X^Q8rKxh(r8`}6%K|zv)V^_YL
zcpZ9KDF$|dTd6v@qPaRA9o9p+N^uGpCmJ7gJ?K(_o<=}8>ShI(e$e9laeV!x-8IcA
z1=AD;tSk(cRm%hiML2#7iY${^y-HLC^{mKFPdbw-D-|@ItfX5mffe;`YV(JR)M7)<
z7?8GwD--)3hu|U>a*--{f`|pUz9ZyFTzr2eOXC#6^!S4@C&KjZql?X^xw2G;ZU^ba
z#*WW!f|ev`7x0GcC7&I7ovI(VaW5AOmj|f7mEXV*EH=fitHL^wY+)!29VNNi=W~BK
z-QDum?$S|Za4ojMyQvWyrTgm4n%QOIjp^yT9CyJ+fh8ut^!eglf#Jv}jUIjMb7ADz
zBn1J5KDv(zRkXQ1sy8AgOg9%IBI;t`%}~N(=<7p_-zqxkvDwVvVr+fR4Q6Zy($2BR
z9C~R<{am?x3u!dbZg3e-=guaiQt~xKXHRcJjgq~z>vHUHy$;6Y^0K-vVYd5cRo4_t
z_0>cUwHg_^yK75IcHRZOP==Hrcg39a*PDM_?(ThNDXN?(*-}#6B1SqZ1;QTPQnhN-
z>|)HWE2jF~Rt}Fp%es;HVUYZJZnpW9ryKD=cQ!-vR&k;ID7OG}_Mz{ca3v<X=`-1k
z$zx=tyK`2r(M0iuu<VTs)uF>UB`4MyIi}IUOE2g5XsAAG-n#P%Iyv4|*}J_g|0f|(
zM2ezo?k=K&&hxS_K9`L^P#_HOa{SXr#;)>Q=ep&FwNgtuM+{<~9p7rUGpsw)R*}D=
zR>R-T>A~O4>#?BYVl6z+n*)K=#e+G7weKU7MB{yPnASk`WrmrIj$MON&SpF{YITXh
zxP7K{y;aN#x9fn1V<W=X4bgp?LN*A>suc2PhGW=lqLzX3-GmUs@DyAh#|ocxxPsEx
zvEc6|8*LT*2<i(>e1J;8{$0iV@Eo(sc<0-3cDq1=-vSgeDr`?zaF1}<_fw>5@qlpg
zN|6u@q<rg$i9j3lB$Ica;BKkFlQQn?PVelltS>=>ukqAdq%O40_kE=?B<(W#KqRd;
zNP|1lzEJ=8oQ=Hy=`)>O+LQ;&4azn=Sl0E3WxRUPsk%`0u6h@}(CT6T^p7h5pY6j8
z{~sH!_>5Nc)?a-y(XYOl?r$Vz{^M$kNJY*6k`}3Npg$$a*FqDd!pxx`3d3xDUjhao
zHtorS@V6G`RuB5EQ>I7uh8d@5zsnAliV^X=5yu`sd6$nS>5-Db`IvF;vChfd@#66U
z{0W(s+Ti_r1sP&LA;bs9tlZt8urx`!ycnO%K6*L|TTQR?uZ^@Fw>#B&TkT<xFevUL
z7PhK_1=Yhh$!k9Xic|xR>1hv&V7m2mhBsl1n!S?zY6j_qE8L<gBX*hc$)vhabkqe|
zJ}xLBY1SPltf(Smcu$&H*zcn+vr)&DEwCC{F^Lb@V@0@f`z7qq*6SYxbstg8n-@%c
zWa{6&R&JU6q@w-7l7&}SQ|X<ljkO}qd&Xpj^du1iIV6#EUSEgQbY9HXPL0&rW7?=m
zGn-*W#svQ8xTyG2_`zpsdAs1I96hs1T=1geRXekvO)>abEuBYx22+dyy5OLNW~z9>
zr_zHs53#d0_%$#TawX+y6zs|B*UA0!Yjcg`q9HykstrwPH5LpF-8U{#>W`c+OmqW6
ziZldfE?{vyI9-yi<&#XjlPs=24$vB1`prD6a;ym#BHfDACO0pAu0e+S?n(1sgOkRh
zg3dx{*TCB}3qJ?ZidU_1J`jC&5I6m#?GN)Z*k015ZO+o>DKnKeIN_h`JNRzO*+&i;
zjzrGgjI%6>`h!@4lR$wBRK82Zz#MVzN94zoFBKCs>%>%~Vw|M4(;z(MdNcck-E}b~
z*mm^j9mHNfYx-pM)knl}{NW#wxP=h0Jqd#pDK`(0r;va8-4totCbRgN6)Anmy6Z0z
zB0$BTO<J1mrzW^4Id+J9*^0YPpxcBj<c{0cwVQ~+>!kpoYq*FZo2tf>U5Xz>Za6yA
z?!{1WlD5Am#Qib2%3|b!?O-h2_koHQ_i7`~5A<slqQOu7q`rHE$i@0^oP?iW-gMvf
zot5^<zn+3(i2sw~j-a!yo#8(vr<W=J8mlTG@iu5TpE^~c=Xh;E>LE9y!LSY#!k_@i
z;8SN<zIivCYG5|B?48X;i(f$h+(wiYi6rCmK{QO)Ow^c472V1j8yiWnFL2&Fd;WR-
z1nJ{iN*U7w56@No!&K-?RvHckAfFggxVIJpotegnm5i}aPe(MCSlvEN_H0HvQJ*Oy
zNo$gd1*~G(D91=MuwTo?$nz4>=ri#ie?#ku7NG-Xxi%G<+o&Dg%e(IGA{&=RkMgc;
zi)KeNHgZtzGNV~Ed6(IOf%k)Dwk=(O<WEFj2b{2(qIDh;k1bmFNZ!*vt`xSmpK=r|
z)Hdy>1ZX0hGA(C?KASfWuB*uY2=ETk#Y&+$y-;oaWM8O2_1I;HQ_@rjr|=G^dNY$O
zvd7U$Yd?g@wRG|E>7a|7Z>>PZNi)~TO8tim6Yqg~Q8sB{ZB&ig1R#W&%SvCVH#dr$
zu0(CJDvUKK@cnM2aXWQA-RAwS3abP&+%2qh9XA{^<u(rwAx`qzsT9IeU9aL;4Dkzt
zanTk5C>BMxDmVAK&T8W>KD-m1#XL5IYuociB!f%fGW{jPu+m}vkwRh0rN-!0>q!@$
z_DU$KmS|HR!}IWG-or(U+pig!<~(?X5tFzd3Z0F?y6t*>9W>tYisrsIi4HQU-XEYv
zCXr&ZlsWguKA|NM^CFy-7o`81_=65Ha+Ijo2q07ixBE5dL^S(}jFqIv75WSCCCohv
zI&(pX!2QH#xL~<*RXF9`X6PnU`TNXGnm&+BUbtEX(QW2j5mtdjPvH}MCdl{B`IO8v
zu0MG{KuVlIl;2c+DUyV!58==}nxc1d2=}!Dn_p(#ZWNd!+9mV+I7W-iHH=qI{ew1M
zI1>rF8hoow6yxyD`j1tf5=;UP8yE=4__tuhzpV0a#;1`AveMlGNS@PkeKQrsl;b2U
zFk%(5)DjA4ATZEt4TsGZlI+#13D0bZ&p_S@jj}ml@j{r18Ll<wZMu8=x5v1hykqzd
z_~|I=WQwrm@Hy+Sg%;m_CQxs7V3jX&><U7=<IB71fmFaCb43pac;loLHTg69;Y#Kt
z53*9O%t9kdsTtHNkzhgC;<?<QWV-7X1TwIs<*mqnIP3uM?#C;zr2$x>^Ou@xj`8!@
z+RHQgg3&~mRnhfAKbRbJx>H_3*mjullxBQL*yY-kXR3R^ByXB@gVtIvR|^<E9ZRbS
zIP-?>8g<(8$GDH6tyxq`6EOMYm`X2%N}qPRSZa8|hKI{q`B7;lRjOYF!A7med<Uw(
z*Zl|NAFr?QB*xwmC=ieb?BA5J6EZZiwlfqnwX=6nbkzIrzyE&8dsQqIQB~2rtg3Bn
zYfL2IKi4lv_zUPj36=;T!6L_?gjy!BEi}lgP0t$4FIp6P=kVvebdA;eCl=jk8b9Q}
zeBsZXws+QtqNx04Tk!F0xM`esziB+v{pR`l+?oL>&-P=V`bb8uk&YOaJsvhT3Wg!w
zh6a#y<Jd)LGM#-X)B-#<lM3e?MCF*RVjl$GXF!N-RC)wbJ;x8c2JDB^^J_PUAYD3R
zjn7KGADl}xinV4H)oWA~BUjU{Od6C+%GI%j7><Ih7yza6ZrvZnIrdiBw2aKs1cy>v
zaJsQ|7tCg)QXR$Vl?PFVQVi>w%QTvk*(2k!hmmw9&(ad>3p5>DCa73FnW%7sa?}@#
zH7d-((k{ucPme<6aHt3cT0*8>F@glAsTPV2_X!u9O>I2J7<Zyp)oM-RD>4RGK(8TL
zm6ao<ia%*KD-1el6tosO-%%iV%@#u)a{ZiaV8-VO-9cCZPu)Y5RcwQ>;v_JOr&*7%
z)naQ(h7<P%hC^JJqH(Q}<38MTXCh6lH8H}@Z9CDAfi>!;QA`cN!#nGgfo(!h?+)?P
zZ5_4^CUzyk?%ivFslNd4Pl5?s&<$~s{JKHVu9tip;V|!Fk{liRZqViID>*nOBZZph
zFcLpkXSK5F3`@6;=ZCq}tY@KV!@LxXL7Ghxt1(fEzGKvBxNrVHN0JCk4AZu`!D*yO
z^inp9_hZ?jIVNmw!8enRx<9j*K(-;-3BTi4p+9BJ`GR32@Ad6a$F=adDs<Zqi_M)z
zs7;4Poj$3~jhBmEIO+HU;;rjY<ZR`&*-_$y1lqVT1dRdus8QpB-1KOIs{67mB-|dj
z|Ah|LiA_wVukg|Hg6!vp_ijt(4i%{oAB~03(?8S{#L-=9yR32R6sgo9I4{y}JzYW=
zE^N<lJR#n7^vI_7(2`tb!%TBWfcxjRP7feveZ9H5b&ED)H$5xV3GMX`WWbO=`S!v*
z>gkfTG_4n@Elj8><fGjWX@Fb6+NGc1(T%N8M~>Sq-nek}zz#7X-d2xTge70edu7?{
z<$I3(fI9xo^9~dgb}HnGa;p4(Mjq-^_+6hVP6)D&YjgBBy@T2-?lH8d!7gU7TgEFp
z!kpZNSiD#r;&s=hTz7)>1EbI*_=sxdh$>dH1uiBF|Fv+=;Ag`mwea>JXc-hsKx%F*
zBJc@O5E#B^!j7aK&Icqi^=8*bo-&CUdvSWFY?Th1Zj1~@0Ok}-H$eJ`+1O!lQaa+@
zw*J1mmaT_YZ}3b-jFa&pr$;88!cjl@g_e#$x=t_k5i*{S%R6IYf^OJG(MHDWEJ;2O
z*(dh6pM-A)=Rn*kzhzec{MANt{&O3m=xXm^X!-XNtB0k!1<-=V7fLMa>gUX6MORpb
zP(^wIF=H?=KQO#M^hza|jwM5-m=;=-QuTu+><mVsG({>B>`_l=z8rrUO>b)TZfytd
z1hz;bLX0G_K+91N7zMFF&lV-}9^#=Ghc;Mxh!LnC?w813GA3A)Sw#+W=dw%qaBd&Y
zB}}8nBG*%zUg^`RkOjM33y#liqJh8+sY^83hPon7j18fE);xnN9`4k{u1FGw3c`wO
zs0U;1IoK$kJvsLn?I0!_>{ibi<L6pmUGJslPDO2RBlC&f@LeUCv<e;kosyc%U~brT
zM}m<ExKcKdC`g`oHeS#BepNKzZD1+OaucuWvOYo<PQg<%m$JIaO8ByA`)-q)5qRU7
zlw2z$j-UOkMa$aR@5Fr3X5u>RD<L_rHx!0JLdSBqs&P_iP(Ry0G6-ZU8$(Oc?CDn_
z7^2hK`w!6q+F@qF&d6*E+OKMT*gA4j7#!%qN9l68i%fp)-{oq+6!V#%XuN>^@s`q~
zoA^Qgx}7axKtN1?r(5{vwU3JH)>H4%p5>^~VC_3slvq&N@fg{TJeaX$$x@SJETN4M
z-CG2@n-etcm+2q)@3+D!`0gO@etqMzTr}_pGo8vLyiGs%*iT<x_x5@Qu>tBA!&zoy
zS{TbU+s1aHo1tfcN>R<c%AF5TYO@t$<o-56Uh2eqNT3t(SpGouz~?Tt`ibZ#Y7UR3
ze7cdtUSPmV)%%<hx7d({loz7>60UYA;Uq-ORe{L#SQO!PM~L=)2fquoft>P~9p%EQ
z<$x|VkHZ#=qJsm)9q_nHo%76a>CHQ#sC1n?9!@iMIcRl;Rv1ZW)+svUEht*wbfKC`
zX)1~b__ad&uo3E(#tdwWy%^XXU80JC_Kf-QDSMb5r2%fv+6gkB_azKLTqehsxLH}K
z#V@F`mG0jHaT?Eg+wLM$k`t|{5MkB*l)X{eZZu_K-Ca+<nB<5qXcq9Eovr&sJ?x(m
zk+iCL{Rk-Q9bKhLwD5Pw3OBJSV6ZVn_EX>Npap$WW4wZLfp%W7Q~Mznv-SkMjY|t*
z@oZEZKQvI4DG#Dn4nn~!2!Noek`Y)+H#9jgqQ1u8o7ZGa1B{5F#C7&8;hgzm+2AAU
zZ3I&Ze~c2JKS`|`J-0OCRve-7r85~AmE4j}?8_@l+4+H%b;X*+l9`QC$Q!xcV3TBs
zP0d%N+gr=|CFqfkuttRV5%Z7LN~|90miO0aV+i_B<Bxwat@IazjpGl~?~$J6G@<f<
zrNDc*^$fG=Yr&B#U8t4ceV|eko&1>7gF^)!4{?F+0kjTk?C?It_UC>?^p-HknIsIF
zbXphVc2<qM)2)ZGb4?3p$Fs*H0#T4C@@NRl6bkyJUx-AtAVZLibZ4c{vKBLqP-n6a
zH%OnTi>-V>$Rh{=lmz2Un)Qqj(a=Q3RHPP}@j!_ydE978Y+id6v3Uu#vLc4TmuxKC
zY64Z(+17r>*<*|6ia>H5`l|3-dVovZLvhzc7x<+nE^XL_lFnd!Pu5h8otGq=Qab|-
z?}~O%eUG^!fI|7pC!>0muo$?hhyrRcCI(Cx81+bw2P_VR;H@hoMEYn+SywVR+2%xm
zVYiHRYH>NV1XJx&t0y|OY?s?&nnwKkP;6`IE(!MZ`#P;wt*QMJS8TTXjl@Vic`a-L
zPtMh9%0ek2X-vb}_BKmY%<nP4aL2|!HZ!`z)q6MHFn6UR82sUUHO2rT*q*}!H1RYQ
z$x%#cz?lTlUg_~0!X-Z9C=>wlPa0it1k4VchW@%Eld;B2%>~xx{Rslb<evki8%OZd
zzAQPmeyRuY5GNP)j$}2QhjUasOl)BtPh#o*UbIx4n0$hZx?G)u7g-di_kG7xX!lG@
zR5`qpEtf04Mm_&MRD@WORIr&z1YZktgA6NSN<91h3<pUz!WcD$u>4_+L`5mJy8Vkq
zkwhm*WHD(@8^2X+x*&JrSc*oPbA5q=D(%v_B3$MXy3S}T$Mv)7Q5U74DCX0y<^gY~
z2Or-=h<$hOKJMr-+mh_`nyeB`5MMVsT%hyjvxGb5lBwk$SA7WA4VX@%AmkvIg!m0d
zbhuCNqyY(bH+u7^*pm;0O9+Ku*2V*f{2lF))}8Oe{d3m$b3rwP*aG4Kr^&_|NZXX<
z({C+!F!2&c>#A(0c#T{8J|~<Si?FpdhF}Y{!x`D0lfK;0TH@?Y-<oiHny3z_KpLSN
zqQ6{WXv-*?{LK5*JA$BJz8}0O1l?!@^e#JkBe@s6>?<dx(87>eM<BolR)mrYbo6TL
zh-^?fcb<pDEu?E+fKm?&*xRfZiLx!}K>NG61{^8@rcr1C&(<3Wpq1ip(7&n9i~f2M
zzS;o%dLsW_3jn4DCV;}9SODz)LHHjS1P%1njNl(-@1cSIXF~!y75r^4E2<<&FDWO+
z@U~d4f>Xh7x<yLAUT8qCTb?iVKNgb}l#>(_RaAN>EB3F5!Ty2xNig-lo2Y+P0`?Cj
z+W*+7{i}kge<*nP7Y1K%08IQ0jK2K(=<I(xHvG?4>x&2cFMXl@M{4~oVDDPs9NMo_
zvibF&i~Irbw-fzWfNzI&zuvjH3OYKN7+N`)>c6h0dds+fqGn(Gi(wh)ciYZaMkla8
zH}U+Vx7Axbup+lrtzYM=@T)ZaAMieb|0$mMe;q3S>Ru$QEe&O?t<4>6{u~-_OMAKZ
z7svz5?=!-$(2!7n3N7lQZ{cWf>h$aTv4x?azP_Qoy{xX4uCd`?T#FHS9kJgewC^F_
zo;yCmpAxA4zW+6DHZnDKw9|c!a=(RE@WeOW{dGyOfBlN_5775We+vEfeoFl6YAyci
z#PeMln^k_R$>6^?8L#Mc7=MZ`V{QDGS7FTVI1C*U2*?WI_jOUPU>#WhyY1bdV{)w3
zuj2lC#7=&-0z`kn#3K4vR<VDMw%REZ+VksTeujQ~pKO``6ivw5+TpjkR2x}cQ>$O2
z;@9suZ=ogT8px)99g<@G?wRlk?Zfe}s(`4Ap}yl^K4bwnc_r1q4uyW9()<B6MfhJl
z6#tF=+e!a9?px2@SKN5HzvICB7VoXc;VYiK^1ttR_?G3Zf8HyLr|REu(|Zf|);8xA
zZuaBfGST@*z&~@nc?C57^w%CZZ&7|L@sGYSzi+>FF6O%bJY)8z@LLy|*HcLS=feNH
zr_5XUx6UB1@Z<)6-zVfP>RS(vS5#!f|ICr&Ez?`CgI6Y0lmF29;4Rf#srgr`7qfpu
zc>XQ?Tg~)W_|F#qp@RBbs<+~+uT%{V|F#tCTavf>m9Hd=&i}ER<y*41a(}O6nC^d9
z{O>L1Td}EE%u}C#UwY~-%Ue~WSC%8czpHWd7W1v5!YgK1*ngt0@K24$n^pd=Jc$wi
zf35j{%lUS#_A94I^xs{%{TB0WQtd0|dCtF;V*8fhZ3g2j!FJximCyK=;BEfcD?wl3
zf0Rx3mgsH1$19O{>HjVJ<1O;rIrLZLz>5EHM*S_-+quhEDwpd2!%XH|*tb)5udoX>
z|JelIKi!2lf&Et|yvF|^%>S0=ZLs+to{Oe`C-nRl|83Oq6<@6NKZ-%VC3+i3c_muu
b_+P^+@1?;Ze)}-s*ALRKR{B%tZ%6+Rs1GVa
--- a/mobile/android/gradle/gradle/wrapper/gradle-wrapper.properties
+++ b/mobile/android/gradle/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Sun Dec 21 20:16:49 PST 2014
+#Sun Oct 18 17:00:46 PDT 2015
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.7-bin.zip
--- a/mobile/android/gradle/gradlew
+++ b/mobile/android/gradle/gradlew
@@ -37,21 +37,16 @@ case "`uname`" in
   Darwin* )
     darwin=true
     ;;
   MINGW* )
     msys=true
     ;;
 esac
 
-# For Cygwin, ensure paths are in UNIX format before anything is touched.
-if $cygwin ; then
-    [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
-fi
-
 # Attempt to set APP_HOME
 # Resolve links: $0 may be a link
 PRG="$0"
 # Need this for relative symlinks.
 while [ -h "$PRG" ] ; do
     ls=`ls -ld "$PRG"`
     link=`expr "$ls" : '.*-> \(.*\)$'`
     if expr "$link" : '/.*' > /dev/null; then
@@ -109,16 +104,17 @@ fi
 if $darwin; then
     GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
 fi
 
 # For Cygwin, switch paths to Windows format before running java
 if $cygwin ; then
     APP_HOME=`cygpath --path --mixed "$APP_HOME"`
     CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
 
     # We build the pattern for arguments to be converted via cygpath
     ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
     SEP=""
     for dir in $ROOTDIRSRAW ; do
         ROOTDIRS="$ROOTDIRS$SEP$dir"
         SEP="|"
     done
deleted file mode 100644
--- a/mobile/android/gradle/preprocessed_code/AndroidManifest.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="org.mozilla.gecko.preprocessed_code">
-
-</manifest>
deleted file mode 100644
--- a/mobile/android/gradle/preprocessed_code/build.gradle
+++ /dev/null
@@ -1,53 +0,0 @@
-apply plugin: 'com.android.library'
-
-android {
-    compileSdkVersion 23
-    buildToolsVersion "23.0.1"
-
-    defaultConfig {
-        targetSdkVersion 22
-        minSdkVersion 9
-    }
-
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_7
-        targetCompatibility JavaVersion.VERSION_1_7
-    }
-
-    lintOptions {
-        abortOnError false
-    }
-
-    sourceSets {
-        main {
-            java {
-                srcDir "${project.buildDir}/generated/source/java"
-
-                srcDir 'src/adjust/java'
-                if (mozconfig.substs.MOZ_INSTALL_TRACKING) {
-                    exclude 'org/mozilla/gecko/adjust/StubAdjustHelper.java'
-                } else {
-                    exclude 'org/mozilla/gecko/adjust/AdjustHelper.java'
-                }
-            }
-        }
-    }
-}
-
-task syncGeneratedSources(type: Sync) {
-    into("${project.buildDir}/generated/source/java")
-    from("${topobjdir}/mobile/android/base/generated/preprocessed")
-}
-
-android.libraryVariants.all { variant ->
-    // variant does not expose its generate sources task.
-    def name = variant.buildType.name
-    def generateSourcesTask = tasks.findByName("generate${name.capitalize()}Sources")
-    generateSourcesTask.dependsOn syncGeneratedSources
-}
-
-dependencies {
-    if (mozconfig.substs.MOZ_INSTALL_TRACKING) {
-        compile project(':thirdparty_adjust_sdk')
-    }
-}
deleted file mode 100644
--- a/mobile/android/gradle/preprocessed_resources/AndroidManifest.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="org.mozilla.gecko.preprocessed_resources">
-
-</manifest>
deleted file mode 100644
--- a/mobile/android/gradle/preprocessed_resources/build.gradle
+++ /dev/null
@@ -1,44 +0,0 @@
-apply plugin: 'com.android.library'
-
-android {
-    compileSdkVersion 23
-    buildToolsVersion "23.0.1"
-
-    defaultConfig {
-        targetSdkVersion 22
-        minSdkVersion 9
-    }
-
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_7
-        targetCompatibility JavaVersion.VERSION_1_7
-    }
-
-    lintOptions {
-        abortOnError false
-    }
-
-    sourceSets {
-        main {
-            res {
-                srcDir "${project.buildDir}/generated/source/preprocessed_resources"
-            }
-        }
-    }
-}
-
-task syncPreprocessedResources(type: Sync) {
-    into("${project.buildDir}/generated/source/preprocessed_resources")
-    from("${topobjdir}/mobile/android/base/res")
-}
-
-android.libraryVariants.all { variant ->
-    // variant does not expose its generate debug res values task.
-    def name = variant.buildType.name
-    def generateResValuesTask = tasks.findByName("generate${name.capitalize()}ResValues")
-    generateResValuesTask.dependsOn syncPreprocessedResources
-}
-
-dependencies {
-    compile project(':branding')
-}
--- a/mobile/android/gradle/settings.gradle
+++ b/mobile/android/gradle/settings.gradle
@@ -20,29 +20,23 @@ if (proc.exitValue() != 0) {
 }
 
 import groovy.json.JsonSlurper
 def slurper = new JsonSlurper()
 def json = slurper.parseText(standardOutput.toString())
 
 include ':app'
 include ':base'
-include ':branding'
 include ':omnijar'
-include ':preprocessed_code'
-include ':preprocessed_resources'
 include ':thirdparty'
 
 def gradleRoot = new File("${json.topobjdir}/mobile/android/gradle")
 project(':app').projectDir = new File(gradleRoot, 'app')
 project(':base').projectDir = new File(gradleRoot, 'base')
-project(':branding').projectDir = new File(gradleRoot, 'branding')
 project(':omnijar').projectDir = new File(gradleRoot, 'omnijar')
-project(':preprocessed_code').projectDir = new File(gradleRoot, 'preprocessed_code')
-project(':preprocessed_resources').projectDir = new File(gradleRoot, 'preprocessed_resources')
 project(':thirdparty').projectDir = new File(gradleRoot, 'thirdparty')
 
 if (json.substs.MOZ_INSTALL_TRACKING) {
     include ':thirdparty_adjust_sdk'
     project(':thirdparty_adjust_sdk').projectDir = new File(gradleRoot, 'thirdparty_adjust_sdk')
 }
 
 // The Gradle instance is shared between settings.gradle and all the
--- a/mobile/android/mach_commands.py
+++ b/mobile/android/mach_commands.py
@@ -75,19 +75,16 @@ class MachCommands(MachCommandBase):
         conditions=[conditions.is_android])
     def gradle_install(self, quiet=False):
         import mozpack.manifests
         m = mozpack.manifests.InstallManifest()
 
         def srcdir(dst, src):
             m.add_symlink(os.path.join(self.topsrcdir, src), dst)
 
-        def objdir(dst, src):
-            m.add_symlink(os.path.join(self.topobjdir, src), dst)
-
         srcdir('build.gradle', 'mobile/android/gradle/build.gradle')
         srcdir('settings.gradle', 'mobile/android/gradle/settings.gradle')
 
         m.add_pattern_copy(os.path.join(self.topsrcdir, 'mobile/android/gradle/gradle/wrapper'), '**', 'gradle/wrapper')
         m.add_copy(os.path.join(self.topsrcdir, 'mobile/android/gradle/gradlew'), 'gradlew')
 
         defines = {
             'topsrcdir': self.topsrcdir,
@@ -98,44 +95,31 @@ class MachCommands(MachCommandBase):
             'gradle.properties',
             defines=defines,
             deps=os.path.join(self.topobjdir, 'mobile/android/gradle/.deps/gradle.properties.pp'))
         m.add_preprocess(os.path.join(self.topsrcdir, 'mobile/android/gradle/local.properties.in'),
             'local.properties',
             defines=defines,
             deps=os.path.join(self.topobjdir, 'mobile/android/gradle/.deps/local.properties.pp'))
 
-        srcdir('branding/build.gradle', 'mobile/android/gradle/branding/build.gradle')
-        srcdir('branding/src/main/AndroidManifest.xml', 'mobile/android/gradle/branding/AndroidManifest.xml')
-        srcdir('branding/src/main/res', os.path.join(self.substs['MOZ_BRANDING_DIRECTORY'], 'res'))
-
-        srcdir('preprocessed_code/build.gradle', 'mobile/android/gradle/preprocessed_code/build.gradle')
-        srcdir('preprocessed_code/src/main/AndroidManifest.xml', 'mobile/android/gradle/preprocessed_code/AndroidManifest.xml')
-        srcdir('preprocessed_code/src/adjust/java/org/mozilla/gecko/adjust', 'mobile/android/base/adjust')
-
-        srcdir('preprocessed_resources/build.gradle', 'mobile/android/gradle/preprocessed_resources/build.gradle')
-        srcdir('preprocessed_resources/src/main/AndroidManifest.xml', 'mobile/android/gradle/preprocessed_resources/AndroidManifest.xml')
-
         srcdir('thirdparty/build.gradle', 'mobile/android/gradle/thirdparty/build.gradle')
         srcdir('thirdparty/src/main/AndroidManifest.xml', 'mobile/android/gradle/thirdparty/AndroidManifest.xml')
         srcdir('thirdparty/src/main/java', 'mobile/android/thirdparty')
 
         srcdir('thirdparty_adjust_sdk/build.gradle', 'mobile/android/gradle/thirdparty_adjust_sdk/build.gradle')
         srcdir('thirdparty_adjust_sdk/src/main/AndroidManifest.xml', 'mobile/android/gradle/thirdparty_adjust_sdk/AndroidManifest.xml')
 
         srcdir('omnijar/build.gradle', 'mobile/android/gradle/omnijar/build.gradle')
         srcdir('omnijar/src/main/java/locales', 'mobile/android/locales')
         srcdir('omnijar/src/main/java/chrome', 'mobile/android/chrome')
         srcdir('omnijar/src/main/java/components', 'mobile/android/components')
         srcdir('omnijar/src/main/java/modules', 'mobile/android/modules')
         srcdir('omnijar/src/main/java/themes', 'mobile/android/themes')
 
         srcdir('app/build.gradle', 'mobile/android/gradle/app/build.gradle')
-        objdir('app/src/main/AndroidManifest.xml', 'mobile/android/base/AndroidManifest.xml')
-        objdir('app/src/androidTest/AndroidManifest.xml', 'build/mobile/robocop/AndroidManifest.xml')
         srcdir('app/src/androidTest/res', 'build/mobile/robocop/res')
         srcdir('app/src/androidTest/assets', 'mobile/android/tests/browser/robocop/assets')
         # Test code.
         srcdir('app/src/robocop_harness/org/mozilla/gecko', 'build/mobile/robocop')
         srcdir('app/src/robocop/org/mozilla/gecko/tests', 'mobile/android/tests/browser/robocop')
         srcdir('app/src/background/org/mozilla/gecko/background', 'mobile/android/tests/background/junit3/src')
         srcdir('app/src/browser', 'mobile/android/tests/browser/junit3/src')
         srcdir('app/src/javaaddons', 'mobile/android/tests/javaaddons/src')
@@ -150,16 +134,17 @@ class MachCommands(MachCommandBase):
         srcdir('base/src/main/java/org/mozilla/search', 'mobile/android/search/java/org/mozilla/search')
         srcdir('base/src/main/java/org/mozilla/javaaddons', 'mobile/android/javaaddons/java/org/mozilla/javaaddons')
         srcdir('base/src/webrtc_audio_device/java', 'media/webrtc/trunk/webrtc/modules/audio_device/android/java/src')
         srcdir('base/src/webrtc_video_capture/java', 'media/webrtc/trunk/webrtc/modules/video_capture/android/java/src')
         srcdir('base/src/webrtc_video_render/java', 'media/webrtc/trunk/webrtc/modules/video_render/android/java/src')
         srcdir('base/src/main/res', 'mobile/android/base/resources')
         srcdir('base/src/main/assets', 'mobile/android/app/assets')
         srcdir('base/src/crashreporter/res', 'mobile/android/base/crashreporter/res')
+        srcdir('base/src/branding/res', os.path.join(self.substs['MOZ_BRANDING_DIRECTORY'], 'res'))
         # JUnit 4 test code.
         srcdir('base/src/background_junit4', 'mobile/android/tests/background/junit4/src')
         srcdir('base/resources/background_junit4', 'mobile/android/tests/background/junit4/resources')
 
         manifest_path = os.path.join(self.topobjdir, 'mobile', 'android', 'gradle.manifest')
         with FileAvoidWrite(manifest_path) as f:
             m.write(fileobj=f)
 
--- a/mobile/android/tests/browser/chrome/chrome.ini
+++ b/mobile/android/tests/browser/chrome/chrome.ini
@@ -22,13 +22,14 @@ support-files =
 [test_java_addons.html]
 [test_jni.html]
 [test_migrate_ui.html]
 [test_network_manager.html]
 [test_offline_page.html]
 [test_reader_view.html]
 [test_resource_substitutions.html]
 [test_restricted_profiles.html]
+[test_selectoraddtab.html]
 [test_session_form_data.html]
 [test_shared_preferences.html]
 [test_simple_discovery.html]
 [test_video_discovery.html]
 [test_web_channel.html]
new file mode 100644
--- /dev/null
+++ b/mobile/android/tests/browser/chrome/test_selectoraddtab.html
@@ -0,0 +1,105 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1216047
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 1216047</title>
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SpawnTask.js"></script>
+  <link rel="stylesheet" type="text/css" href="chrome://global/skin"/>
+  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
+  <script type="application/javascript" src="head.js"></script>
+  <script type="application/javascript;version=1.7">
+
+  "use strict";
+
+  const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
+
+  Cu.import("resource://gre/modules/Services.jsm");
+  Cu.import("resource://gre/modules/Messaging.jsm");
+  Cu.import("resource://gre/modules/Task.jsm");
+
+  function promiseTabEvent(container, eventType) {
+    return new Promise((resolve) => {
+      function handle(event) {
+        info("Received event " + eventType + " from container");
+        container.removeEventListener(eventType, handle, true);
+        resolve(event);
+      }
+
+      container.addEventListener(eventType, handle, true);
+      info("Now waiting for " + eventType + " event from container");
+    });
+  }
+
+  // The chrome window
+  let chromeWin;
+
+  // Track the <browser>s where the tests are happening
+  let browserBlank;
+  let browserTest;
+
+  const kTestPage = "http://mochi.test:8888/chrome/mobile/android/tests/browser/chrome/basic_article.html";
+
+  add_task(function* test_selectOrAdd() {
+    chromeWin = Services.wm.getMostRecentWindow("navigator:browser");
+    let BrowserApp = chromeWin.BrowserApp;
+
+    SimpleTest.registerCleanupFunction(function() {
+      BrowserApp.closeTab(BrowserApp.getTabForBrowser(browserBlank));
+      BrowserApp.closeTab(BrowserApp.getTabForBrowser(browserTest));
+    });
+
+    // Add a new tab with a blank page
+    browserBlank = BrowserApp.addTab("about:blank", { selected: true, parentId: BrowserApp.selectedTab.id }).browser;
+
+    // Now, let's force the target browser to be added
+    browserTest = BrowserApp.selectOrAddTab(kTestPage, { selected: true, parentId: BrowserApp.selectedTab.id }).browser;
+    yield promiseBrowserEvent(browserTest, "DOMContentLoaded");
+
+    // Check that basic_article is now selected
+    is(BrowserApp.selectedBrowser, browserTest, "Target browser is selected after being added.");
+
+    // Switch back to about:blank
+    BrowserApp.selectTab(BrowserApp.getTabForBrowser(browserBlank));
+    yield promiseTabEvent(BrowserApp.deck, "TabSelect");
+
+    // Check that about:blank is selected
+    is(BrowserApp.selectedBrowser, browserBlank, "about:blank is selected.");
+
+    // Use selectOrAddTab to select the existing tab
+    BrowserApp.selectOrAddTab(kTestPage, { selected: true, parentId: BrowserApp.selectedTab.id }).browser;
+    yield promiseTabEvent(BrowserApp.deck, "TabSelect");
+
+    // Check that basic_article is now selected
+    is(BrowserApp.selectedBrowser, browserTest, "Target browser is selected.");
+
+    // Switch back to about:blank
+    BrowserApp.selectTab(BrowserApp.getTabForBrowser(browserBlank));
+    yield promiseTabEvent(BrowserApp.deck, "TabSelect");
+
+    // Check that about:blank is selected
+    is(BrowserApp.selectedBrowser, browserBlank, "about:blank is selected.");
+
+    // Use selectOrAddTab to select the existing tab using the startsWith flag
+    BrowserApp.selectOrAddTab(kTestPage, { selected: true, parentId: BrowserApp.selectedTab.id }, { startsWith: kTestPage }).browser;
+    yield promiseTabEvent(BrowserApp.deck, "TabSelect");
+
+    // Check that basic_article is now selected
+    is(BrowserApp.selectedBrowser, browserTest, "Target browser is selected.");
+  });
+
+  </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1216047">Mozilla Bug 1216047</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
--- a/toolkit/components/alerts/nsAlertsUtils.cpp
+++ b/toolkit/components/alerts/nsAlertsUtils.cpp
@@ -5,58 +5,27 @@
 #include "nsAlertsUtils.h"
 
 #include "nsCOMPtr.h"
 #include "nsContentUtils.h"
 #include "nsIStringBundle.h"
 #include "nsIURI.h"
 #include "nsXPIDLString.h"
 
-#define ALERTS_BUNDLE "chrome://alerts/locale/alert.properties"
-
 /* static */
 bool
 nsAlertsUtils::IsActionablePrincipal(nsIPrincipal* aPrincipal)
 {
   return aPrincipal &&
          !nsContentUtils::IsSystemOrExpandedPrincipal(aPrincipal) &&
          !aPrincipal->GetIsNullPrincipal();
 }
 
 /* static */
 void
-nsAlertsUtils::GetSource(nsIPrincipal* aPrincipal, nsAString& aSource)
-{
-  nsAutoString hostPort;
-  GetSourceHostPort(aPrincipal, hostPort);
-  if (hostPort.IsEmpty()) {
-    return;
-  }
-  nsCOMPtr<nsIStringBundleService> stringService(
-    mozilla::services::GetStringBundleService());
-  if (!stringService) {
-    return;
-  }
-  nsCOMPtr<nsIStringBundle> alertsBundle;
-  if (NS_WARN_IF(NS_FAILED(stringService->CreateBundle(ALERTS_BUNDLE,
-      getter_AddRefs(alertsBundle))))) {
-    return;
-  }
-  const char16_t* params[1] = { hostPort.get() };
-  nsXPIDLString result;
-  if (NS_WARN_IF(NS_FAILED(
-      alertsBundle->FormatStringFromName(MOZ_UTF16("source.label"), params, 1,
-      getter_Copies(result))))) {
-    return;
-  }
-  aSource = result;
-}
-
-/* static */
-void
 nsAlertsUtils::GetSourceHostPort(nsIPrincipal* aPrincipal,
                                  nsAString& aHostPort)
 {
   if (!IsActionablePrincipal(aPrincipal)) {
     return;
   }
   nsCOMPtr<nsIURI> principalURI;
   if (NS_WARN_IF(NS_FAILED(
--- a/toolkit/components/alerts/nsAlertsUtils.h
+++ b/toolkit/components/alerts/nsAlertsUtils.h
@@ -18,22 +18,15 @@ public:
    * Indicates whether an alert from |aPrincipal| should include the source
    * string and action buttons. Returns false if |aPrincipal| is |nullptr|, or
    * a system, expanded, or null principal.
    */
   static bool
   IsActionablePrincipal(nsIPrincipal* aPrincipal);
 
   /**
-   * Sets |aSource| to the localized notification source string, or an empty
-   * string if |aPrincipal| is not actionable.
-   */
-  static void
-  GetSource(nsIPrincipal* aPrincipal, nsAString& aSource);
-
-  /**
    * Sets |aHostPort| to the host and port from |aPrincipal|'s URI, or an
    * empty string if |aPrincipal| is not actionable.
    */
   static void
   GetSourceHostPort(nsIPrincipal* aPrincipal, nsAString& aHostPort);
 };
 #endif /* nsAlertsUtils_h */
--- a/toolkit/components/alerts/nsXULAlerts.cpp
+++ b/toolkit/components/alerts/nsXULAlerts.cpp
@@ -140,17 +140,17 @@ nsXULAlerts::ShowAlertNotification(const
   rv = argsArray->AppendElement(ifptr);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // The source contains the host and port of the site that sent the
   // notification. It is empty for system alerts.
   nsCOMPtr<nsISupportsString> scriptableAlertSource (do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID));
   NS_ENSURE_TRUE(scriptableAlertSource, NS_ERROR_FAILURE);
   nsAutoString source;
-  nsAlertsUtils::GetSource(aPrincipal, source);
+  nsAlertsUtils::GetSourceHostPort(aPrincipal, source);
   scriptableAlertSource->SetData(source);
   rv = argsArray->AppendElement(scriptableAlertSource);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIDOMWindow> newWindow;
   nsAutoCString features("chrome,dialog=yes,titlebar=no,popup=yes");
   if (aInPrivateBrowsing) {
     features.AppendLiteral(",private");
--- a/toolkit/components/alerts/resources/content/alert.js
+++ b/toolkit/components/alerts/resources/content/alert.js
@@ -27,24 +27,38 @@ function prefillAlertInfo() {
   // arguments[2] --> the alert text
   // arguments[3] --> is the text clickable?
   // arguments[4] --> the alert cookie to be passed back to the listener
   // arguments[5] --> the alert origin reported by the look and feel
   // arguments[6] --> bidi
   // arguments[7] --> lang
   // arguments[8] --> replaced alert window (nsIDOMWindow)
   // arguments[9] --> an optional callback listener (nsIObserver)
-  // arguments[10] -> the localized alert source string
+  // arguments[10] -> the nsIURI.hostPort of the origin, optional
 
   switch (window.arguments.length) {
     default:
     case 11: {
       if (window.arguments[10]) {
-        document.getElementById('alertBox').setAttribute('hasOrigin', true);
-        document.getElementById('alertSourceLabel').setAttribute('value', window.arguments[10]);
+        let alertBox = document.getElementById("alertBox");
+        alertBox.setAttribute("hasOrigin", true);
+
+        let hostPort = window.arguments[10];
+        const ALERT_BUNDLE = Services.strings.createBundle(
+          "chrome://alerts/locale/alert.properties");
+        let label = document.getElementById("alertSourceLabel");
+        label.setAttribute("value",
+          ALERT_BUNDLE.formatStringFromName("source.label",
+                                            [hostPort],
+                                            1));
+        let disableForOrigin = document.getElementById("disableForOriginMenuItem");
+        disableForOrigin.setAttribute("label",
+          ALERT_BUNDLE.formatStringFromName("webActions.disableForOrigin.label",
+                                            [hostPort],
+                                            1));
       }
     }
     case 10:
       gAlertListener = window.arguments[9];
     case 9:
       gReplacedWindow = window.arguments[8];
     case 8:
       if (window.arguments[7]) {
@@ -212,16 +226,21 @@ function onAlertClick() {
   if (alertBox.getAttribute("animate") == "true") {
     // Closed when the animation ends.
     alertBox.setAttribute("clicked", "true");
   } else {
     window.close();
   }
 }
 
+function disableForOrigin() {
+  gAlertListener.observe(null, "alertdisablecallback", gAlertCookie);
+  onAlertClose();
+}
+
 function onAlertClose() {
   let alertBox = document.getElementById("alertBox");
   if (alertBox.getAttribute("animate") == "true") {
     // Closed when the animation ends.
     alertBox.setAttribute("closing", "true");
   } else {
     window.close();
   }
--- a/toolkit/components/alerts/resources/content/alert.xul
+++ b/toolkit/components/alerts/resources/content/alert.xul
@@ -38,17 +38,23 @@
         <image id="alertImage"/>
       </hbox>
 
       <vbox id="alertTextBox" class="alertTextBox">
         <label id="alertTextLabel" class="alertText plain"/>
         <spacer flex="1"/>
         <box id="alertFooter">
           <label id="alertSourceLabel" class="alertSource plain"/>
-          <button type="menu" id="alertSettings" tooltiptext="&settings.label;"/>
+          <button type="menu" id="alertSettings" tooltiptext="&settings.label;"
+                  onclick="event.stopPropagation();">
+            <menupopup position="after_end">
+              <menuitem id="disableForOriginMenuItem"
+                        oncommand="disableForOrigin();"/>
+            </menupopup>
+          </button>
         </box>
       </vbox>
     </box>
   </vbox>
 
   <!-- This method is called inline because we want to make sure we establish the width
        and height of the alert before we fire the onload handler. -->
   <script type="application/javascript">prefillAlertInfo();</script>
--- a/toolkit/locales/en-US/chrome/alerts/alert.properties
+++ b/toolkit/locales/en-US/chrome/alerts/alert.properties
@@ -3,15 +3,17 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 # LOCALIZATION NOTE(closeButton.title): Used as the close button text for web notifications on OS X.
 # This should ideally match the string that OS X uses for the close button on alert-type
 # notifications. OS X will truncate the value if it's too long.
 closeButton.title = Close
 # LOCALIZATION NOTE(actionButton.label): Used as the button label to provide more actions on OS X notifications. OS X will truncate this if it's too long.
 actionButton.label = …
-webActions.disable.label = Disable notifications from this site
+# LOCALIZATION NOTE(webActions.disableForOrigin.label): %S is replaced
+# with the hostname origin of the notification.
+webActions.disableForOrigin.label = Disable notifications from %S
 
 # LOCALIZATION NOTE(source.label): Used to show the URL of the site that
 # sent the notification (e.g., "via mozilla.org"). "%1$S" is the source host
 # and port.
 source.label=via %1$S
 webActions.settings.label = Notification settings
--- a/toolkit/themes/shared/alert-common.css
+++ b/toolkit/themes/shared/alert-common.css
@@ -60,25 +60,24 @@ label {
 }
 
 #alertSettings {
   -moz-appearance: none;
   background-color: transparent;
   border-width: 0;
   min-width: 0;
   list-style-image: url("chrome://mozapps/skin/extensions/utilities.svg#utilities");
-  visibility: hidden; /* Temporary until bug 1209602 or bug 1205172 is fixed. */
 }
 
 #alertSettings:hover {
   background-color: rgba(107,107,107,.2);
   border-radius: 20px;
 }
 
-#alertSettings["open"],
+#alertSettings[open],
 #alertSettings:hover:active {
   background-color: rgba(107,107,107,.4);
 }
 
 #alertSettings > .button-box > .button-menu-dropmarker,
 #alertSettings > .button-box > .box-inherit > .button-text {
   display: none;
 }
--- a/widget/cocoa/OSXNotificationCenter.mm
+++ b/widget/cocoa/OSXNotificationCenter.mm
@@ -240,37 +240,49 @@ OSXNotificationCenter::ShowAlertNotifica
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
   Class unClass = NSClassFromString(@"NSUserNotification");
   id<FakeNSUserNotification> notification = [[unClass alloc] init];
   notification.title = nsCocoaUtils::ToNSString(aAlertTitle);
 
   nsAutoString hostPort;
   nsAlertsUtils::GetSourceHostPort(aPrincipal, hostPort);
+  nsCOMPtr<nsIStringBundle> bundle;
+  nsCOMPtr<nsIStringBundleService> sbs = do_GetService(NS_STRINGBUNDLE_CONTRACTID);
+  nsresult rv = sbs->CreateBundle("chrome://alerts/locale/alert.properties", getter_AddRefs(bundle));
+
   if (!hostPort.IsEmpty()) {
-    notification.subtitle = nsCocoaUtils::ToNSString(hostPort);
+    const char16_t* formatStrings[] = { hostPort.get() };
+    nsXPIDLString notificationSource;
+    bundle->FormatStringFromName(NS_LITERAL_STRING("source.label").get(),
+                                 formatStrings,
+                                 ArrayLength(formatStrings),
+                                 getter_Copies(notificationSource));
+    notification.subtitle = nsCocoaUtils::ToNSString(notificationSource);
   }
 
   notification.informativeText = nsCocoaUtils::ToNSString(aAlertText);
   notification.soundName = NSUserNotificationDefaultSoundName;
   notification.hasActionButton = NO;
 
   // If this is not an application/extension alert, show additional actions dealing with permissions.
   if (nsAlertsUtils::IsActionablePrincipal(aPrincipal)) {
-    nsCOMPtr<nsIStringBundleService> sbs = do_GetService(NS_STRINGBUNDLE_CONTRACTID);
-    nsCOMPtr<nsIStringBundle> bundle;
-    nsresult rv = sbs->CreateBundle("chrome://alerts/locale/alert.properties", getter_AddRefs(bundle));
     if (NS_SUCCEEDED(rv)) {
       nsXPIDLString closeButtonTitle, actionButtonTitle, disableButtonTitle, settingsButtonTitle;
       bundle->GetStringFromName(NS_LITERAL_STRING("closeButton.title").get(),
                                 getter_Copies(closeButtonTitle));
       bundle->GetStringFromName(NS_LITERAL_STRING("actionButton.label").get(),
                                 getter_Copies(actionButtonTitle));
-      bundle->GetStringFromName(NS_LITERAL_STRING("webActions.disable.label").get(),
-                                getter_Copies(disableButtonTitle));
+      if (!hostPort.IsEmpty()) {
+        const char16_t* formatStrings[] = { hostPort.get() };
+        bundle->FormatStringFromName(NS_LITERAL_STRING("webActions.disableForOrigin.label").get(),
+                                     formatStrings,
+                                     ArrayLength(formatStrings),
+                                     getter_Copies(disableButtonTitle));
+      }
       bundle->GetStringFromName(NS_LITERAL_STRING("webActions.settings.label").get(),
                                 getter_Copies(settingsButtonTitle));
 
       notification.hasActionButton = YES;
       notification.otherButtonTitle = nsCocoaUtils::ToNSString(closeButtonTitle);
       notification.actionButtonTitle = nsCocoaUtils::ToNSString(actionButtonTitle);
       [(NSObject*)notification setValue:@(YES) forKey:@"_showsButtons"];
       [(NSObject*)notification setValue:@(YES) forKey:@"_alwaysShowAlternateActionMenu"];