Merge mozilla-central to autoland. a=merge CLOSED TREE
authorTiberius Oros <toros@mozilla.com>
Wed, 22 Aug 2018 00:59:19 +0300
changeset 487778 9dcb4b6cb5104adb3bb4f576daeea3d63e30f4b7
parent 487777 0d1ee61d3377e5f843c8db0ae51e777ee2e857c7 (current diff)
parent 487750 7c96ad3ab6731287646616610e159447c69d6beb (diff)
child 487779 58b3e727210440e6a7c26cf664ddc03f8d616822
push id9719
push userffxbld-merge
push dateFri, 24 Aug 2018 17:49:46 +0000
treeherdermozilla-beta@719ec98fba77 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone63.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge mozilla-central to autoland. a=merge CLOSED TREE
testing/talos/talos/tests/devtools/addon/content/pages/custom/debugger/js/testfile.js
xpcom/ds/nsINIProcessor.js
xpcom/ds/nsINIProcessor.manifest
xpcom/tests/unit/test_iniProcessor.js
--- a/.gitignore
+++ b/.gitignore
@@ -1,16 +1,17 @@
 # .gitignore - List of filenames git should ignore
 
 # Filenames that should be ignored wherever they appear
 *~
 *.pyc
 *.pyo
 TAGS
 tags
+compile_commands.json
 # Ignore ID generated by idutils and un-ignore id directory (for Indonesian locale)
 ID
 !id/
 .DS_Store*
 *.pdb
 *.egg-info
 
 # Vim swap files.
@@ -36,18 +37,20 @@ security/manager/.nss.checkout
 
 # Build directories
 /obj*/
 
 # gecko.log is generated by various test harnesses
 /gecko.log
 
 # Build directories for js shell
-_DBG.OBJ/
-_OPT.OBJ/
+*_DBG.OBJ/
+*_OPT.OBJ/
+/js/src/*-obj/
+/js/src/obj-*/
 
 # SpiderMonkey configury
 js/src/configure
 js/src/old-configure
 js/src/autom4te.cache
 # SpiderMonkey test result logs
 js/src/tests/results-*.html
 js/src/tests/results-*.txt
@@ -139,11 +142,11 @@ tps_result.json
 
 # Ignore files created when running a reftest.
 lextab.py
 
 # tup database
 /.tup
 
 # Ignore Visual Studio Code workspace files.
-.vscode/*
+.vscode/
 !.vscode/extensions.json
 !.vscode/tasks.json
--- a/.hgignore
+++ b/.hgignore
@@ -6,16 +6,17 @@
 (?i)(^|/)TAGS$
 (^|/)ID$
 (^|/)\.DS_Store$
 \.pdb
 \.egg-info
 \.gcda
 \.gcno
 \.gcov
+compile_commands\.json
 
 # Vim swap files.
 ^\.sw.$
 .[^/]*\.sw.$
 
 # Emacs directory variable files.
 \.dir-locals\.el
 
@@ -37,16 +38,17 @@
 
 # gecko.log is generated by various test harnesses
 ^gecko\.log
 
 # Build directories for js shell
 _DBG\.OBJ/
 _OPT\.OBJ/
 ^js/src/.*-obj/
+^js/src/obj-.*/
 
 # SpiderMonkey configury
 ^js/src/configure$
 ^js/src/old-configure$
 ^js/src/autom4te.cache$
 # SpiderMonkey test result logs
 ^js/src/tests/results-.*\.(html|txt)$
 ^js/src/devtools/rootAnalysis/t/out
--- a/browser/actors/LightweightThemeChild.jsm
+++ b/browser/actors/LightweightThemeChild.jsm
@@ -6,16 +6,18 @@
 
 var EXPORTED_SYMBOLS = ["LightweightThemeChild"];
 
 ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 /**
  * LightweightThemeChild forwards theme data to in-content pages.
+ * It is both instantiated by the traditional Actor mechanism,
+ * and also manually within the sidebar JS global (which has no message manager)
  */
 class LightweightThemeChild extends ActorChild {
   constructor(mm) {
     super(mm);
 
     this.init();
   }
 
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -3,33 +3,30 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
 @namespace html url("http://www.w3.org/1999/xhtml");
 
 :root {
   --panelui-subview-transition-duration: 150ms;
   --lwt-additional-images: none;
-  --lwt-background-alignment: right top;
   --lwt-background-tiling: no-repeat;
 }
 
 :root:-moz-lwtheme {
   color: var(--lwt-text-color) !important;
 }
 
 :root:-moz-lwtheme {
   background-color: var(--lwt-accent-color) !important;
-  background-image: var(--lwt-additional-images) !important;
-  background-position: var(--lwt-background-alignment) !important;
-  background-repeat: var(--lwt-background-tiling) !important;
 }
 
 :root:-moz-lwtheme[lwtheme-image] {
-  background-image: var(--lwt-header-image), var(--lwt-additional-images) !important;
+  background-image: var(--lwt-header-image) !important;
+  background-position: right top !important;
 }
 
 :root:-moz-lwtheme:-moz-window-inactive {
   background-color: var(--lwt-accent-color-inactive, var(--lwt-accent-color)) !important;
 }
 
 #main-window:not([chromehidden~="toolbar"]) {
 %ifdef XP_MACOSX
--- a/browser/base/content/contentTheme.js
+++ b/browser/base/content/contentTheme.js
@@ -27,16 +27,53 @@ const inContentVariableMap = [
       const {r, g, b, a} = rgbaChannels;
       if (!_isTextColorDark(r, g, b)) {
         element.setAttribute("lwt-newtab-brighttext", "true");
       }
 
       return `rgba(${r}, ${g}, ${b}, ${a})`;
     },
   }],
+  ["--lwt-sidebar-background-color", {
+    lwtProperty: "sidebar",
+  }],
+  ["--lwt-sidebar-text-color", {
+    lwtProperty: "sidebar_text",
+    processColor(rgbaChannels, element) {
+      if (!rgbaChannels) {
+        element.removeAttribute("lwt-sidebar");
+        element.removeAttribute("lwt-sidebar-brighttext");
+        return null;
+      }
+
+      element.setAttribute("lwt-sidebar", "true");
+      const {r, g, b, a} = rgbaChannels;
+      if (!_isTextColorDark(r, g, b)) {
+        element.setAttribute("lwt-sidebar-brighttext", "true");
+      }
+
+      return `rgba(${r}, ${g}, ${b}, ${a})`;
+    },
+  }],
+  ["--lwt-sidebar-highlight-background-color", {
+    lwtProperty: "sidebar_highlight",
+  }],
+  ["--lwt-sidebar-highlight-text-color", {
+    lwtProperty: "sidebar_highlight_text",
+    processColor(rgbaChannels, element) {
+      if (!rgbaChannels) {
+        element.removeAttribute("lwt-sidebar-highlight");
+        return null;
+      }
+      element.setAttribute("lwt-sidebar-highlight", "true");
+
+      const {r, g, b, a} = rgbaChannels;
+      return `rgba(${r}, ${g}, ${b}, ${a})`;
+    },
+  }],
 ];
 
 /**
  * ContentThemeController handles theme updates sent by the frame script.
  * To be able to use ContentThemeController, you must add your page to the whitelist
  * in LightweightThemeChildListener.jsm
  */
 const ContentThemeController = {
@@ -53,17 +90,19 @@ const ContentThemeController = {
    * @param {Object} event object containing the theme update.
    */
   handleEvent({ type, detail }) {
     if (type == "LightweightTheme:Set") {
       let {data} = detail;
       if (!data) {
         data = {};
       }
-      this._setProperties(document.body, data);
+      // XUL documents don't have a body
+      const element = document.body ? document.body : document.documentElement;
+      this._setProperties(element, data);
     }
   },
 
   /**
    * Set a CSS variable to a given value
    * @param {Element} elem The element where the CSS variable should be added.
    * @param {string} variableName The CSS variable to set.
    * @param {string} value The new value of the CSS variable.
@@ -85,17 +124,17 @@ const ContentThemeController = {
     for (let [cssVarName, definition] of inContentVariableMap) {
       const {
         lwtProperty,
         processColor,
       } = definition;
       let value = themeData[lwtProperty];
 
       if (processColor) {
-        value = processColor(value, document.body);
+        value = processColor(value, elem);
       } else if (value) {
         const {r, g, b, a} = value;
         value = `rgba(${r}, ${g}, ${b}, ${a})`;
       }
 
       this._setProperty(elem, cssVarName, value);
     }
   },
--- a/browser/base/content/test/favicons/browser.ini
+++ b/browser/base/content/test/favicons/browser.ini
@@ -46,8 +46,12 @@ support-files =
 [browser_redirect.js]
 support-files =
   file_favicon_redirect.html
   file_favicon_redirect.ico
   file_favicon_redirect.ico^headers^
 [browser_rooticon.js]
 support-files =
   blank.html
+[browser_mixed_content.js]
+support-files =
+  file_insecure_favicon.html
+  file_favicon.png
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/favicons/browser_mixed_content.js
@@ -0,0 +1,17 @@
+add_task(async () => {
+  const testPath = "https://example.com/browser/browser/base/content/test/favicons/file_insecure_favicon.html";
+  const expectedIcon = "http://example.com/browser/browser/base/content/test/favicons/file_favicon.png";
+
+  let tab = BrowserTestUtils.addTab(gBrowser, testPath);
+  gBrowser.selectedTab = tab;
+  let browser = tab.linkedBrowser;
+
+  let faviconPromise = waitForLinkAvailable(browser);
+  await BrowserTestUtils.browserLoaded(browser);
+  let iconURI = await faviconPromise;
+  is(iconURI, expectedIcon, "Got correct icon.");
+
+  ok(gIdentityHandler._isMixedPassiveContentLoaded, "Should have seen mixed content.");
+
+  BrowserTestUtils.removeTab(tab);
+});
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/favicons/file_insecure_favicon.html
@@ -0,0 +1,11 @@
+<!DOCTYPE HTML>
+<html>
+  <head>
+    <meta charset='utf-8'>
+    <title>Favicon Test for mixed content</title>
+    <link rel="icon" type="image/png" href="http://example.com/browser/browser/base/content/test/favicons/file_favicon.png" />
+  </head>
+  <body>
+    Favicon!!
+  </body>
+</html>
--- a/browser/base/content/test/general/browser.ini
+++ b/browser/base/content/test/general/browser.ini
@@ -137,16 +137,17 @@ skip-if = toolkit == "cocoa"
 [browser_bug484315.js]
 # DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
 [browser_bug491431.js]
 # DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
 [browser_bug495058.js]
 skip-if = coverage # Bug 1439493
 # DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
 [browser_bug519216.js]
+skip-if = true # Bug 1478159
 # DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
 [browser_bug520538.js]
 # DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
 [browser_bug521216.js]
 # DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
 [browser_bug533232.js]
 # DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
 [browser_bug537013.js]
--- a/browser/base/content/test/performance/browser_startup_content.js
+++ b/browser/base/content/test/performance/browser_startup_content.js
@@ -51,17 +51,16 @@ const whitelist = {
     "resource:///actors/AboutReaderChild.jsm",
     "resource:///actors/BrowserTabChild.jsm",
     "resource:///modules/ContentMetaHandler.jsm",
     "resource:///actors/LinkHandlerChild.jsm",
     "resource:///actors/PageStyleChild.jsm",
     "resource://gre/modules/ActorChild.jsm",
     "resource://gre/modules/ActorManagerChild.jsm",
     "resource://gre/modules/E10SUtils.jsm",
-    "resource://gre/modules/PrivateBrowsingUtils.jsm",
     "resource://gre/modules/ReaderMode.jsm",
     "resource://gre/modules/WebProgressChild.jsm",
 
     // Pocket
     "chrome://pocket/content/AboutPocket.jsm",
 
     // Telemetry
     "resource://gre/modules/TelemetryController.jsm", // bug 1470339
--- a/browser/base/content/test/sidebar/browser_sidebar_keys.js
+++ b/browser/base/content/test/sidebar/browser_sidebar_keys.js
@@ -1,12 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 async function testSidebarKeyToggle(key, options, expectedSidebarId) {
+  EventUtils.synthesizeMouseAtCenter(gURLBar, {});
   let promiseShown = BrowserTestUtils.waitForEvent(window, "SidebarShown");
   EventUtils.synthesizeKey(key, options);
   await promiseShown;
   Assert.equal(document.getElementById("sidebar-box")
                        .getAttribute("sidebarcommand"), expectedSidebarId);
   EventUtils.synthesizeKey(key, options);
   Assert.ok(!SidebarUI.isOpen);
 }
--- a/browser/components/places/content/bookmarksSidebar.js
+++ b/browser/components/places/content/bookmarksSidebar.js
@@ -2,16 +2,17 @@
 /* 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/. */
 
 /* Shared Places Import - change other consumers if you change this: */
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 XPCOMUtils.defineLazyModuleGetters(this, {
+  LightweightThemeChild: "resource:///actors/LightweightThemeChild.jsm",
   PlacesUtils: "resource://gre/modules/PlacesUtils.jsm",
   PlacesUIUtils: "resource:///modules/PlacesUIUtils.jsm",
   PlacesTransactions: "resource://gre/modules/PlacesTransactions.jsm",
   PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.jsm",
 });
 XPCOMUtils.defineLazyScriptGetter(this, "PlacesTreeView",
                                   "chrome://browser/content/places/treeView.js");
 XPCOMUtils.defineLazyScriptGetter(this, ["PlacesInsertionPoint", "PlacesController",
@@ -20,16 +21,27 @@ XPCOMUtils.defineLazyScriptGetter(this, 
 /* End Shared Places Import */
 
 function init() {
   let uidensity = window.top.document.documentElement.getAttribute("uidensity");
   if (uidensity) {
     document.documentElement.setAttribute("uidensity", uidensity);
   }
 
+  /* Listen for sidebar theme changes */
+  let themeListener = new LightweightThemeChild({
+    content: window,
+    chromeOuterWindowID: window.top.windowUtils.outerWindowID,
+    docShell: window.docShell,
+  });
+
+  window.addEventListener("unload", () => {
+    themeListener.cleanup();
+  });
+
   document.getElementById("bookmarks-view").place =
     "place:type=" + Ci.nsINavHistoryQueryOptions.RESULTS_AS_ROOTS_QUERY;
 }
 
 function searchBookmarks(aSearchString) {
   var tree = document.getElementById("bookmarks-view");
   if (!aSearchString) {
     // eslint-disable-next-line no-self-assign
--- a/browser/components/places/content/bookmarksSidebar.xul
+++ b/browser/components/places/content/bookmarksSidebar.xul
@@ -26,16 +26,18 @@
       aria-label="&bookmarksButton.label;">
 
   <script type="application/javascript"
           src="chrome://browser/content/places/bookmarksSidebar.js"/>
   <script type="application/javascript"
           src="chrome://global/content/globalOverlay.js"/>
   <script type="application/javascript"
           src="chrome://browser/content/utilityOverlay.js"/>
+  <script type="application/javascript"
+          src="chrome://browser/content/contentTheme.js"/>
 
 #include placesCommands.inc.xul
 #include ../../../../toolkit/content/editMenuCommands.inc.xul
 #include placesContextMenu.inc.xul
 #include bookmarksHistoryTooltip.inc.xul
 
   <hbox id="sidebar-search-container" align="center">
     <textbox id="search-box" flex="1" type="search"
--- a/browser/components/places/content/historySidebar.js
+++ b/browser/components/places/content/historySidebar.js
@@ -2,16 +2,17 @@
 /* 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/. */
 
 /* Shared Places Import - change other consumers if you change this: */
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 XPCOMUtils.defineLazyModuleGetters(this, {
+  LightweightThemeChild: "resource:///actors/LightweightThemeChild.jsm",
   PlacesUtils: "resource://gre/modules/PlacesUtils.jsm",
   PlacesUIUtils: "resource:///modules/PlacesUIUtils.jsm",
   PlacesTransactions: "resource://gre/modules/PlacesTransactions.jsm",
   PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.jsm",
 });
 XPCOMUtils.defineLazyScriptGetter(this, "PlacesTreeView",
                                   "chrome://browser/content/places/treeView.js");
 XPCOMUtils.defineLazyScriptGetter(this, ["PlacesInsertionPoint", "PlacesController",
@@ -27,16 +28,27 @@ var gHistoryGrouping = "";
 var gSearching = false;
 
 function HistorySidebarInit() {
   let uidensity = window.top.document.documentElement.getAttribute("uidensity");
   if (uidensity) {
     document.documentElement.setAttribute("uidensity", uidensity);
   }
 
+  /* Listen for sidebar theme changes */
+  let themeListener = new LightweightThemeChild({
+    content: window,
+    chromeOuterWindowID: window.top.windowUtils.outerWindowID,
+    docShell: window.docShell,
+  });
+
+  window.addEventListener("unload", () => {
+    themeListener.cleanup();
+  });
+
   gHistoryTree = document.getElementById("historyTree");
   gSearchBox = document.getElementById("search-box");
 
   gHistoryGrouping = document.getElementById("viewButton").
                               getAttribute("selectedsort");
 
   if (gHistoryGrouping == "site")
     document.getElementById("bysite").setAttribute("checked", "true");
--- a/browser/components/places/content/historySidebar.xul
+++ b/browser/components/places/content/historySidebar.xul
@@ -26,16 +26,18 @@
       aria-label="&historyButton.label;">
 
   <script type="application/javascript"
           src="chrome://browser/content/places/historySidebar.js"/>
   <script type="application/javascript"
           src="chrome://global/content/globalOverlay.js"/>
   <script type="application/javascript"
           src="chrome://browser/content/utilityOverlay.js"/>
+  <script type="application/javascript"
+          src="chrome://browser/content/contentTheme.js"/>
 
 #include ../../../../toolkit/content/editMenuCommands.inc.xul
 
 #include placesCommands.inc.xul
 
 #include ../../../../toolkit/content/editMenuKeys.inc.xul
 #ifdef XP_MACOSX
   <keyset id="editMenuKeysExtra">
--- a/browser/extensions/formautofill/FormAutofillContent.jsm
+++ b/browser/extensions/formautofill/FormAutofillContent.jsm
@@ -9,17 +9,16 @@
 /* eslint-disable no-use-before-define */
 
 "use strict";
 
 var EXPORTED_SYMBOLS = ["FormAutofillContent"];
 
 const Cm = Components.manager;
 
-ChromeUtils.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 ChromeUtils.defineModuleGetter(this, "AddressResult",
                                "resource://formautofill/ProfileAutoCompleteResult.jsm");
 ChromeUtils.defineModuleGetter(this, "CreditCardResult",
                                "resource://formautofill/ProfileAutoCompleteResult.jsm");
 ChromeUtils.defineModuleGetter(this, "FormAutofill",
@@ -27,16 +26,18 @@ ChromeUtils.defineModuleGetter(this, "Fo
 ChromeUtils.defineModuleGetter(this, "FormAutofillHandler",
                                "resource://formautofill/FormAutofillHandler.jsm");
 ChromeUtils.defineModuleGetter(this, "FormAutofillUtils",
                                "resource://formautofill/FormAutofillUtils.jsm");
 ChromeUtils.defineModuleGetter(this, "FormLikeFactory",
                                "resource://gre/modules/FormLikeFactory.jsm");
 ChromeUtils.defineModuleGetter(this, "InsecurePasswordUtils",
                                "resource://gre/modules/InsecurePasswordUtils.jsm");
+ChromeUtils.defineModuleGetter(this, "PrivateBrowsingUtils",
+                               "resource://gre/modules/PrivateBrowsingUtils.jsm");
 
 const formFillController = Cc["@mozilla.org/satchel/form-fill-controller;1"]
                              .getService(Ci.nsIFormFillController);
 const autocompleteController = Cc["@mozilla.org/autocomplete/controller;1"]
                              .getService(Ci.nsIAutoCompleteController);
 
 XPCOMUtils.defineLazyGetter(this, "ADDRESSES_COLLECTION_NAME",
                             () => FormAutofillUtils.ADDRESSES_COLLECTION_NAME);
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -280,18 +280,16 @@
 #ifdef XP_WIN
 @RESPATH@/browser/components/360seProfileMigrator.js
 @RESPATH@/browser/components/EdgeProfileMigrator.js
 @RESPATH@/browser/components/IEProfileMigrator.js
 #endif
 #ifdef XP_MACOSX
 @RESPATH@/browser/components/SafariProfileMigrator.js
 #endif
-@RESPATH@/components/nsINIProcessor.manifest
-@RESPATH@/components/nsINIProcessor.js
 @RESPATH@/components/nsPrompter.manifest
 @RESPATH@/components/nsPrompter.js
 @RESPATH@/components/SyncComponents.manifest
 @RESPATH@/components/Weave.js
 @RESPATH@/components/FxAccountsComponents.manifest
 @RESPATH@/components/FxAccountsPush.js
 @RESPATH@/components/CaptivePortalDetectComponents.manifest
 @RESPATH@/components/captivedetect.js
--- a/browser/modules/ThemeVariableMap.jsm
+++ b/browser/modules/ThemeVariableMap.jsm
@@ -79,9 +79,13 @@ const ThemeVariableMap = [
   ["--autocomplete-popup-highlight-color", {
     lwtProperty: "popup_highlight_text"
   }],
 ];
 
 const ThemeContentPropertyList = [
   "ntp_background",
   "ntp_text",
+  "sidebar",
+  "sidebar_highlight",
+  "sidebar_highlight_text",
+  "sidebar_text",
 ];
--- a/browser/themes/linux/browser.css
+++ b/browser/themes/linux/browser.css
@@ -149,18 +149,16 @@ menuitem.bookmark-item {
 %include ../shared/menupanel.inc.css
 
 /* Fullscreen window controls */
 
 #minimize-button,
 #restore-button,
 #close-button {
   -moz-appearance: none;
-  border: none;
-  margin: 0 !important;
   padding: 6px 12px;
   -moz-context-properties: stroke;
   stroke: currentColor;
   color: inherit;
 }
 
 #minimize-button {
   list-style-image: url(chrome://browser/skin/window-controls/minimize.svg);
--- a/browser/themes/linux/places/sidebar.css
+++ b/browser/themes/linux/places/sidebar.css
@@ -18,23 +18,16 @@
   margin: 1px 0;
   margin-inline-start: 4px;
 }
 
 #viewButton:-moz-focusring:not(:hover):not([open]) {
   outline: 1px dotted -moz-DialogText;
 }
 
-.sidebar-placesTree {
-  margin: 0;
-  color: inherit;
-  -moz-appearance: none;
-  background: transparent;
-}
-
 :root[uidensity=touch] #search-box,
 :root[uidensity=touch] .sidebar-placesTreechildren::-moz-tree-row {
   min-height: 32px;
 }
 
 .sidebar-placesTreechildren::-moz-tree-cell(leaf) ,
 .sidebar-placesTreechildren::-moz-tree-image(leaf) {
   cursor: pointer;
--- a/browser/themes/osx/browser.css
+++ b/browser/themes/osx/browser.css
@@ -42,19 +42,35 @@
   --panel-separator-color: rgba(249,249,250,.1);
 
   --arrowpanel-dimmed: rgba(249,249,250,.1);
   --arrowpanel-dimmed-further: rgba(249,249,250,.15);
   --arrowpanel-dimmed-even-further: rgba(249,249,250,.2);
 }
 
 #navigator-toolbox {
+  -moz-appearance: none;
   --tabs-border-color: rgba(0,0,0,.3);
 }
 
+/*
+  This is a workaround for Bug 1482157
+  -moz-appearance: toolbox; makes the macOS sheets attached to the element's
+  bottom border. We cannot put this property on the toolbox itself as it
+  cancels all backgrounds that are there, so we set it on the toolbox bottom
+  border.
+*/
+#navigator-toolbox::after {
+  -moz-appearance: toolbox;
+  height: 1px;
+  /* use inset box-shadow instead of border because -moz-appearance hides the border */
+  border: none;
+  box-shadow: inset 0 -1px var(--toolbox-border-bottom-color);
+}
+
 #tabbrowser-tabs {
   --tab-line-color: #0a84ff;
 }
 
 #navigator-toolbox toolbarbutton:-moz-lwtheme {
   color: inherit;
   text-shadow: inherit;
 }
--- a/browser/themes/osx/places/sidebar.css
+++ b/browser/themes/osx/places/sidebar.css
@@ -5,16 +5,19 @@
 /* Sidebars */
 
 %include ../../shared/places/sidebar.inc.css
 
 .sidebar-placesTree {
   margin: 0;
   /* Default font size is 11px on mac, so this is 12px */
   font-size: 1.0909rem;
+}
+
+.sidebar-panel:not([lwt-sidebar]) .sidebar-placesTree {
   -moz-appearance: -moz-mac-source-list;
   -moz-font-smoothing-background-color: -moz-mac-source-list;
 }
 
 :root[uidensity=touch] .sidebar-placesTreechildren::-moz-tree-row {
   min-height: 32px;
 }
 
--- a/browser/themes/shared/browser.inc.css
+++ b/browser/themes/shared/browser.inc.css
@@ -19,20 +19,29 @@
   --space-above-tabbar: 8px;
 }
 
 :root[sessionrestored]:-moz-lwtheme {
   transition: @themeTransition@;
 }
 
 /* Increase contrast of UI links on dark themes */
+
 :root[lwt-popup-brighttext] panel .text-link {
   color: @lwtPopupBrighttextLinkColor@;
 }
 
+/* Set additional backgrounds alignment relative to toolbox*/
+
+#navigator-toolbox:-moz-lwtheme {
+  background-image: var(--lwt-additional-images);
+  background-position: var(--lwt-background-alignment);
+  background-repeat: var(--lwt-background-tiling);
+}
+
 /* Toolbar / content area border */
 
 #navigator-toolbox::after {
   content: "";
   display: -moz-box;
   border-bottom: 1px solid var(--toolbox-border-bottom-color);
 }
 
--- a/browser/themes/shared/places/sidebar.inc.css
+++ b/browser/themes/shared/places/sidebar.inc.css
@@ -2,16 +2,61 @@
  * 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/. */
 
 .sidebar-panel {
   -moz-appearance: none;
   background-color: transparent;
 }
 
+/* Themed sidebars */
+
+.sidebar-panel[lwt-sidebar] {
+  background-color: var(--lwt-sidebar-background-color);
+  color: var(--lwt-sidebar-text-color);
+}
+
+.sidebar-panel[lwt-sidebar] .sidebar-placesTreechildren::-moz-tree-row(selected) {
+  background-color: hsla(0,0%,80%,.3);
+}
+
+.sidebar-panel[lwt-sidebar-brighttext] .sidebar-placesTreechildren::-moz-tree-row(selected) {
+  -moz-appearance: none;
+  background-color: rgba(249,249,250,.1);
+}
+
+.sidebar-panel[lwt-sidebar-brighttext] .sidebar-placesTreechildren::-moz-tree-image(selected),
+.sidebar-panel[lwt-sidebar-brighttext] .sidebar-placesTreechildren::-moz-tree-twisty(selected),
+.sidebar-panel[lwt-sidebar-brighttext] .sidebar-placesTreechildren::-moz-tree-cell-text(selected) {
+  color: var(--lwt-sidebar-text-color);
+}
+
+.sidebar-panel[lwt-sidebar-highlight] .sidebar-placesTreechildren::-moz-tree-row(selected,focus) {
+  -moz-appearance: none;
+  background-color: var(--lwt-sidebar-highlight-background-color);
+}
+
+.sidebar-panel[lwt-sidebar-highlight] .sidebar-placesTreechildren::-moz-tree-image(selected, focus),
+.sidebar-panel[lwt-sidebar-highlight] .sidebar-placesTreechildren::-moz-tree-twisty(selected, focus),
+.sidebar-panel[lwt-sidebar-highlight] .sidebar-placesTreechildren::-moz-tree-cell-text(selected, focus) {
+  color: var(--lwt-sidebar-highlight-text-color);
+}
+
+/* Sidebar tree */
+
+.sidebar-placesTree {
+  -moz-appearance: none;
+  background-color: transparent;
+  color: inherit;
+  border: 0;
+  margin: 0;
+}
+
+/* View button */
+
 #viewButton {
   -moz-appearance: none;
   border-radius: 4px;
   padding: 2px 4px;
   color: inherit;
 }
 
 #viewButton:hover {
--- a/browser/themes/windows/browser.css
+++ b/browser/themes/windows/browser.css
@@ -397,18 +397,16 @@ menuitem.bookmark-item {
 %include ../shared/menupanel.inc.css
 
 /* ::::: fullscreen window controls ::::: */
 
 #minimize-button,
 #restore-button,
 #close-button {
   -moz-appearance: none;
-  border: none;
-  margin: 0 !important;
   padding: 6px 12px;
   -moz-context-properties: stroke;
   stroke: currentColor;
   color: inherit;
 }
 
 #minimize-button {
   list-style-image: url(chrome://browser/skin/window-controls/minimize.svg);
--- a/browser/themes/windows/places/sidebar.css
+++ b/browser/themes/windows/places/sidebar.css
@@ -1,24 +1,16 @@
 /* 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/. */
 
 /* Sidebars */
 
 %include ../../shared/places/sidebar.inc.css
 
-.sidebar-placesTree {
-  -moz-appearance: none;
-  background-color: transparent;
-  color: inherit;
-  border: 0;
-  margin: 0;
-}
-
 :root[uidensity=touch] #search-box,
 :root[uidensity=touch] .sidebar-placesTreechildren::-moz-tree-row {
   min-height: 32px;
 }
 
 .sidebar-placesTreechildren::-moz-tree-cell,
 .sidebar-placesTreechildren::-moz-tree-twisty {
   padding: 0 4px;
--- a/build/autoconf/compiler-opts.m4
+++ b/build/autoconf/compiler-opts.m4
@@ -16,16 +16,19 @@ case "$target" in
     if test -z "$AS"; then
         case "${target_cpu}" in
         i*86)
             AS=ml;
             ;;
         x86_64)
             AS=ml64;
             ;;
+        aarch64)
+            AS=armasm64;
+            ;;
         esac
     fi
     if test -z "$MIDL"; then MIDL=midl; fi
 
     # need override this flag since we don't use $(LDFLAGS) for this.
     if test -z "$HOST_LDFLAGS" ; then
         HOST_LDFLAGS=" "
     fi
--- a/build/autoconf/icu.m4
+++ b/build/autoconf/icu.m4
@@ -86,16 +86,23 @@ AC_SUBST(USE_ICU)
 AC_SUBST(ICU_DATA_FILE)
 
 if test -n "$USE_ICU"; then
     dnl Source files that use ICU should have control over which parts of the ICU
     dnl namespace they want to use.
     AC_DEFINE(U_USING_ICU_NAMESPACE,0)
 
     if test -z "$MOZ_SYSTEM_ICU"; then
-        if test -z "$YASM" -a -z "$GNU_AS" -a "$COMPILE_ENVIRONMENT"; then
-            AC_MSG_ERROR([Building ICU requires either yasm or a GNU assembler. If you do not have either of those available for this platform you must use --without-intl-api])
-        fi
+        case "$OS_TARGET:$CPU_ARCH" in
+        WINNT:aarch64)
+            dnl we use non-yasm, non-GNU as solutions here.
+            ;;
+        *)
+            if test -z "$YASM" -a -z "$GNU_AS" -a "$COMPILE_ENVIRONMENT"; then
+                AC_MSG_ERROR([Building ICU requires either yasm or a GNU assembler. If you do not have either of those available for this platform you must use --without-intl-api])
+            fi
+            ;;
+        esac
         dnl We build ICU as a static library.
         AC_DEFINE(U_STATIC_IMPLEMENTATION)
     fi
 fi
 ])
--- a/build/moz.configure/toolchain.configure
+++ b/build/moz.configure/toolchain.configure
@@ -684,17 +684,17 @@ def default_c_compilers(host_or_target):
             gcc = tuple('%sgcc' % p for p in toolchain_prefix) + gcc
         # Android sets toolchain_prefix and android_clang_compiler, but
         # we want the latter to take precedence, because the latter can
         # point at clang, which is what we want to use.
         if android_clang_compiler and host_or_target is target:
             return (android_clang_compiler,) + gcc
 
         if host_or_target.kernel == 'WINNT':
-            return ('cl', 'clang-cl') + gcc + ('clang',)
+            return ('clang-cl', 'cl') + gcc + ('clang',)
         if host_or_target.kernel == 'Darwin':
             return ('clang',)
         if developer_options:
             return ('clang',) + gcc
         return gcc + ('clang',)
 
     return default_c_compilers
 
--- a/build/moz.configure/windows.configure
+++ b/build/moz.configure/windows.configure
@@ -454,17 +454,18 @@ def valid_mt(path):
     except subprocess.CalledProcessError:
         pass
     raise FatalCheckError('%s is not Microsoft Manifest Tool')
 
 
 set_config('MSMANIFEST_TOOL', depends(valid_mt)(lambda x: bool(x)))
 
 
-link = check_prog('LINKER', ('link.exe',), paths=toolchain_search_path)
+link = check_prog('LINKER', ('lld-link.exe', 'link.exe'),
+                  paths=toolchain_search_path)
 
 add_old_configure_assignment('LINKER', link)
 
 
 # Normally, we'd just have CC, etc. set to absolute paths, but the build system
 # doesn't currently handle properly the case where the paths contain spaces.
 # Additionally, there's the issue described in toolchain.configure, in
 # valid_compiler().
new file mode 100644
--- /dev/null
+++ b/config/external/icu/data/genicudata.py
@@ -0,0 +1,14 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+def main(output, data_file, data_symbol):
+    output.write('''    AREA .rdata,ALIGN=4,DATA,READONLY
+    EXPORT _{data_symbol}[DATA]
+_{data_symbol}
+    INCBIN {data_file}
+    END
+'''.format(data_file=data_file, data_symbol=data_symbol))
--- a/config/external/icu/data/moz.build
+++ b/config/external/icu/data/moz.build
@@ -9,19 +9,30 @@
 Library('icudata')
 
 if CONFIG['OS_ARCH'] == 'WINNT':
     if CONFIG['CPU_ARCH'] == 'x86':
         ASFLAGS += ['-DPREFIX']
 elif CONFIG['OS_ARCH'] == 'Darwin':
     ASFLAGS += ['-DPREFIX']
 
-ASFLAGS += [
+data_symbol = 'icudt%s_dat' % CONFIG['MOZ_ICU_VERSION']
+asflags = [
     '-DICU_DATA_FILE="%s"' % CONFIG['ICU_DATA_FILE'],
-    '-DICU_DATA_SYMBOL=icudt%s_dat' % CONFIG['MOZ_ICU_VERSION'],
+    '-DICU_DATA_SYMBOL=%s' % data_symbol,
 ]
 LOCAL_INCLUDES += ['.']
 
-if CONFIG['HAVE_YASM']:
+if CONFIG['OS_TARGET'] == 'WINNT' and CONFIG['CPU_ARCH'] == 'aarch64':
+    icudata = 'icudata.asm'
+    GENERATED_FILES += [icudata]
+    SOURCES += ['!%s' % icudata]
+    icudata = GENERATED_FILES[icudata]
+    icudata.script = 'genicudata.py'
+    icudata.inputs = [CONFIG['ICU_DATA_FILE']]
+    icudata.flags = [data_symbol]
+elif CONFIG['HAVE_YASM']:
     USE_YASM = True
     SOURCES += ['icudata.s']
+    ASFLAGS += asflags
 elif CONFIG['GNU_AS']:
     SOURCES += ['icudata_gas.S']
+    ASFLAGS += asflags
--- a/devtools/client/responsive.html/components/Toolbar.js
+++ b/devtools/client/responsive.html/components/Toolbar.js
@@ -2,144 +2,162 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const { PureComponent, createFactory } = require("devtools/client/shared/vendor/react");
 const dom = require("devtools/client/shared/vendor/react-dom-factories");
 const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
+const { connect } = require("devtools/client/shared/vendor/react-redux");
 
 const DevicePixelRatioMenu = createFactory(require("./DevicePixelRatioMenu"));
 const DeviceSelector = createFactory(require("./DeviceSelector"));
 const NetworkThrottlingMenu = createFactory(require("devtools/client/shared/components/throttling/NetworkThrottlingMenu"));
 const SettingsMenu = createFactory(require("./SettingsMenu"));
 const ViewportDimension = createFactory(require("./ViewportDimension"));
 
 const { getStr } = require("../utils/l10n");
 const Types = require("../types");
 
 class Toolbar extends PureComponent {
   static get propTypes() {
     return {
       devices: PropTypes.shape(Types.devices).isRequired,
       displayPixelRatio: Types.pixelRatio.value.isRequired,
+      leftAlignmentEnabled: PropTypes.bool.isRequired,
       networkThrottling: PropTypes.shape(Types.networkThrottling).isRequired,
-      reloadConditions: PropTypes.shape(Types.reloadConditions).isRequired,
-      screenshot: PropTypes.shape(Types.screenshot).isRequired,
-      selectedDevice: PropTypes.string.isRequired,
-      selectedPixelRatio: PropTypes.shape(Types.pixelRatio).isRequired,
-      touchSimulation: PropTypes.shape(Types.touchSimulation).isRequired,
-      viewport: PropTypes.shape(Types.viewport).isRequired,
       onChangeDevice: PropTypes.func.isRequired,
       onChangeNetworkThrottling: PropTypes.func.isRequired,
       onChangePixelRatio: PropTypes.func.isRequired,
       onChangeReloadCondition: PropTypes.func.isRequired,
       onChangeTouchSimulation: PropTypes.func.isRequired,
       onExit: PropTypes.func.isRequired,
       onRemoveDeviceAssociation: PropTypes.func.isRequired,
       onResizeViewport: PropTypes.func.isRequired,
       onRotateViewport: PropTypes.func.isRequired,
       onScreenshot: PropTypes.func.isRequired,
       onToggleLeftAlignment: PropTypes.func.isRequired,
       onUpdateDeviceModal: PropTypes.func.isRequired,
+      reloadConditions: PropTypes.shape(Types.reloadConditions).isRequired,
+      screenshot: PropTypes.shape(Types.screenshot).isRequired,
+      selectedDevice: PropTypes.string.isRequired,
+      selectedPixelRatio: PropTypes.shape(Types.pixelRatio).isRequired,
+      touchSimulation: PropTypes.shape(Types.touchSimulation).isRequired,
+      viewport: PropTypes.shape(Types.viewport).isRequired,
     };
   }
 
   render() {
     const {
       devices,
       displayPixelRatio,
+      leftAlignmentEnabled,
       networkThrottling,
-      reloadConditions,
-      screenshot,
-      selectedDevice,
-      selectedPixelRatio,
-      touchSimulation,
-      viewport,
       onChangeDevice,
       onChangeNetworkThrottling,
       onChangePixelRatio,
       onChangeReloadCondition,
       onChangeTouchSimulation,
       onExit,
       onRemoveDeviceAssociation,
       onResizeViewport,
       onRotateViewport,
       onScreenshot,
       onToggleLeftAlignment,
       onUpdateDeviceModal,
+      reloadConditions,
+      screenshot,
+      selectedDevice,
+      selectedPixelRatio,
+      touchSimulation,
+      viewport,
     } = this.props;
 
-    return dom.header(
-      { id: "toolbar" },
-      DeviceSelector({
-        devices,
-        selectedDevice,
-        viewportId: viewport.id,
-        onChangeDevice,
-        onResizeViewport,
-        onUpdateDeviceModal,
-      }),
-      dom.div(
-        { id: "toolbar-center-controls" },
-        ViewportDimension({
-          viewport,
-          onRemoveDeviceAssociation,
+    return (
+      dom.header(
+        {
+          id: "toolbar",
+          className: leftAlignmentEnabled ? "left-aligned" : "",
+        },
+        DeviceSelector({
+          devices,
+          onChangeDevice,
           onResizeViewport,
-        }),
-        dom.button({
-          id: "rotate-button",
-          className: "devtools-button",
-          onClick: () => onRotateViewport(viewport.id),
-          title: getStr("responsive.rotate"),
-        }),
-        dom.div({ className: "devtools-separator" }),
-        DevicePixelRatioMenu({
-          devices,
-          displayPixelRatio,
+          onUpdateDeviceModal,
           selectedDevice,
-          selectedPixelRatio,
-          onChangePixelRatio,
+          viewportId: viewport.id,
         }),
-        dom.div({ className: "devtools-separator" }),
-        NetworkThrottlingMenu({
-          networkThrottling,
-          onChangeNetworkThrottling,
-          useTopLevelWindow: true,
-        }),
-        dom.div({ className: "devtools-separator" }),
-        dom.button({
-          id: "touch-simulation-button",
-          className: "devtools-button" +
-                     (touchSimulation.enabled ? " checked" : ""),
-          title: (touchSimulation.enabled ?
-            getStr("responsive.disableTouch") : getStr("responsive.enableTouch")),
-          onClick: () => onChangeTouchSimulation(!touchSimulation.enabled),
-        })
-      ),
-      dom.div(
-        { id: "toolbar-end-controls" },
-        dom.button({
-          id: "screenshot-button",
-          className: "devtools-button",
-          title: getStr("responsive.screenshot"),
-          onClick: onScreenshot,
-          disabled: screenshot.isCapturing,
-        }),
-        SettingsMenu({
-          reloadConditions,
-          onChangeReloadCondition,
-          onToggleLeftAlignment,
-        }),
-        dom.div({ className: "devtools-separator" }),
-        dom.button({
-          id: "exit-button",
-          className: "devtools-button",
-          title: getStr("responsive.exit"),
-          onClick: onExit,
-        })
+        leftAlignmentEnabled ?
+          dom.div({ className: "devtools-separator" })
+          :
+          null,
+        dom.div(
+          { id: "toolbar-center-controls" },
+          ViewportDimension({
+            onRemoveDeviceAssociation,
+            onResizeViewport,
+            viewport,
+          }),
+          dom.button({
+            id: "rotate-button",
+            className: "devtools-button",
+            onClick: () => onRotateViewport(viewport.id),
+            title: getStr("responsive.rotate"),
+          }),
+          dom.div({ className: "devtools-separator" }),
+          DevicePixelRatioMenu({
+            devices,
+            displayPixelRatio,
+            onChangePixelRatio,
+            selectedDevice,
+            selectedPixelRatio,
+          }),
+          dom.div({ className: "devtools-separator" }),
+          NetworkThrottlingMenu({
+            networkThrottling,
+            onChangeNetworkThrottling,
+            useTopLevelWindow: true,
+          }),
+          dom.div({ className: "devtools-separator" }),
+          dom.button({
+            id: "touch-simulation-button",
+            className: "devtools-button" +
+                       (touchSimulation.enabled ? " checked" : ""),
+            title: (touchSimulation.enabled ?
+              getStr("responsive.disableTouch") : getStr("responsive.enableTouch")),
+            onClick: () => onChangeTouchSimulation(!touchSimulation.enabled),
+          })
+        ),
+        dom.div(
+          { id: "toolbar-end-controls" },
+          dom.button({
+            id: "screenshot-button",
+            className: "devtools-button",
+            title: getStr("responsive.screenshot"),
+            onClick: onScreenshot,
+            disabled: screenshot.isCapturing,
+          }),
+          SettingsMenu({
+            reloadConditions,
+            onChangeReloadCondition,
+            onToggleLeftAlignment,
+          }),
+          dom.div({ className: "devtools-separator" }),
+          dom.button({
+            id: "exit-button",
+            className: "devtools-button",
+            title: getStr("responsive.exit"),
+            onClick: onExit,
+          })
+        )
       )
     );
   }
 }
 
-module.exports = Toolbar;
+const mapStateToProps = state => {
+  return {
+    leftAlignmentEnabled: state.ui.leftAlignmentEnabled,
+  };
+};
+
+module.exports = connect(mapStateToProps)(Toolbar);
--- a/devtools/client/responsive.html/index.css
+++ b/devtools/client/responsive.html/index.css
@@ -67,24 +67,33 @@ body,
   border-bottom: 1px solid var(--theme-splitter-color);
   display: grid;
   grid-template-columns: min-content auto min-content;
   width: 100%;
   min-height: 29px;
   -moz-user-select: none;
 }
 
+#toolbar.left-aligned {
+  grid-template-columns: min-content min-content min-content auto;
+}
+
 #toolbar-center-controls,
 #toolbar-end-controls {
   display: flex;
   align-items: center;
 }
 
 #toolbar-center-controls {
   justify-self: center;
+  margin: 1px;
+}
+
+#toolbar.left-aligned #toolbar-end-controls {
+  justify-self: end;
 }
 
 #rotate-button::before {
   background-image: url("./images/rotate-viewport.svg");
 }
 
 #touch-simulation-button::before {
   background-image: url("./images/touch-events.svg");
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -768,21 +768,22 @@ ContentParent::MinTabSelect(const nsTArr
   }
 
   return candidate.forget();
 }
 
 static bool
 CreateTemporaryRecordingFile(nsAString& aResult)
 {
-  unsigned long elapsed = (TimeStamp::Now() - TimeStamp::ProcessCreation()).ToMilliseconds();
-
+  static int sNumTemporaryRecordings;
   nsCOMPtr<nsIFile> file;
   return !NS_FAILED(NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(file)))
-      && !NS_FAILED(file->AppendNative(nsPrintfCString("Recording%lu", elapsed)))
+      && !NS_FAILED(file->AppendNative(nsPrintfCString("TempRecording.%d.%d",
+                                                       base::GetCurrentProcId(),
+                                                       ++sNumTemporaryRecordings)))
       && !NS_FAILED(file->GetPath(aResult));
 }
 
 /*static*/ already_AddRefed<ContentParent>
 ContentParent::GetNewOrUsedBrowserProcess(Element* aFrameElement,
                                           const nsAString& aRemoteType,
                                           ProcessPriority aPriority,
                                           ContentParent* aOpener,
@@ -1444,21 +1445,23 @@ ContentParent::ShutDownProcess(ShutDownM
   }
 
   // Shutting down by sending a shutdown message works differently than the
   // other methods. We first call Shutdown() in the child. After the child is
   // ready, it calls FinishShutdown() on us. Then we close the channel.
   if (aMethod == SEND_SHUTDOWN_MESSAGE) {
     if (const char* directory = recordreplay::parent::SaveAllRecordingsDirectory()) {
       // Save a recording for the child process before it shuts down.
-      unsigned long elapsed = (TimeStamp::Now() - TimeStamp::ProcessCreation()).ToMilliseconds();
+      static int sNumSavedRecordings;
       nsCOMPtr<nsIFile> file;
       if (!NS_FAILED(NS_NewNativeLocalFile(nsDependentCString(directory), false,
                                            getter_AddRefs(file))) &&
-          !NS_FAILED(file->AppendNative(nsPrintfCString("Recording%lu", elapsed)))) {
+          !NS_FAILED(file->AppendNative(nsPrintfCString("Recording.%d.%d",
+                                                        base::GetCurrentProcId(),
+                                                        ++sNumSavedRecordings)))) {
         bool unused;
         SaveRecording(file, &unused);
       }
     }
 
     if (mIPCOpen && !mShutdownPending) {
       // Stop sending input events with input priority when shutting down.
       SetInputPriorityEventEnabled(false);
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -39,16 +39,17 @@
 #include "mozilla/layers/ImageBridgeChild.h"
 #include "mozilla/layers/InputAPZContext.h"
 #include "mozilla/layers/LayerTransactionChild.h"
 #include "mozilla/layers/ShadowLayers.h"
 #include "mozilla/layers/WebRenderLayerManager.h"
 #include "mozilla/layout/RenderFrameChild.h"
 #include "mozilla/layout/RenderFrameParent.h"
 #include "mozilla/plugins/PPluginWidgetChild.h"
+#include "mozilla/recordreplay/ParentIPC.h"
 #include "mozilla/LookAndFeel.h"
 #include "mozilla/MouseEvents.h"
 #include "mozilla/Move.h"
 #include "mozilla/PresShell.h"
 #include "mozilla/ProcessHangMonitor.h"
 #include "mozilla/ScopeExit.h"
 #include "mozilla/Services.h"
 #include "mozilla/StaticPtr.h"
@@ -335,17 +336,20 @@ private:
         if (!mReadyToDelete) {
           // This time run this runnable at input priority.
           mReadyToDelete = true;
           MOZ_ALWAYS_SUCCEEDS(NS_DispatchToCurrentThread(this));
           return NS_OK;
         }
 
         // Check in case ActorDestroy was called after RecvDestroy message.
-        if (mTabChild->IPCOpen()) {
+        // Middleman processes with their own recording child process avoid
+        // sending a delete message, so that the parent process does not
+        // receive two deletes for the same actor.
+        if (mTabChild->IPCOpen() && !recordreplay::parent::IsMiddlemanWithRecordingChild()) {
           Unused << PBrowserChild::Send__delete__(mTabChild);
         }
 
         mTabChild = nullptr;
         return NS_OK;
     }
 };
 
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -1,35 +1,33 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* 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/. */
 
 #include "MediaFormatReader.h"
 
+#include "AllocationPolicy.h"
 #include "MediaData.h"
 #include "MediaInfo.h"
 #include "VideoFrameContainer.h"
 #include "VideoUtils.h"
 #include "mozilla/AbstractThread.h"
 #include "mozilla/CDMProxy.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/NotNull.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/SharedThreadPool.h"
 #include "mozilla/StaticPrefs.h"
 #include "mozilla/TaskQueue.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/Unused.h"
 #include "nsContentUtils.h"
 #include "nsPrintfCString.h"
-#ifdef MOZ_WIDGET_ANDROID
-#include "mozilla/jni/Utils.h"
-#endif
 
 #include <algorithm>
 #include <map>
 #include <queue>
 
 using namespace mozilla::media;
 
 static mozilla::LazyLogModule sFormatDecoderLog("MediaFormatReader");
@@ -133,172 +131,16 @@ private:
   static StaticMutex sGPUCrashMapMutex;
 };
 
 std::map<MediaDecoderOwnerID, GPUProcessCrashTelemetryLogger::GPUCrashData>
 GPUProcessCrashTelemetryLogger::sGPUCrashDataMap;
 StaticMutex GPUProcessCrashTelemetryLogger::sGPUCrashMapMutex;
 
 /**
- * This is a singleton which controls the number of decoders that can be
- * created concurrently. Before calling PDMFactory::CreateDecoder(), Alloc()
- * must be called to get a token object as a permission to create a decoder.
- * The token should stay alive until Shutdown() is called on the decoder.
- * The destructor of the token will restore the decoder count so it is available
- * for next calls of Alloc().
- */
-class GlobalAllocPolicy
-{
-  using TrackType = TrackInfo::TrackType;
-
-public:
-  class Token
-  {
-    NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Token)
-  protected:
-    virtual ~Token() {}
-  };
-
-  using Promise = MozPromise<RefPtr<Token>, bool, true>;
-
-  // Acquire a token for decoder creation. Thread-safe.
-  auto Alloc() -> RefPtr<Promise>;
-
-  // Called by ClearOnShutdown() to delete the singleton.
-  void operator=(decltype(nullptr));
-
-  // Get the singleton for the given track type. Thread-safe.
-  static GlobalAllocPolicy& Instance(TrackType aTrack);
-
-private:
-  class AutoDeallocToken;
-  using PromisePrivate = Promise::Private;
-  GlobalAllocPolicy();
-  ~GlobalAllocPolicy();
-  // Called by the destructor of TokenImpl to restore the decoder limit.
-  void Dealloc();
-  // Decrement the decoder limit and resolve a promise if available.
-  void ResolvePromise(ReentrantMonitorAutoEnter& aProofOfLock);
-
-  // Protect access to Instance().
-  static StaticMutex sMutex;
-
-  ReentrantMonitor mMonitor;
-  // The number of decoders available for creation.
-  int mDecoderLimit;
-  // Requests to acquire tokens.
-  std::queue<RefPtr<PromisePrivate>> mPromises;
-};
-
-StaticMutex GlobalAllocPolicy::sMutex;
-
-class GlobalAllocPolicy::AutoDeallocToken : public Token
-{
-public:
-  explicit AutoDeallocToken(GlobalAllocPolicy& aPolicy) : mPolicy(aPolicy) { }
-
-private:
-  ~AutoDeallocToken()
-  {
-    mPolicy.Dealloc();
-  }
-
-  GlobalAllocPolicy& mPolicy; // reference to a singleton object.
-};
-
-static int32_t
-MediaDecoderLimitDefault()
-{
-#ifdef MOZ_WIDGET_ANDROID
-  if (jni::GetAPIVersion() < 18) {
-    // Older Android versions have broken support for multiple simultaneous
-    // decoders, see bug 1278574.
-    return 1;
-  }
-#endif
-  // Otherwise, set no decoder limit.
-  return -1;
-}
-
-GlobalAllocPolicy::GlobalAllocPolicy()
-  : mMonitor("DecoderAllocPolicy::mMonitor")
-  , mDecoderLimit(MediaDecoderLimitDefault())
-{
-  SystemGroup::Dispatch(
-    TaskCategory::Other,
-    NS_NewRunnableFunction("GlobalAllocPolicy::GlobalAllocPolicy", [this]() {
-      ClearOnShutdown(this, ShutdownPhase::ShutdownThreads);
-    }));
-}
-
-GlobalAllocPolicy::~GlobalAllocPolicy()
-{
-  while (!mPromises.empty()) {
-    RefPtr<PromisePrivate> p = mPromises.front().forget();
-    mPromises.pop();
-    p->Reject(true, __func__);
-  }
-}
-
-GlobalAllocPolicy&
-GlobalAllocPolicy::Instance(TrackType aTrack)
-{
-  StaticMutexAutoLock lock(sMutex);
-  if (aTrack == TrackType::kAudioTrack) {
-    static auto sAudioPolicy = new GlobalAllocPolicy();
-    return *sAudioPolicy;
-  } else {
-    static auto sVideoPolicy = new GlobalAllocPolicy();
-    return *sVideoPolicy;
-  }
-}
-
-auto
-GlobalAllocPolicy::Alloc() -> RefPtr<Promise>
-{
-  // No decoder limit set.
-  if (mDecoderLimit < 0) {
-    return Promise::CreateAndResolve(new Token(), __func__);
-  }
-
-  ReentrantMonitorAutoEnter mon(mMonitor);
-  RefPtr<PromisePrivate> p = new PromisePrivate(__func__);
-  mPromises.push(p);
-  ResolvePromise(mon);
-  return p.forget();
-}
-
-void
-GlobalAllocPolicy::Dealloc()
-{
-  ReentrantMonitorAutoEnter mon(mMonitor);
-  ++mDecoderLimit;
-  ResolvePromise(mon);
-}
-
-void
-GlobalAllocPolicy::ResolvePromise(ReentrantMonitorAutoEnter& aProofOfLock)
-{
-  MOZ_ASSERT(mDecoderLimit >= 0);
-
-  if (mDecoderLimit > 0 && !mPromises.empty()) {
-    --mDecoderLimit;
-    RefPtr<PromisePrivate> p = mPromises.front().forget();
-    mPromises.pop();
-    p->Resolve(new AutoDeallocToken(*this), __func__);
-  }
-}
-
-void
-GlobalAllocPolicy::operator=(std::nullptr_t)
-{
-  delete this;
-}
-
-/**
  * This class addresses the concern of bug 1339310 comment 4 where the Widevine
  * CDM doesn't support running multiple instances of a video decoder at once per
  * CDM instance by sequencing the order of decoder creation and shutdown. Note
  * this class addresses a different concern from that of GlobalAllocPolicy which
  * controls a system-wide number of decoders while this class control a per-MFR
  * number (which is one per CDM requirement).
  */
 class LocalAllocPolicy
@@ -616,18 +458,16 @@ public:
     if (data.mDecoder) {
       mOwner->mShutdownPromisePool->ShutdownDecoder(data.mDecoder.forget());
     }
     data.mStage = Stage::None;
     MOZ_ASSERT(!data.mToken);
   }
 
 private:
-  class Wrapper;
-
   enum class Stage : int8_t
   {
     None,
     WaitForToken,
     CreateDecoder,
     WaitForInit
   };
 
@@ -658,82 +498,16 @@ private:
 void
 MediaFormatReader::DecoderFactory::CreateDecoder(TrackType aTrack)
 {
   MOZ_ASSERT(aTrack == TrackInfo::kAudioTrack ||
              aTrack == TrackInfo::kVideoTrack);
   RunStage(aTrack == TrackInfo::kAudioTrack ? mAudio : mVideo);
 }
 
-class MediaFormatReader::DecoderFactory::Wrapper : public MediaDataDecoder
-{
-  using Token = GlobalAllocPolicy::Token;
-
-public:
-  Wrapper(already_AddRefed<MediaDataDecoder> aDecoder,
-          already_AddRefed<Token> aToken)
-    : mDecoder(aDecoder)
-    , mToken(aToken)
-  {
-    DecoderDoctorLogger::LogConstructionAndBase(
-      "MediaFormatReader::DecoderFactory::Wrapper",
-      this,
-      static_cast<const MediaDataDecoder*>(this));
-    DecoderDoctorLogger::LinkParentAndChild(
-      "MediaFormatReader::DecoderFactory::Wrapper",
-      this,
-      "decoder",
-      mDecoder.get());
-  }
-
-  ~Wrapper()
-  {
-    DecoderDoctorLogger::LogDestruction(
-      "MediaFormatReader::DecoderFactory::Wrapper", this);
-  }
-
-  RefPtr<InitPromise> Init() override { return mDecoder->Init(); }
-  RefPtr<DecodePromise> Decode(MediaRawData* aSample) override
-  {
-    return mDecoder->Decode(aSample);
-  }
-  RefPtr<DecodePromise> Drain() override { return mDecoder->Drain(); }
-  RefPtr<FlushPromise> Flush() override { return mDecoder->Flush(); }
-  bool IsHardwareAccelerated(nsACString& aFailureReason) const override
-  {
-    return mDecoder->IsHardwareAccelerated(aFailureReason);
-  }
-  nsCString GetDescriptionName() const override
-  {
-    return mDecoder->GetDescriptionName();
-  }
-  void SetSeekThreshold(const TimeUnit& aTime) override
-  {
-    mDecoder->SetSeekThreshold(aTime);
-  }
-  bool SupportDecoderRecycling() const override
-  {
-    return mDecoder->SupportDecoderRecycling();
-  }
-  RefPtr<ShutdownPromise> Shutdown() override
-  {
-    RefPtr<MediaDataDecoder> decoder = mDecoder.forget();
-    RefPtr<Token> token = mToken.forget();
-    return decoder->Shutdown()->Then(
-      AbstractThread::GetCurrent(), __func__,
-      [token]() {
-        return ShutdownPromise::CreateAndResolve(true, __func__);
-      });
-  }
-
-private:
-  RefPtr<MediaDataDecoder> mDecoder;
-  RefPtr<Token> mToken;
-};
-
 void
 MediaFormatReader::DecoderFactory::RunStage(Data& aData)
 {
   switch (aData.mStage) {
     case Stage::None: {
       MOZ_ASSERT(!aData.mToken);
       aData.mPolicy->Alloc()->Then(
         mOwner->OwnerThread(), __func__,
@@ -772,17 +546,18 @@ MediaFormatReader::DecoderFactory::RunSt
                  this,
                  DDLogCategory::Log,
                  "create_decoder_error",
                  rv);
         mOwner->NotifyError(aData.mTrack, rv);
         return;
       }
 
-      aData.mDecoder = new Wrapper(aData.mDecoder.forget(), aData.mToken.forget());
+      aData.mDecoder =
+        new AllocationWrapper(aData.mDecoder.forget(), aData.mToken.forget());
       DecoderDoctorLogger::LinkParentAndChild(
         aData.mDecoder.get(),
         "decoder",
         "MediaFormatReader::DecoderFactory",
         this);
 
       DoInitDecoder(aData);
       aData.mStage = Stage::WaitForInit;
--- a/dom/media/mediacapabilities/MediaCapabilities.cpp
+++ b/dom/media/mediacapabilities/MediaCapabilities.cpp
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "MediaCapabilities.h"
+#include "AllocationPolicy.h"
 #include "Benchmark.h"
 #include "DecoderTraits.h"
 #include "Layers.h"
 #include "MediaInfo.h"
 #include "MediaRecorder.h"
 #include "PDMFactory.h"
 #include "VPXDecoder.h"
 #include "mozilla/Move.h"
@@ -323,78 +324,85 @@ MediaCapabilities::DecodingInfo(
         // MediaDataDecoder keeps a reference to the config object, so we must
         // keep it alive until the decoder has been shutdown.
         CreateDecoderParams params{ *config,
                                     taskQueue,
                                     compositor,
                                     CreateDecoderParams::VideoFrameRate(
                                       frameRate),
                                     TrackInfo::kVideoTrack };
-
-        RefPtr<PDMFactory> pdm = new PDMFactory();
-        RefPtr<MediaDataDecoder> decoder = pdm->CreateDecoder(params);
-        if (!decoder) {
-          return CapabilitiesPromise::CreateAndReject(
-            MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, "Can't create decoder"),
-            __func__);
-        }
-        // We now query the decoder to determine if it's power efficient.
-        return decoder->Init()->Then(
+        return AllocationWrapper::CreateDecoder(params)->Then(
           taskQueue,
           __func__,
-          [taskQueue, decoder, frameRate, config = std::move(config)](
-            const MediaDataDecoder::InitPromise::ResolveOrRejectValue&
-              aValue) mutable {
-            RefPtr<CapabilitiesPromise> p;
+          [taskQueue, frameRate, config = std::move(config)](
+            const AllocationWrapper::AllocateDecoderPromise::
+              ResolveOrRejectValue& aValue) mutable {
             if (aValue.IsReject()) {
-              p = CapabilitiesPromise::CreateAndReject(aValue.RejectValue(),
-                                                       __func__);
-            } else {
-              MOZ_ASSERT(config->IsVideo());
-              nsAutoCString reason;
-              bool powerEfficient = true;
-              bool smooth = true;
-              if (config->GetAsVideoInfo()->mImage.height > 480) {
-                // Assume that we can do stuff at 480p or less in a power
-                // efficient manner and smoothly. If greater than 480p we assume
-                // that if the video decoding is hardware accelerated it will be
-                // smooth and power efficient, otherwise we use the benchmark to
-                // estimate
-                powerEfficient = decoder->IsHardwareAccelerated(reason);
-                if (!powerEfficient && VPXDecoder::IsVP9(config->mMimeType)) {
-                  smooth = VP9Benchmark::IsVP9DecodeFast(true /* default */);
-                  uint32_t fps = VP9Benchmark::MediaBenchmarkVp9Fps();
-                  if (!smooth && fps > 0) {
-                    // The VP9 estimizer decode a 1280x720 video. Let's adjust
-                    // the result for the resolution and frame rate of what we
-                    // actually want. If the result is twice that we need we
-                    // assume it will be smooth.
-                    const auto& videoConfig = *config->GetAsVideoInfo();
-                    double needed =
-                      ((1280.0 * 720.0) /
-                       (videoConfig.mImage.width * videoConfig.mImage.height) *
-                       fps) /
-                      frameRate;
-                    smooth = needed > 2;
-                  }
-                }
-              }
-              p = CapabilitiesPromise::CreateAndResolve(
-                MediaCapabilitiesInfo(
-                  true /* supported */, smooth, powerEfficient),
-                __func__);
+              return CapabilitiesPromise::CreateAndReject(aValue.RejectValue(),
+                                                          __func__);
             }
-            MOZ_ASSERT(p.get(), "the promise has been created");
-            // Let's keep alive the decoder and the config object until the
-            // decoder has shutdown.
-            decoder->Shutdown()->Then(
+            RefPtr<MediaDataDecoder> decoder = aValue.ResolveValue();
+            // We now query the decoder to determine if it's power efficient.
+            RefPtr<CapabilitiesPromise> p = decoder->Init()->Then(
               taskQueue,
               __func__,
-              [taskQueue, decoder, config = std::move(config)](
-                const ShutdownPromise::ResolveOrRejectValue& aValue) {});
+              [taskQueue, decoder, frameRate, config = std::move(config)](
+                const MediaDataDecoder::InitPromise::ResolveOrRejectValue&
+                  aValue) mutable {
+                RefPtr<CapabilitiesPromise> p;
+                if (aValue.IsReject()) {
+                  p = CapabilitiesPromise::CreateAndReject(aValue.RejectValue(),
+                                                           __func__);
+                } else {
+                  MOZ_ASSERT(config->IsVideo());
+                  nsAutoCString reason;
+                  bool powerEfficient = true;
+                  bool smooth = true;
+                  if (config->GetAsVideoInfo()->mImage.height > 480) {
+                    // Assume that we can do stuff at 480p or less in a power
+                    // efficient manner and smoothly. If greater than 480p we
+                    // assume that if the video decoding is hardware accelerated
+                    // it will be smooth and power efficient, otherwise we use
+                    // the benchmark to estimate
+                    powerEfficient = decoder->IsHardwareAccelerated(reason);
+                    if (!powerEfficient &&
+                        VPXDecoder::IsVP9(config->mMimeType)) {
+                      smooth =
+                        VP9Benchmark::IsVP9DecodeFast(true /* default */);
+                      uint32_t fps = VP9Benchmark::MediaBenchmarkVp9Fps();
+                      if (!smooth && fps > 0) {
+                        // The VP9 estimizer decode a 1280x720 video. Let's
+                        // adjust the result for the resolution and frame rate
+                        // of what we actually want. If the result is twice that
+                        // we need we assume it will be smooth.
+                        const auto& videoConfig = *config->GetAsVideoInfo();
+                        double needed = ((1280.0 * 720.0) /
+                                         (videoConfig.mImage.width *
+                                          videoConfig.mImage.height) *
+                                         fps) /
+                                        frameRate;
+                        smooth = needed > 2;
+                      }
+                    }
+                  }
+                  p = CapabilitiesPromise::CreateAndResolve(
+                    MediaCapabilitiesInfo(
+                      true /* supported */, smooth, powerEfficient),
+                    __func__);
+                }
+                MOZ_ASSERT(p.get(), "the promise has been created");
+                // Let's keep alive the decoder and the config object until the
+                // decoder has shutdown.
+                decoder->Shutdown()->Then(
+                  taskQueue,
+                  __func__,
+                  [taskQueue, decoder, config = std::move(config)](
+                    const ShutdownPromise::ResolveOrRejectValue& aValue) {});
+                return p;
+              });
             return p;
           });
       }));
   }
 
   auto holder =
     MakeRefPtr<DOMMozPromiseRequestHolder<CapabilitiesPromise::AllPromiseType>>(
       mParent);
new file mode 100644
--- /dev/null
+++ b/dom/media/platforms/AllocationPolicy.cpp
@@ -0,0 +1,216 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* 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/. */
+
+#include "AllocationPolicy.h"
+
+#include "PDMFactory.h"
+#include "MediaInfo.h"
+#include "mozilla/ClearOnShutdown.h"
+#include "mozilla/SystemGroup.h"
+#ifdef MOZ_WIDGET_ANDROID
+#include "mozilla/jni/Utils.h"
+#endif
+
+namespace mozilla {
+
+using TrackType = TrackInfo::TrackType;
+
+StaticMutex GlobalAllocPolicy::sMutex;
+
+class GlobalAllocPolicy::AutoDeallocToken : public Token
+{
+public:
+  explicit AutoDeallocToken(GlobalAllocPolicy& aPolicy) : mPolicy(aPolicy) { }
+
+private:
+  ~AutoDeallocToken()
+  {
+    mPolicy.Dealloc();
+  }
+
+  GlobalAllocPolicy& mPolicy; // reference to a singleton object.
+};
+
+static int32_t
+MediaDecoderLimitDefault()
+{
+#ifdef MOZ_WIDGET_ANDROID
+  if (jni::GetAPIVersion() < 18) {
+    // Older Android versions have broken support for multiple simultaneous
+    // decoders, see bug 1278574.
+    return 1;
+  }
+#endif
+  // Otherwise, set no decoder limit.
+  return -1;
+}
+
+GlobalAllocPolicy::GlobalAllocPolicy()
+  : mMonitor("DecoderAllocPolicy::mMonitor")
+  , mDecoderLimit(MediaDecoderLimitDefault())
+{
+  SystemGroup::Dispatch(
+    TaskCategory::Other,
+    NS_NewRunnableFunction("GlobalAllocPolicy::GlobalAllocPolicy", [this]() {
+      ClearOnShutdown(this, ShutdownPhase::ShutdownThreads);
+    }));
+}
+
+GlobalAllocPolicy::~GlobalAllocPolicy()
+{
+  while (!mPromises.empty()) {
+    RefPtr<PromisePrivate> p = mPromises.front().forget();
+    mPromises.pop();
+    p->Reject(true, __func__);
+  }
+}
+
+GlobalAllocPolicy&
+GlobalAllocPolicy::Instance(TrackType aTrack)
+{
+  StaticMutexAutoLock lock(sMutex);
+  if (aTrack == TrackType::kAudioTrack) {
+    static auto sAudioPolicy = new GlobalAllocPolicy();
+    return *sAudioPolicy;
+  } else {
+    static auto sVideoPolicy = new GlobalAllocPolicy();
+    return *sVideoPolicy;
+  }
+}
+
+auto
+GlobalAllocPolicy::Alloc() -> RefPtr<Promise>
+{
+  // No decoder limit set.
+  if (mDecoderLimit < 0) {
+    return Promise::CreateAndResolve(new Token(), __func__);
+  }
+
+  ReentrantMonitorAutoEnter mon(mMonitor);
+  RefPtr<PromisePrivate> p = new PromisePrivate(__func__);
+  mPromises.push(p);
+  ResolvePromise(mon);
+  return p.forget();
+}
+
+void
+GlobalAllocPolicy::Dealloc()
+{
+  ReentrantMonitorAutoEnter mon(mMonitor);
+  ++mDecoderLimit;
+  ResolvePromise(mon);
+}
+
+void
+GlobalAllocPolicy::ResolvePromise(ReentrantMonitorAutoEnter& aProofOfLock)
+{
+  MOZ_ASSERT(mDecoderLimit >= 0);
+
+  if (mDecoderLimit > 0 && !mPromises.empty()) {
+    --mDecoderLimit;
+    RefPtr<PromisePrivate> p = mPromises.front().forget();
+    mPromises.pop();
+    p->Resolve(new AutoDeallocToken(*this), __func__);
+  }
+}
+
+void
+GlobalAllocPolicy::operator=(std::nullptr_t)
+{
+  delete this;
+}
+
+AllocationWrapper::AllocationWrapper(
+  already_AddRefed<MediaDataDecoder> aDecoder,
+  already_AddRefed<Token> aToken)
+  : mDecoder(aDecoder)
+  , mToken(aToken)
+{
+  DecoderDoctorLogger::LogConstructionAndBase(
+    "AllocationWrapper", this, static_cast<const MediaDataDecoder*>(this));
+  DecoderDoctorLogger::LinkParentAndChild(
+    "AllocationWrapper", this, "decoder", mDecoder.get());
+}
+
+AllocationWrapper::~AllocationWrapper()
+{
+  DecoderDoctorLogger::LogDestruction("AllocationWrapper", this);
+}
+
+RefPtr<ShutdownPromise>
+AllocationWrapper::Shutdown()
+{
+  RefPtr<MediaDataDecoder> decoder = mDecoder.forget();
+  RefPtr<Token> token = mToken.forget();
+  return decoder->Shutdown()->Then(
+    AbstractThread::GetCurrent(), __func__, [token]() {
+      return ShutdownPromise::CreateAndResolve(true, __func__);
+    });
+}
+/* static */ RefPtr<AllocationWrapper::AllocateDecoderPromise>
+AllocationWrapper::CreateDecoder(const CreateDecoderParams& aParams)
+{
+  // aParams.mConfig is guaranteed to stay alive during the lifetime of the
+  // MediaDataDecoder, so keeping a pointer to the object is safe.
+  const TrackInfo* config = &aParams.mConfig;
+  RefPtr<TaskQueue> taskQueue = aParams.mTaskQueue;
+  DecoderDoctorDiagnostics* diagnostics = aParams.mDiagnostics;
+  RefPtr<layers::ImageContainer> imageContainer = aParams.mImageContainer;
+  RefPtr<layers::KnowsCompositor> knowsCompositor = aParams.mKnowsCompositor;
+  RefPtr<GMPCrashHelper> crashHelper = aParams.mCrashHelper;
+  CreateDecoderParams::UseNullDecoder useNullDecoder = aParams.mUseNullDecoder;
+  CreateDecoderParams::NoWrapper noWrapper = aParams.mNoWrapper;
+  TrackInfo::TrackType type = aParams.mType;
+  MediaEventProducer<TrackInfo::TrackType>* onWaitingForKeyEvent =
+    aParams.mOnWaitingForKeyEvent;
+  CreateDecoderParams::OptionSet options = aParams.mOptions;
+  CreateDecoderParams::VideoFrameRate rate = aParams.mRate;
+
+  RefPtr<AllocateDecoderPromise> p =
+    GlobalAllocPolicy::Instance(aParams.mType)
+      .Alloc()
+      ->Then(
+        AbstractThread::GetCurrent(),
+        __func__,
+        [=](RefPtr<Token> aToken) {
+          // result may not always be updated by PDMFactory::CreateDecoder
+          // either when the creation succeeded or failed, as such it must be
+          // initialized to a fatal error by default.
+          MediaResult result = MediaResult(
+            NS_ERROR_DOM_MEDIA_FATAL_ERR,
+            nsPrintfCString("error creating %s decoder", TrackTypeToStr(type)));
+          RefPtr<PDMFactory> pdm = new PDMFactory();
+          CreateDecoderParams params{ *config,
+                                      taskQueue,
+                                      diagnostics,
+                                      imageContainer,
+                                      &result,
+                                      knowsCompositor,
+                                      crashHelper,
+                                      useNullDecoder,
+                                      noWrapper,
+                                      type,
+                                      onWaitingForKeyEvent,
+                                      options,
+                                      rate };
+          RefPtr<MediaDataDecoder> decoder = pdm->CreateDecoder(params);
+          if (decoder) {
+            RefPtr<AllocationWrapper> wrapper =
+              new AllocationWrapper(decoder.forget(), aToken.forget());
+            return AllocateDecoderPromise::CreateAndResolve(wrapper, __func__);
+          }
+          return AllocateDecoderPromise::CreateAndReject(result, __func__);
+        },
+        []() {
+          return AllocateDecoderPromise::CreateAndReject(
+            MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+                        "Allocation policy expired"),
+            __func__);
+        });
+  return p;
+}
+
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/media/platforms/AllocationPolicy.h
@@ -0,0 +1,121 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* 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/. */
+
+#ifndef AllocationPolicy_h_
+#define AllocationPolicy_h_
+
+#include "MediaInfo.h"
+#include "PlatformDecoderModule.h"
+#include "TimeUnits.h"
+#include "mozilla/MozPromise.h"
+#include "mozilla/StaticMutex.h"
+#include "mozilla/ReentrantMonitor.h"
+#include <queue>
+
+namespace mozilla {
+
+/**
+ * This is a singleton which controls the number of decoders that can be
+ * created concurrently. Before calling PDMFactory::CreateDecoder(), Alloc()
+ * must be called to get a token object as a permission to create a decoder.
+ * The token should stay alive until Shutdown() is called on the decoder.
+ * The destructor of the token will restore the decoder count so it is available
+ * for next calls of Alloc().
+ */
+class GlobalAllocPolicy
+{
+public:
+  class Token
+  {
+    NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Token)
+  protected:
+    virtual ~Token() {}
+  };
+
+  using Promise = MozPromise<RefPtr<Token>, bool, true>;
+
+  // Acquire a token for decoder creation. Thread-safe.
+  RefPtr<Promise> Alloc();
+
+  // Called by ClearOnShutdown() to delete the singleton.
+  void operator=(decltype(nullptr));
+
+  // Get the singleton for the given track type. Thread-safe.
+  static GlobalAllocPolicy& Instance(TrackInfo::TrackType aTrack);
+
+private:
+  class AutoDeallocToken;
+  using PromisePrivate = Promise::Private;
+  GlobalAllocPolicy();
+  ~GlobalAllocPolicy();
+  // Called by the destructor of TokenImpl to restore the decoder limit.
+  void Dealloc();
+  // Decrement the decoder limit and resolve a promise if available.
+  void ResolvePromise(ReentrantMonitorAutoEnter& aProofOfLock);
+
+  // Protect access to Instance().
+  static StaticMutex sMutex;
+
+  ReentrantMonitor mMonitor;
+  // The number of decoders available for creation.
+  int mDecoderLimit;
+  // Requests to acquire tokens.
+  std::queue<RefPtr<PromisePrivate>> mPromises;
+};
+
+class AllocationWrapper : public MediaDataDecoder
+{
+  using Token = GlobalAllocPolicy::Token;
+
+public:
+  AllocationWrapper(already_AddRefed<MediaDataDecoder> aDecoder,
+                    already_AddRefed<Token> aToken);
+  ~AllocationWrapper();
+
+  RefPtr<InitPromise> Init() override { return mDecoder->Init(); }
+  RefPtr<DecodePromise> Decode(MediaRawData* aSample) override
+  {
+    return mDecoder->Decode(aSample);
+  }
+  RefPtr<DecodePromise> Drain() override { return mDecoder->Drain(); }
+  RefPtr<FlushPromise> Flush() override { return mDecoder->Flush(); }
+  bool IsHardwareAccelerated(nsACString& aFailureReason) const override
+  {
+    return mDecoder->IsHardwareAccelerated(aFailureReason);
+  }
+  nsCString GetDescriptionName() const override
+  {
+    return mDecoder->GetDescriptionName();
+  }
+  void SetSeekThreshold(const media::TimeUnit& aTime) override
+  {
+    mDecoder->SetSeekThreshold(aTime);
+  }
+  bool SupportDecoderRecycling() const override
+  {
+    return mDecoder->SupportDecoderRecycling();
+  }
+  RefPtr<ShutdownPromise> Shutdown() override;
+
+  typedef MozPromise<RefPtr<MediaDataDecoder>,
+                     MediaResult,
+                     /* IsExclusive = */ true>
+    AllocateDecoderPromise;
+  // Will create a decoder has soon as one can be created according to the
+  // GlobalAllocPolicy.
+  // Warning: all aParams members must be valid until the promise has been
+  // resolved, as some contains raw pointers to objects.
+  static RefPtr<AllocateDecoderPromise> CreateDecoder(
+    const CreateDecoderParams& aParams);
+
+private:
+  RefPtr<MediaDataDecoder> mDecoder;
+  RefPtr<Token> mToken;
+};
+
+} // namespace mozilla
+
+#endif
--- a/dom/media/platforms/moz.build
+++ b/dom/media/platforms/moz.build
@@ -6,16 +6,17 @@
 
 EXPORTS += [
     'agnostic/AgnosticDecoderModule.h',
     'agnostic/DummyMediaDataDecoder.h',
     'agnostic/OpusDecoder.h',
     'agnostic/TheoraDecoder.h',
     'agnostic/VorbisDecoder.h',
     'agnostic/VPXDecoder.h',
+    'AllocationPolicy.h',
     'MediaTelemetryConstants.h',
     'PDMFactory.h',
     'PlatformDecoderModule.h',
     'ReorderQueue.h',
     'SimpleMap.h',
     'wrappers/H264Converter.h',
     'wrappers/MediaDataDecoderProxy.h'
 
@@ -26,16 +27,17 @@ UNIFIED_SOURCES += [
     'agnostic/BlankDecoderModule.cpp',
     'agnostic/DummyMediaDataDecoder.cpp',
     'agnostic/NullDecoderModule.cpp',
     'agnostic/OpusDecoder.cpp',
     'agnostic/TheoraDecoder.cpp',
     'agnostic/VorbisDecoder.cpp',
     'agnostic/VPXDecoder.cpp',
     'agnostic/WAVDecoder.cpp',
+    'AllocationPolicy.cpp',
     'PDMFactory.cpp',
     'wrappers/H264Converter.cpp',
     'wrappers/MediaDataDecoderProxy.cpp'
 ]
 
 DIRS += [
     'agnostic/bytestreams',
     'agnostic/eme',
--- a/dom/plugins/base/nsPluginHost.cpp
+++ b/dom/plugins/base/nsPluginHost.cpp
@@ -788,16 +788,22 @@ nsPluginHost::InstantiatePluginInstance(
   PR_LogFlush();
 #endif
 
   if (aMimeType.IsEmpty()) {
     MOZ_ASSERT_UNREACHABLE("Attempting to spawn a plugin with no mime type");
     return NS_ERROR_FAILURE;
   }
 
+  // Plugins are not supported when recording or replaying executions.
+  // See bug 1483232.
+  if (recordreplay::IsRecordingOrReplaying()) {
+    return NS_ERROR_FAILURE;
+  }
+
   RefPtr<nsPluginInstanceOwner> instanceOwner = new nsPluginInstanceOwner();
   if (!instanceOwner) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   nsCOMPtr<nsIContent> ourContent = do_QueryInterface(static_cast<nsIImageLoadingContent*>(aContent));
   nsresult rv = instanceOwner->Init(ourContent);
   if (NS_FAILED(rv)) {
--- a/dom/storage/LocalStorageCache.cpp
+++ b/dom/storage/LocalStorageCache.cpp
@@ -438,17 +438,19 @@ LocalStorageCache::SetItem(const LocalSt
   }
 
   data.mKeys.Put(aKey, aValue);
 
   if (aSource != ContentMutation) {
     return NS_OK;
   }
 
+#if !defined(MOZ_WIDGET_ANDROID)
   NotifyObservers(aStorage, nsString(aKey), aOld, aValue);
+#endif
 
   if (Persist(aStorage)) {
     StorageDBChild* storageChild = StorageDBChild::Get();
     if (!storageChild) {
       NS_ERROR("Writing to localStorage after the database has been shut down"
                ", data lose!");
       return NS_ERROR_NOT_INITIALIZED;
     }
@@ -486,17 +488,19 @@ LocalStorageCache::RemoveItem(const Loca
                           static_cast<int64_t>(aKey.Length()));
   Unused << ProcessUsageDelta(aStorage, delta, aSource);
   data.mKeys.Remove(aKey);
 
   if (aSource != ContentMutation) {
     return NS_OK;
   }
 
+#if !defined(MOZ_WIDGET_ANDROID)
   NotifyObservers(aStorage, nsString(aKey), aOld, VoidString());
+#endif
 
   if (Persist(aStorage)) {
     StorageDBChild* storageChild = StorageDBChild::Get();
     if (!storageChild) {
       NS_ERROR("Writing to localStorage after the database has been shut down"
                ", data lose!");
       return NS_ERROR_NOT_INITIALIZED;
     }
@@ -534,19 +538,21 @@ LocalStorageCache::Clear(const LocalStor
     Unused << ProcessUsageDelta(aStorage, -data.mOriginQuotaUsage, aSource);
     data.mKeys.Clear();
   }
 
   if (aSource != ContentMutation) {
     return hadData ? NS_OK : NS_SUCCESS_DOM_NO_OPERATION;
   }
 
+#if !defined(MOZ_WIDGET_ANDROID)
   if (hadData) {
     NotifyObservers(aStorage, VoidString(), VoidString(), VoidString());
   }
+#endif
 
   if (Persist(aStorage) && (refresh || hadData)) {
     StorageDBChild* storageChild = StorageDBChild::Get();
     if (!storageChild) {
       NS_ERROR("Writing to localStorage after the database has been shut down"
                ", data lose!");
       return NS_ERROR_NOT_INITIALIZED;
     }
--- a/dom/storage/LocalStorageManager.cpp
+++ b/dom/storage/LocalStorageManager.cpp
@@ -241,16 +241,17 @@ LocalStorageManager::GetStorageInternal(
         }
       } else {
         if (originKey.EqualsLiteral("knalb.:about")) {
           return NS_OK;
         }
       }
     }
 
+#if !defined(MOZ_WIDGET_ANDROID)
     PBackgroundChild* backgroundActor =
       BackgroundChild::GetOrCreateForCurrentThread();
     if (NS_WARN_IF(!backgroundActor)) {
       return NS_ERROR_FAILURE;
     }
 
     PrincipalInfo principalInfo;
     rv = mozilla::ipc::PrincipalToPrincipalInfo(aPrincipal, &principalInfo);
@@ -258,31 +259,34 @@ LocalStorageManager::GetStorageInternal(
       return rv;
     }
 
     uint32_t privateBrowsingId;
     rv = aPrincipal->GetPrivateBrowsingId(&privateBrowsingId);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
+#endif
 
     // There is always a single instance of a cache per scope
     // in a single instance of a DOM storage manager.
     cache = PutCache(originAttrSuffix, originKey, aPrincipal);
 
+#if !defined(MOZ_WIDGET_ANDROID)
     LocalStorageCacheChild* actor = new LocalStorageCacheChild(cache);
 
     MOZ_ALWAYS_TRUE(
       backgroundActor->SendPBackgroundLocalStorageCacheConstructor(
                                                             actor,
                                                             principalInfo,
                                                             originKey,
                                                             privateBrowsingId));
 
     cache->SetActor(actor);
+#endif
   }
 
   if (aRetval) {
     nsCOMPtr<nsPIDOMWindowInner> inner = nsPIDOMWindowInner::From(aWindow);
 
     nsCOMPtr<nsIDOMStorage> storage = new LocalStorage(
       inner, this, cache, aDocumentURI, aPrincipal, aPrivate);
     storage.forget(aRetval);
--- a/extensions/cookie/nsPermissionManager.cpp
+++ b/extensions/cookie/nsPermissionManager.cpp
@@ -2096,16 +2096,97 @@ nsPermissionManager::RemoveAll()
 
 NS_IMETHODIMP
 nsPermissionManager::RemoveAllSince(int64_t aSince)
 {
   ENSURE_NOT_CHILD_PROCESS;
   return RemoveAllModifiedSince(aSince);
 }
 
+template<class T>
+nsresult
+nsPermissionManager::RemovePermissionEntries(T aCondition)
+{
+  nsCOMArray<nsIPermission> array;
+  for (auto iter = mPermissionTable.Iter(); !iter.Done(); iter.Next()) {
+    PermissionHashKey* entry = iter.Get();
+    for (const auto& permEntry : entry->GetPermissions()) {
+      if (!aCondition(permEntry)) {
+        continue;
+      }
+
+      nsCOMPtr<nsIPrincipal> principal;
+      nsresult rv = GetPrincipalFromOrigin(entry->GetKey()->mOrigin,
+                                           getter_AddRefs(principal));
+      if (NS_FAILED(rv)) {
+        continue;
+      }
+
+      nsCOMPtr<nsIPermission> permission =
+        nsPermission::Create(principal,
+                             mTypeArray.ElementAt(permEntry.mType),
+                             permEntry.mPermission,
+                             permEntry.mExpireType,
+                             permEntry.mExpireTime);
+      if (NS_WARN_IF(!permission)) {
+        continue;
+      }
+      array.AppendObject(permission);
+    }
+  }
+
+  for (int32_t i = 0; i<array.Count(); ++i) {
+    nsCOMPtr<nsIPrincipal> principal;
+    nsAutoCString type;
+
+    nsresult rv = array[i]->GetPrincipal(getter_AddRefs(principal));
+    if (NS_FAILED(rv)) {
+      NS_ERROR("GetPrincipal() failed!");
+      continue;
+    }
+
+    rv = array[i]->GetType(type);
+    if (NS_FAILED(rv)) {
+      NS_ERROR("GetType() failed!");
+      continue;
+    }
+
+    // AddInternal handles removal, so let it do the work...
+    AddInternal(
+      principal,
+      type,
+      nsIPermissionManager::UNKNOWN_ACTION,
+      0,
+      nsIPermissionManager::EXPIRE_NEVER, 0, 0,
+      nsPermissionManager::eNotify,
+      nsPermissionManager::eWriteToDB);
+  }
+  // now re-import any defaults as they may now be required if we just deleted
+  // an override.
+  ImportDefaults();
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPermissionManager::RemoveByType(const char* aType)
+{
+  ENSURE_NOT_CHILD_PROCESS;
+
+  int32_t typeIndex = GetTypeIndex(aType, false);
+  // If type == -1, the type isn't known,
+  // so just return NS_OK
+  if (typeIndex == -1) {
+    return NS_OK;
+  }
+
+  return RemovePermissionEntries([typeIndex] (const PermissionEntry& aPermEntry) {
+    return static_cast<uint32_t> (typeIndex) == aPermEntry.mType;
+  });
+}
+
 void
 nsPermissionManager::CloseDB(bool aRebuildOnSuccess)
 {
   // Null the statements, this will finalize them.
   mStmtInsert = nullptr;
   mStmtDelete = nullptr;
   mStmtUpdate = nullptr;
   if (mDBConn) {
@@ -2622,74 +2703,19 @@ NS_IMETHODIMP nsPermissionManager::Obser
   return NS_OK;
 }
 
 nsresult
 nsPermissionManager::RemoveAllModifiedSince(int64_t aModificationTime)
 {
   ENSURE_NOT_CHILD_PROCESS;
 
-  nsCOMArray<nsIPermission> array;
-  for (auto iter = mPermissionTable.Iter(); !iter.Done(); iter.Next()) {
-    PermissionHashKey* entry = iter.Get();
-    for (const auto& permEntry : entry->GetPermissions()) {
-      if (aModificationTime > permEntry.mModificationTime) {
-        continue;
-      }
-
-      nsCOMPtr<nsIPrincipal> principal;
-      nsresult rv = GetPrincipalFromOrigin(entry->GetKey()->mOrigin,
-                                           getter_AddRefs(principal));
-      if (NS_FAILED(rv)) {
-        continue;
-      }
-
-      nsCOMPtr<nsIPermission> permission =
-        nsPermission::Create(principal,
-                             mTypeArray.ElementAt(permEntry.mType),
-                             permEntry.mPermission,
-                             permEntry.mExpireType,
-                             permEntry.mExpireTime);
-      if (NS_WARN_IF(!permission)) {
-        continue;
-      }
-      array.AppendObject(permission);
-    }
-  }
-
-  for (int32_t i = 0; i<array.Count(); ++i) {
-    nsCOMPtr<nsIPrincipal> principal;
-    nsAutoCString type;
-
-    nsresult rv = array[i]->GetPrincipal(getter_AddRefs(principal));
-    if (NS_FAILED(rv)) {
-      NS_ERROR("GetPrincipal() failed!");
-      continue;
-    }
-
-    rv = array[i]->GetType(type);
-    if (NS_FAILED(rv)) {
-      NS_ERROR("GetType() failed!");
-      continue;
-    }
-
-    // AddInternal handles removal, so let it do the work...
-    AddInternal(
-      principal,
-      type,
-      nsIPermissionManager::UNKNOWN_ACTION,
-      0,
-      nsIPermissionManager::EXPIRE_NEVER, 0, 0,
-      nsPermissionManager::eNotify,
-      nsPermissionManager::eWriteToDB);
-  }
-  // now re-import any defaults as they may now be required if we just deleted
-  // an override.
-  ImportDefaults();
-  return NS_OK;
+  return RemovePermissionEntries([aModificationTime] (const PermissionEntry& aPermEntry) {
+    return aModificationTime <= aPermEntry.mModificationTime;
+  });
 }
 
 NS_IMETHODIMP
 nsPermissionManager::RemovePermissionsWithAttributes(const nsAString& aPattern)
 {
   ENSURE_NOT_CHILD_PROCESS;
   mozilla::OriginAttributesPattern pattern;
   if (!pattern.Init(aPattern)) {
--- a/extensions/cookie/nsPermissionManager.h
+++ b/extensions/cookie/nsPermissionManager.h
@@ -359,16 +359,20 @@ private:
                        int64_t aModificationTime);
 
   /**
    * This method removes all permissions modified after the specified time.
    */
   nsresult
   RemoveAllModifiedSince(int64_t aModificationTime);
 
+  template<class T>
+  nsresult
+  RemovePermissionEntries(T aCondition);
+
   /**
    * Returns false if this permission manager wouldn't have the permission
    * requested available.
    *
    * If aType is nullptr, checks that the permission manager would have all
    * permissions available for the given principal.
    */
   bool PermissionAvailable(nsIPrincipal* aPrincipal, const char* aType);
new file mode 100644
--- /dev/null
+++ b/extensions/cookie/test/unit/test_permmanager_removebytype.js
@@ -0,0 +1,77 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function run_test() {
+  // initialize the permission manager service
+  let pm = Cc["@mozilla.org/permissionmanager;1"].
+        getService(Ci.nsIPermissionManager);
+
+  Assert.equal(perm_count(), 0);
+
+  // add some permissions
+  let uri = NetUtil.newURI("http://amazon.com:8080/foobarbaz");
+  let uri2 = NetUtil.newURI("http://google.com:2048/quxx");
+  let uri3 = NetUtil.newURI("https://google.com/search");
+
+  pm.add(uri, "apple", 3);
+  pm.add(uri, "pear", 1);
+  pm.add(uri, "cucumber", 1);
+
+  pm.add(uri2, "apple", 2);
+  pm.add(uri2, "pear", 2);
+
+  pm.add(uri3, "cucumber", 3);
+  pm.add(uri3, "apple", 1);
+
+  Assert.equal(perm_count(), 7);
+
+  pm.removeByType("apple");
+  Assert.equal(perm_count(), 4);
+
+  Assert.equal(pm.testPermission(uri, "pear"), 1);
+  Assert.equal(pm.testPermission(uri2, "pear"), 2);
+
+  Assert.equal(pm.testPermission(uri, "apple"), 0);
+  Assert.equal(pm.testPermission(uri2, "apple"), 0);
+  Assert.equal(pm.testPermission(uri3, "apple"), 0);
+
+  Assert.equal(pm.testPermission(uri, "cucumber"), 1);
+  Assert.equal(pm.testPermission(uri3, "cucumber"), 3);
+
+  pm.removeByType("cucumber");
+  Assert.equal(perm_count(), 2);
+
+  Assert.equal(pm.testPermission(uri, "pear"), 1);
+  Assert.equal(pm.testPermission(uri2, "pear"), 2);
+
+  Assert.equal(pm.testPermission(uri, "apple"), 0);
+  Assert.equal(pm.testPermission(uri2, "apple"), 0);
+  Assert.equal(pm.testPermission(uri3, "apple"), 0);
+
+  Assert.equal(pm.testPermission(uri, "cucumber"), 0);
+  Assert.equal(pm.testPermission(uri3, "cucumber"), 0);
+
+  pm.removeByType("pear");
+  Assert.equal(perm_count(), 0);
+
+  Assert.equal(pm.testPermission(uri, "pear"), 0);
+  Assert.equal(pm.testPermission(uri2, "pear"), 0);
+
+  Assert.equal(pm.testPermission(uri, "apple"), 0);
+  Assert.equal(pm.testPermission(uri2, "apple"), 0);
+  Assert.equal(pm.testPermission(uri3, "apple"), 0);
+
+  Assert.equal(pm.testPermission(uri, "cucumber"), 0);
+  Assert.equal(pm.testPermission(uri3, "cucumber"), 0);
+
+  function perm_count() {
+    let enumerator = pm.enumerator;
+    let count = 0;
+    while (enumerator.hasMoreElements()) {
+      count++;
+      enumerator.getNext();
+    }
+
+    return count;
+  }
+}
--- a/extensions/cookie/test/unit/xpcshell.ini
+++ b/extensions/cookie/test/unit/xpcshell.ini
@@ -19,16 +19,17 @@ skip-if = true # Bug 863738
 [test_eviction.js]
 [test_permmanager_default_pref.js]
 [test_permmanager_defaults.js]
 [test_permmanager_expiration.js]
 [test_permmanager_getAllForURI.js]
 [test_permmanager_getPermissionObject.js]
 [test_permmanager_notifications.js]
 [test_permmanager_removeall.js]
+[test_permmanager_removebytype.js]
 [test_permmanager_removesince.js]
 [test_permmanager_removeforapp.js]
 [test_permmanager_load_invalid_entries.js]
 skip-if = debug == true
 [test_permmanager_idn.js]
 [test_permmanager_subdomains.js]
 [test_permmanager_local_files.js]
 [test_permmanager_cleardata.js]
--- a/gfx/2d/UserData.h
+++ b/gfx/2d/UserData.h
@@ -73,17 +73,19 @@ public:
     return nullptr;
   }
 
   /* Remove and destroy a given key */
   void RemoveAndDestroy(UserDataKey *key)
   {
     for (int i=0; i<count; i++) {
       if (key == entries[i].key) {
-        entries[i].destroy(entries[i].userData);
+        if (entries[i].destroy) {
+          entries[i].destroy(entries[i].userData);
+        }
         // decrement before looping so entries[i+1] doesn't read past the end:
         --count;
         for (;i<count; i++) {
           entries[i] = entries[i+1];
         }
       }
     }
   }
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -1465,17 +1465,17 @@ public:
   virtual int32_t GetReadCount() override;
 
   virtual LockType GetType() override { return TYPE_NONBLOCKING_MEMORY; }
 
   virtual bool IsValid() const override { return true; };
 
   virtual bool Serialize(ReadLockDescriptor& aOutput, base::ProcessId aOther) override;
 
-  int32_t mReadCount;
+  Atomic<int32_t> mReadCount;
 };
 
 // The cross-prcess implementation of TextureReadLock.
 //
 // Since we don't use cross-process reference counting for the ReadLock objects,
 // we use the lock's internal counter as a way to know when to deallocate the
 // underlying shmem section: when the counter is equal to 1, it means that the
 // lock is not "held" (the texture is writable), when the counter is equal to 0
@@ -1646,24 +1646,24 @@ MemoryTextureReadLock::Serialize(ReadLoc
   return true;
 }
 
 bool
 MemoryTextureReadLock::ReadLock()
 {
   NS_ASSERT_OWNINGTHREAD(MemoryTextureReadLock);
 
-  PR_ATOMIC_INCREMENT(&mReadCount);
+  ++mReadCount;
   return true;
 }
 
 int32_t
 MemoryTextureReadLock::ReadUnlock()
 {
-  int32_t readCount = PR_ATOMIC_DECREMENT(&mReadCount);
+  int32_t readCount = --mReadCount;
   MOZ_ASSERT(readCount >= 0);
 
   return readCount;
 }
 
 int32_t
 MemoryTextureReadLock::GetReadCount()
 {
--- a/gfx/thebes/gfxFontMissingGlyphs.cpp
+++ b/gfx/thebes/gfxFontMissingGlyphs.cpp
@@ -4,117 +4,41 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "gfxFontMissingGlyphs.h"
 
 #include "gfxUtils.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/Helpers.h"
 #include "mozilla/gfx/PathHelpers.h"
+#include "mozilla/LinkedList.h"
 #include "mozilla/RefPtr.h"
 #include "nsDeviceContext.h"
 #include "nsLayoutUtils.h"
+#include "TextDrawTarget.h"
 
 using namespace mozilla;
 using namespace mozilla::gfx;
 
-#define CHAR_BITS(b00, b01, b02, b10, b11, b12, b20, b21, b22, b30, b31, b32, b40, b41, b42) \
-  ((b00 << 0) | (b01 << 1) | (b02 << 2) | (b10 << 3) | (b11 << 4) | (b12 << 5) | \
-   (b20 << 6) | (b21 << 7) | (b22 << 8) | (b30 << 9) | (b31 << 10) | (b32 << 11) | \
-   (b40 << 12) | (b41 << 13) | (b42 << 14))
-
-static const uint16_t glyphMicroFont[16] = {
-  CHAR_BITS(0, 1, 0,
-            1, 0, 1,
-            1, 0, 1,
-            1, 0, 1,
-            0, 1, 0),
-  CHAR_BITS(0, 1, 0,
-            0, 1, 0,
-            0, 1, 0,
-            0, 1, 0,
-            0, 1, 0),
-  CHAR_BITS(1, 1, 1,
-            0, 0, 1,
-            1, 1, 1,
-            1, 0, 0,
-            1, 1, 1),
-  CHAR_BITS(1, 1, 1,
-            0, 0, 1,
-            1, 1, 1,
-            0, 0, 1,
-            1, 1, 1),
-  CHAR_BITS(1, 0, 1,
-            1, 0, 1,
-            1, 1, 1,
-            0, 0, 1,
-            0, 0, 1),
-  CHAR_BITS(1, 1, 1,
-            1, 0, 0,
-            1, 1, 1,
-            0, 0, 1,
-            1, 1, 1),
-  CHAR_BITS(1, 1, 1,
-            1, 0, 0,
-            1, 1, 1,
-            1, 0, 1,
-            1, 1, 1),
-  CHAR_BITS(1, 1, 1,
-            0, 0, 1,
-            0, 0, 1,
-            0, 0, 1,
-            0, 0, 1),
-  CHAR_BITS(0, 1, 0,
-            1, 0, 1,
-            0, 1, 0,
-            1, 0, 1,
-            0, 1, 0),
-  CHAR_BITS(1, 1, 1,
-            1, 0, 1,
-            1, 1, 1,
-            0, 0, 1,
-            0, 0, 1),
-  CHAR_BITS(1, 1, 1,
-            1, 0, 1,
-            1, 1, 1,
-            1, 0, 1,
-            1, 0, 1),
-  CHAR_BITS(1, 1, 0,
-            1, 0, 1,
-            1, 1, 0,
-            1, 0, 1,
-            1, 1, 0),
-  CHAR_BITS(0, 1, 1,
-            1, 0, 0,
-            1, 0, 0,
-            1, 0, 0,
-            0, 1, 1),
-  CHAR_BITS(1, 1, 0,
-            1, 0, 1,
-            1, 0, 1,
-            1, 0, 1,
-            1, 1, 0),
-  CHAR_BITS(1, 1, 1,
-            1, 0, 0,
-            1, 1, 1,
-            1, 0, 0,
-            1, 1, 1),
-  CHAR_BITS(1, 1, 1,
-            1, 0, 0,
-            1, 1, 1,
-            1, 0, 0,
-            1, 0, 0)
+#define X 255
+static const uint8_t gMiniFontData[] = {
+    0,X,0, 0,X,0, X,X,X, X,X,X, X,0,X, X,X,X, X,X,X, X,X,X, X,X,X, X,X,X, X,X,X, X,X,0, 0,X,X, X,X,0, X,X,X, X,X,X,
+    X,0,X, 0,X,0, 0,0,X, 0,0,X, X,0,X, X,0,0, X,0,0, 0,0,X, X,0,X, X,0,X, X,0,X, X,0,X, X,0,0, X,0,X, X,0,0, X,0,0,
+    X,0,X, 0,X,0, X,X,X, X,X,X, X,X,X, X,X,X, X,X,X, 0,0,X, X,X,X, X,X,X, X,X,X, X,X,0, X,0,0, X,0,X, X,X,X, X,X,X,
+    X,0,X, 0,X,0, X,0,0, 0,0,X, 0,0,X, 0,0,X, X,0,X, 0,0,X, X,0,X, 0,0,X, X,0,X, X,0,X, X,0,0, X,0,X, X,0,0, X,0,0,
+    0,X,0, 0,X,0, X,X,X, X,X,X, 0,0,X, X,X,X, X,X,X, 0,0,X, X,X,X, 0,0,X, X,0,X, X,X,0, 0,X,X, X,X,0, X,X,X, X,0,0,
 };
+#undef X
 
 /* Parameters that control the rendering of hexboxes. They look like this:
 
         BMP codepoints           non-BMP codepoints
       (U+0000 - U+FFFF)         (U+10000 - U+10FFFF)
 
-         +---------+              +-------------+ 
+         +---------+              +-------------+
          |         |              |             |
          | HHH HHH |              | HHH HHH HHH |
          | HHH HHH |              | HHH HHH HHH |
          | HHH HHH |              | HHH HHH HHH |
          | HHH HHH |              | HHH HHH HHH |
          | HHH HHH |              | HHH HHH HHH |
          |         |              |             |
          | HHH HHH |              | HHH HHH HHH |
@@ -143,77 +67,327 @@ static const int HEX_CHAR_GAP = 1;
 static const int BOX_HORIZONTAL_INSET = 1;
 /** The width of the border */
 static const int BOX_BORDER_WIDTH = 1;
 /**
  * The scaling factor for the border opacity; this is multiplied by the current
  * opacity being used to draw the text.
  */
 static const Float BOX_BORDER_OPACITY = 0.5;
+
+#ifndef MOZ_GFX_OPTIMIZE_MOBILE
+
+static RefPtr<DrawTarget> gGlyphDrawTarget;
+static RefPtr<SourceSurface> gGlyphMask;
+static RefPtr<SourceSurface> gGlyphAtlas;
+static Color gGlyphColor;
+
 /**
- * Draw a single hex character using the current color. A nice way to do this
- * would be to fill in an A8 image surface and then use it as a mask
- * to paint the current color. Tragically this doesn't currently work with the
- * Quartz cairo backend which doesn't generally support masking with surfaces.
- * So for now we just paint a bunch of rectangles...
+ * Generates a new colored mini-font atlas from the mini-font mask.
  */
-#ifndef MOZ_GFX_OPTIMIZE_MOBILE
-static void
-DrawHexChar(uint32_t aDigit, const Point& aPt, DrawTarget& aDrawTarget,
-            const Pattern &aPattern, const Matrix* aMat)
+static bool
+MakeGlyphAtlas(const Color& aColor)
 {
-    uint32_t glyphBits = glyphMicroFont[aDigit];
+    gGlyphAtlas = nullptr;
+    if (!gGlyphDrawTarget) {
+        gGlyphDrawTarget = gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(
+            IntSize(MINIFONT_WIDTH * 16, MINIFONT_HEIGHT), SurfaceFormat::B8G8R8A8);
+        if (!gGlyphDrawTarget) {
+            return false;
+        }
+    }
+    if (!gGlyphMask) {
+        gGlyphMask = gGlyphDrawTarget->CreateSourceSurfaceFromData(
+            const_cast<uint8_t*>(gMiniFontData), IntSize(MINIFONT_WIDTH * 16, MINIFONT_HEIGHT),
+            MINIFONT_WIDTH * 16, SurfaceFormat::A8);
+        if (!gGlyphMask) {
+            return false;
+        }
+    }
+    gGlyphDrawTarget->MaskSurface(ColorPattern(aColor), gGlyphMask, Point(0, 0),
+                                  DrawOptions(1.0f, CompositionOp::OP_SOURCE));
+    gGlyphAtlas = gGlyphDrawTarget->Snapshot();
+    if (!gGlyphAtlas) {
+        return false;
+    }
+    gGlyphColor = aColor;
+    return true;
+}
 
-    if (aMat) {
-        // If using an orientation matrix instead of a DT transform, step
-        // with the matrix basis vectors, filling individual rectangles of
-        // the size indicated by the matrix.
-        Point stepX(aMat->_11, aMat->_12);
-        Point stepY(aMat->_21, aMat->_22);
-        Point corner = stepX + stepY;
-        // Get the rectangle at the origin that will be stepped into place.
-        Rect startRect(std::min(corner.x, 0.0f), std::min(corner.y, 0.0f),
-                       fabs(corner.x), fabs(corner.y));
-        startRect.MoveBy(aMat->TransformPoint(aPt));
-        for (int y = 0; y < MINIFONT_HEIGHT; ++y) {
-            Rect curRect = startRect;
-            for (int x = 0; x < MINIFONT_WIDTH; ++x) {
-                if (glyphBits & 1) {
-                    aDrawTarget.FillRect(curRect, aPattern);
-                }
-                glyphBits >>= 1;
-                curRect.MoveBy(stepX);
-            }
-            startRect.MoveBy(stepY);
+/**
+ * Reuse the current mini-font atlas if the color matches, otherwise regenerate it.
+ */
+static inline already_AddRefed<SourceSurface>
+GetGlyphAtlas(const Color& aColor)
+{
+    // Get the opaque color, ignoring any transparency which will be handled later.
+    Color color(aColor.r, aColor.g, aColor.b);
+    if ((gGlyphAtlas && gGlyphColor == color) || MakeGlyphAtlas(color)) {
+        return do_AddRef(gGlyphAtlas);
+    }
+    return nullptr;
+}
+
+/**
+ * Clear any cached glyph atlas resources.
+ */
+static void
+PurgeGlyphAtlas()
+{
+    gGlyphAtlas = nullptr;
+    gGlyphDrawTarget = nullptr;
+    gGlyphMask = nullptr;
+}
+
+// WebRender layer manager user data that will get signaled when the layer
+// manager is destroyed.
+class WRUserData : public layers::LayerUserData, public LinkedListElement<WRUserData>
+{
+public:
+    explicit WRUserData(layers::WebRenderLayerManager* aManager);
+
+    ~WRUserData();
+
+    static void
+    Assign(layers::WebRenderLayerManager* aManager)
+    {
+        if (!aManager->HasUserData(&sWRUserDataKey)) {
+            aManager->SetUserData(&sWRUserDataKey, new WRUserData(aManager));
         }
-        return;
+    }
+
+    void
+    Remove()
+    {
+        remove();
+        mManager->RemoveUserData(&sWRUserDataKey);
     }
 
-    // To avoid the potential for seams showing between rects when we're under
-    // a transform we concat all the rects into a PathBuilder and fill the
-    // resulting Path (rather than using DrawTarget::FillRect).
-    RefPtr<PathBuilder> builder = aDrawTarget.CreatePathBuilder();
-    for (int y = 0; y < MINIFONT_HEIGHT; ++y) {
-        for (int x = 0; x < MINIFONT_WIDTH; ++x) {
-            if (glyphBits & 1) {
-                Rect r(aPt.x + x, aPt.y + y, 1, 1);
-                MaybeSnapToDevicePixels(r, aDrawTarget, true);
-                builder->MoveTo(r.TopLeft());
-                builder->LineTo(r.TopRight());
-                builder->LineTo(r.BottomRight());
-                builder->LineTo(r.BottomLeft());
-                builder->Close();
+    layers::WebRenderLayerManager* mManager;
+
+    static UserDataKey sWRUserDataKey;
+};
+
+static RefPtr<SourceSurface> gWRGlyphAtlas[8];
+static LinkedList<WRUserData> gWRUsers;
+UserDataKey WRUserData::sWRUserDataKey;
+
+/**
+ * Generates a transformed WebRender mini-font atlas for a given orientation.
+ */
+static already_AddRefed<SourceSurface>
+MakeWRGlyphAtlas(const Matrix* aMat)
+{
+    IntSize size(MINIFONT_WIDTH * 16, MINIFONT_HEIGHT);
+    // If the orientation is transposed, width/height are swapped.
+    if (aMat && aMat->_11 == 0) {
+        std::swap(size.width, size.height);
+    }
+    RefPtr<DrawTarget> ref = gfxPlatform::GetPlatform()->ScreenReferenceDrawTarget();
+    RefPtr<DrawTarget> dt = gfxPlatform::GetPlatform()->CreateSimilarSoftwareDrawTarget(
+            ref, size, SurfaceFormat::B8G8R8A8);
+    if (!dt) {
+        return nullptr;
+    }
+    if (aMat) {
+        // Select appropriate transform matrix based on whether the
+        // orientation is transposed.
+        dt->SetTransform(aMat->_11 == 0 ?
+            Matrix(0.0f, copysign(1.0f, aMat->_12),
+                   copysign(1.0f, aMat->_21), 0.0f,
+                   aMat->_21 < 0 ? MINIFONT_HEIGHT : 0.0f,
+                   aMat->_12 < 0 ? MINIFONT_WIDTH * 16 : 0.0f) :
+            Matrix(copysign(1.0f, aMat->_11), 0.0f,
+                   0.0f, copysign(1.0f, aMat->_22),
+                   aMat->_11 < 0 ? MINIFONT_WIDTH * 16 : 0.0f,
+                   aMat->_22 < 0 ? MINIFONT_HEIGHT : 0.0f));
+    }
+    RefPtr<SourceSurface> mask = dt->CreateSourceSurfaceFromData(
+        const_cast<uint8_t*>(gMiniFontData), IntSize(MINIFONT_WIDTH * 16, MINIFONT_HEIGHT),
+        MINIFONT_WIDTH * 16, SurfaceFormat::A8);
+    if (!mask) {
+        return nullptr;
+    }
+    dt->MaskSurface(ColorPattern(Color(1.0f, 1.0f, 1.0f)), mask, Point(0, 0));
+    return dt->Snapshot();
+}
+
+/**
+ * Clear any cached WebRender glyph atlas resources.
+ */
+static void
+PurgeWRGlyphAtlas()
+{
+    // For each WR layer manager, we need go through each atlas orientation
+    // and see if it has a stashed image key. If it does, remove the image
+    // from the layer manager.
+    for (WRUserData* user : gWRUsers) {
+        auto* manager = user->mManager;
+        for (size_t i = 0; i < 8; i++) {
+            if (gWRGlyphAtlas[i]) {
+                uint32_t handle =
+                    (uint32_t)(uintptr_t)gWRGlyphAtlas[i]->GetUserData(
+                        reinterpret_cast<UserDataKey*>(manager));
+                if (handle) {
+                    manager->AddImageKeyForDiscard(
+                        wr::ImageKey{manager->WrBridge()->GetNamespace(), handle});
+                }
             }
-            glyphBits >>= 1;
+        }
+        // Remove the layer manager's destroy notification.
+        user->Remove();
+    }
+    // Finally, clear out the atlases.
+    for (size_t i = 0; i < 8; i++) {
+        gWRGlyphAtlas[i] = nullptr;
+    }
+}
+
+WRUserData::WRUserData(layers::WebRenderLayerManager* aManager)
+    : mManager(aManager)
+{
+    gWRUsers.insertFront(this);
+}
+
+WRUserData::~WRUserData()
+{
+    // When the layer manager is destroyed, we need go through each
+    // atlas and remove any assigned image keys.
+    if (isInList()) {
+        for (size_t i = 0; i < 8; i++) {
+            if (gWRGlyphAtlas[i]) {
+                gWRGlyphAtlas[i]->RemoveUserData(reinterpret_cast<UserDataKey*>(mManager));
+            }
+        }
+    }
+}
+
+static already_AddRefed<SourceSurface>
+GetWRGlyphAtlas(DrawTarget& aDrawTarget, const Matrix* aMat)
+{
+    uint32_t key = 0;
+    // Encode orientation in the key.
+    if (aMat) {
+        if (aMat->_11 == 0) {
+            key |= 4 | (aMat->_12 < 0 ? 1 : 0) | (aMat->_21 < 0 ? 2 : 0);
+        } else {
+            key |= (aMat->_11 < 0 ? 1 : 0) | (aMat->_22 < 0 ? 2 : 0);
         }
     }
-    RefPtr<Path> path = builder->Finish();
-    aDrawTarget.Fill(path, aPattern);
+    // Check if an atlas was already created, or create one if necessary.
+    RefPtr<SourceSurface> atlas = gWRGlyphAtlas[key];
+    if (!atlas) {
+        atlas = MakeWRGlyphAtlas(aMat);
+        gWRGlyphAtlas[key] = atlas;
+    }
+    // The atlas may exist, but an image key may not be assigned for it to
+    // the given layer manager.
+    auto* tdt = static_cast<layout::TextDrawTarget*>(&aDrawTarget);
+    auto* manager = tdt->WrLayerManager();
+    if (!atlas->GetUserData(reinterpret_cast<UserDataKey*>(manager))) {
+        // No image key, so we need to map the atlas' data for transfer to WR.
+        RefPtr<DataSourceSurface> dataSurface = atlas->GetDataSurface();
+        if (!dataSurface) {
+            return nullptr;
+        }
+        DataSourceSurface::ScopedMap map(dataSurface, DataSourceSurface::READ);
+        if (!map.IsMapped()) {
+            return nullptr;
+        }
+        // Transfer the data and get an image key for it.
+        Maybe<wr::ImageKey> result =
+            tdt->DefineImage(atlas->GetSize(),
+                             map.GetStride(),
+                             atlas->GetFormat(),
+                             map.GetData());
+        if (!result.isSome()) {
+            return nullptr;
+        }
+        // Assign the image key to the atlas.
+        atlas->AddUserData(reinterpret_cast<UserDataKey*>(manager),
+                           (void*)(uintptr_t)result.value().mHandle,
+                           nullptr);
+        // Create a user data notification for when the layer manager is
+        // destroyed so we can clean up any assigned image keys.
+        WRUserData::Assign(manager);
+    }
+    return atlas.forget();
 }
-#endif // MOZ_GFX_OPTIMIZE_MOBILE
+
+static void
+DrawHexChar(uint32_t aDigit, Float aLeft, Float aTop, DrawTarget& aDrawTarget,
+            SourceSurface* aAtlas, const Color& aColor,
+            const Matrix* aMat = nullptr)
+{
+    Rect dest(aLeft, aTop, MINIFONT_WIDTH, MINIFONT_HEIGHT);
+    if (aDrawTarget.GetBackendType() == BackendType::WEBRENDER_TEXT) {
+        // For WR, we need to get the image key assigned to the given WR layer manager
+        // for referencing the image.
+        auto* tdt = static_cast<layout::TextDrawTarget*>(&aDrawTarget);
+        auto* manager = tdt->WrLayerManager();
+        wr::ImageKey key = {
+            manager->WrBridge()->GetNamespace(),
+            (uint32_t)(uintptr_t)aAtlas->GetUserData(reinterpret_cast<UserDataKey*>(manager))
+        };
+        // Transform the bounds of the atlas into the given orientation, and then also transform
+        // a small clip rect which will be used to select the given digit from the atlas.
+        Rect bounds(aLeft - aDigit * MINIFONT_WIDTH, aTop, MINIFONT_WIDTH * 16, MINIFONT_HEIGHT);
+        if (aMat) {
+            // Width and height may be negative after the transform, so move the rect
+            // if necessary and fix size.
+            bounds = aMat->TransformRect(bounds);
+            bounds.x += std::min(bounds.width, 0.0f);
+            bounds.y += std::min(bounds.height, 0.0f);
+            bounds.width = fabs(bounds.width);
+            bounds.height = fabs(bounds.height);
+            dest = aMat->TransformRect(dest);
+            dest.x += std::min(dest.width, 0.0f);
+            dest.y += std::min(dest.height, 0.0f);
+            dest.width = fabs(dest.width);
+            dest.height = fabs(dest.height);
+        }
+        // Finally, push the colored image with point filtering.
+        tdt->PushImage(key,
+                       wr::ToLayoutRect(bounds),
+                       wr::ToLayoutRect(dest),
+                       wr::ImageRendering::Pixelated,
+                       wr::ToColorF(aColor));
+    } else {
+        // For the normal case, just draw the given digit from the atlas. Point filtering is used
+        // to ensure the mini-font rectangles stay sharp with any scaling. Handle any transparency
+        // here as well.
+        aDrawTarget.DrawSurface(aAtlas,
+                                dest,
+                                Rect(aDigit * MINIFONT_WIDTH, 0, MINIFONT_WIDTH, MINIFONT_HEIGHT),
+                                DrawSurfaceOptions(SamplingFilter::POINT),
+                                DrawOptions(aColor.a, CompositionOp::OP_OVER, AntialiasMode::NONE));
+    }
+}
+
+void
+gfxFontMissingGlyphs::Purge()
+{
+    PurgeGlyphAtlas();
+    PurgeWRGlyphAtlas();
+}
+
+#else // MOZ_GFX_OPTIMIZE_MOBILE
+
+void
+gfxFontMissingGlyphs::Purge()
+{
+}
+
+#endif
+
+void
+gfxFontMissingGlyphs::Shutdown()
+{
+    Purge();
+}
 
 void
 gfxFontMissingGlyphs::DrawMissingGlyph(uint32_t aChar,
                                        const Rect& aRect,
                                        DrawTarget& aDrawTarget,
                                        const Pattern& aPattern,
                                        uint32_t aAppUnitsPerDevPixel,
                                        const Matrix* aMat)
@@ -223,41 +397,49 @@ gfxFontMissingGlyphs::DrawMissingGlyph(u
     if (aMat) {
         rect.MoveBy(-aRect.BottomLeft());
         rect = aMat->TransformBounds(rect);
         rect.MoveBy(aRect.BottomLeft());
     }
 
     // If we're currently drawing with some kind of pattern, we just draw the
     // missing-glyph data in black.
-    ColorPattern color = aPattern.GetType() == PatternType::COLOR ?
-        static_cast<const ColorPattern&>(aPattern) :
-        ColorPattern(ToDeviceColor(Color(0.f, 0.f, 0.f, 1.f)));
+    Color color = aPattern.GetType() == PatternType::COLOR ?
+        static_cast<const ColorPattern&>(aPattern).mColor :
+        ToDeviceColor(Color(0.f, 0.f, 0.f, 1.f));
 
     // Stroke a rectangle so that the stroke's left edge is inset one pixel
     // from the left edge of the glyph box and the stroke's right edge
     // is inset one pixel from the right edge of the glyph box.
     Float halfBorderWidth = BOX_BORDER_WIDTH / 2.0;
     Float borderLeft = rect.X() + BOX_HORIZONTAL_INSET + halfBorderWidth;
     Float borderRight = rect.XMost() - BOX_HORIZONTAL_INSET - halfBorderWidth;
     Rect borderStrokeRect(borderLeft, rect.Y() + halfBorderWidth,
                           borderRight - borderLeft,
                           rect.Height() - 2.0 * halfBorderWidth);
     if (!borderStrokeRect.IsEmpty()) {
-        ColorPattern adjustedColor = color;
+        ColorPattern adjustedColor(color);
         adjustedColor.mColor.a *= BOX_BORDER_OPACITY;
 #ifdef MOZ_GFX_OPTIMIZE_MOBILE
         aDrawTarget.FillRect(borderStrokeRect, adjustedColor);
 #else
         StrokeOptions strokeOptions(BOX_BORDER_WIDTH);
         aDrawTarget.StrokeRect(borderStrokeRect, adjustedColor, strokeOptions);
 #endif
     }
 
 #ifndef MOZ_GFX_OPTIMIZE_MOBILE
+    RefPtr<SourceSurface> atlas =
+        aDrawTarget.GetBackendType() == BackendType::WEBRENDER_TEXT ?
+            GetWRGlyphAtlas(aDrawTarget, aMat) :
+            GetGlyphAtlas(color);
+    if (!atlas) {
+        return;
+    }
+
     Point center = rect.Center();
     Float halfGap = HEX_CHAR_GAP / 2.f;
     Float top = -(MINIFONT_HEIGHT + halfGap);
     // We always want integer scaling, otherwise the "bitmap" glyphs will look
     // even uglier than usual when zoomed
     int32_t devPixelsPerCSSPx =
         std::max<int32_t>(1, AppUnitsPerCSSPixel() /
                              aAppUnitsPerDevPixel);
@@ -279,44 +461,34 @@ gfxFontMissingGlyphs::DrawMissingGlyph(u
                            .PreScale(devPixelsPerCSSPx, devPixelsPerCSSPx));
     }
 
     if (aChar < 0x10000) {
         if (rect.Width() >= 2 * (MINIFONT_WIDTH + HEX_CHAR_GAP) &&
             rect.Height() >= 2 * MINIFONT_HEIGHT + HEX_CHAR_GAP) {
             // Draw 4 digits for BMP
             Float left = -(MINIFONT_WIDTH + halfGap);
-            DrawHexChar((aChar >> 12) & 0xF,
-                        Point(left, top), aDrawTarget, color, aMat);
-            DrawHexChar((aChar >> 8) & 0xF,
-                        Point(halfGap, top), aDrawTarget, color, aMat);
-            DrawHexChar((aChar >> 4) & 0xF,
-                        Point(left, halfGap), aDrawTarget, color, aMat);
-            DrawHexChar(aChar & 0xF,
-                        Point(halfGap, halfGap), aDrawTarget, color, aMat);
+            DrawHexChar((aChar >> 12) & 0xF, left, top, aDrawTarget, atlas, color, aMat);
+            DrawHexChar((aChar >> 8) & 0xF, halfGap, top, aDrawTarget, atlas, color, aMat);
+            DrawHexChar((aChar >> 4) & 0xF, left, halfGap, aDrawTarget, atlas, color, aMat);
+            DrawHexChar(aChar & 0xF, halfGap, halfGap, aDrawTarget, atlas, color, aMat);
         }
     } else {
         if (rect.Width() >= 3 * (MINIFONT_WIDTH + HEX_CHAR_GAP) &&
             rect.Height() >= 2 * MINIFONT_HEIGHT + HEX_CHAR_GAP) {
             // Draw 6 digits for non-BMP
             Float first = -(MINIFONT_WIDTH * 1.5 + HEX_CHAR_GAP);
             Float second = -(MINIFONT_WIDTH / 2.0);
             Float third = (MINIFONT_WIDTH / 2.0 + HEX_CHAR_GAP);
-            DrawHexChar((aChar >> 20) & 0xF,
-                        Point(first, top), aDrawTarget, color, aMat);
-            DrawHexChar((aChar >> 16) & 0xF,
-                        Point(second, top), aDrawTarget, color, aMat);
-            DrawHexChar((aChar >> 12) & 0xF,
-                        Point(third, top), aDrawTarget, color, aMat);
-            DrawHexChar((aChar >> 8) & 0xF,
-                        Point(first, halfGap), aDrawTarget, color, aMat);
-            DrawHexChar((aChar >> 4) & 0xF,
-                        Point(second, halfGap), aDrawTarget, color, aMat);
-            DrawHexChar(aChar & 0xF,
-                        Point(third, halfGap), aDrawTarget, color, aMat);
+            DrawHexChar((aChar >> 20) & 0xF, first, top, aDrawTarget, atlas, color, aMat);
+            DrawHexChar((aChar >> 16) & 0xF, second, top, aDrawTarget, atlas, color, aMat);
+            DrawHexChar((aChar >> 12) & 0xF, third, top, aDrawTarget, atlas, color, aMat);
+            DrawHexChar((aChar >> 8) & 0xF, first, halfGap, aDrawTarget, atlas, color, aMat);
+            DrawHexChar((aChar >> 4) & 0xF, second, halfGap, aDrawTarget, atlas, color, aMat);
+            DrawHexChar(aChar & 0xF, third, halfGap, aDrawTarget, atlas, color, aMat);
         }
     }
 
     if (!aMat) {
         // The draw target transform was changed, so it must be restored to
         // the original value.
         aDrawTarget.SetTransform(tempMat);
     }
--- a/gfx/thebes/gfxFontMissingGlyphs.h
+++ b/gfx/thebes/gfxFontMissingGlyphs.h
@@ -49,11 +49,15 @@ public:
                                  uint32_t aAppUnitsPerDevPixel,
                                  const Matrix* aMat = nullptr);
     /**
      * @return the desired minimum width for a glyph-box that will allow
      * the hexboxes to be drawn reasonably.
      */
     static Float GetDesiredMinWidth(uint32_t aChar,
                                     uint32_t aAppUnitsPerDevUnit);
+
+    static void Purge();
+
+    static void Shutdown();
 };
 
 #endif
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -68,16 +68,17 @@
 #include "gfxContext.h"
 #include "gfxImageSurface.h"
 #include "nsUnicodeProperties.h"
 #include "harfbuzz/hb.h"
 #include "gfxGraphiteShaper.h"
 #include "gfx2DGlue.h"
 #include "gfxGradientCache.h"
 #include "gfxUtils.h" // for NextPowerOfTwo
+#include "gfxFontMissingGlyphs.h"
 
 #include "nsExceptionHandler.h"
 #include "nsUnicodeRange.h"
 #include "nsServiceManagerUtils.h"
 #include "nsTArray.h"
 #include "nsIObserverService.h"
 #include "nsIScreenManager.h"
 #include "FrameMetrics.h"
@@ -465,16 +466,17 @@ FontPrefChanged(const char* aPref, void*
     gfxPlatform::GetPlatform()->FontsPrefsChanged(aPref);
 }
 
 void
 gfxPlatform::OnMemoryPressure(layers::MemoryPressureReason aWhy)
 {
     Factory::PurgeAllCaches();
     gfxGradientCache::PurgeAllCaches();
+    gfxFontMissingGlyphs::Purge();
     PurgeSkiaFontCache();
     PurgeSkiaGPUCache();
     if (XRE_IsParentProcess()) {
       layers::CompositorManagerChild* manager = CompositorManagerChild::GetInstance();
       if (manager) {
         manager->SendNotifyMemoryPressure();
       }
     }
@@ -959,16 +961,17 @@ gfxPlatform::Shutdown()
 
     // These may be called before the corresponding subsystems have actually
     // started up. That's OK, they can handle it.
     gfxFontCache::Shutdown();
     gfxGradientCache::Shutdown();
     gfxAlphaBoxBlur::ShutdownBlurCache();
     gfxGraphiteShaper::Shutdown();
     gfxPlatformFontList::Shutdown();
+    gfxFontMissingGlyphs::Shutdown();
     ShutdownTileCache();
 
     // Free the various non-null transforms and loaded profiles
     ShutdownCMS();
 
     /* Unregister our CMS Override callback. */
     NS_ASSERTION(gPlatform->mSRGBOverrideObserver, "mSRGBOverrideObserver has alreay gone");
     Preferences::RemoveObserver(gPlatform->mSRGBOverrideObserver, GFX_PREF_CMS_FORCE_SRGB);
--- a/gfx/webrender_bindings/WebRenderAPI.cpp
+++ b/gfx/webrender_bindings/WebRenderAPI.cpp
@@ -1042,39 +1042,41 @@ DisplayListBuilder::PushRadialGradient(c
 }
 
 void
 DisplayListBuilder::PushImage(const wr::LayoutRect& aBounds,
                               const wr::LayoutRect& aClip,
                               bool aIsBackfaceVisible,
                               wr::ImageRendering aFilter,
                               wr::ImageKey aImage,
-                              bool aPremultipliedAlpha)
+                              bool aPremultipliedAlpha,
+                              const wr::ColorF& aColor)
 {
   wr::LayoutSize size;
   size.width = aBounds.size.width;
   size.height = aBounds.size.height;
-  PushImage(aBounds, aClip, aIsBackfaceVisible, size, size, aFilter, aImage, aPremultipliedAlpha);
+  PushImage(aBounds, aClip, aIsBackfaceVisible, size, size, aFilter, aImage, aPremultipliedAlpha, aColor);
 }
 
 void
 DisplayListBuilder::PushImage(const wr::LayoutRect& aBounds,
                               const wr::LayoutRect& aClip,
                               bool aIsBackfaceVisible,
                               const wr::LayoutSize& aStretchSize,
                               const wr::LayoutSize& aTileSpacing,
                               wr::ImageRendering aFilter,
                               wr::ImageKey aImage,
-                              bool aPremultipliedAlpha)
+                              bool aPremultipliedAlpha,
+                              const wr::ColorF& aColor)
 {
   WRDL_LOG("PushImage b=%s cl=%s s=%s t=%s\n", mWrState,
       Stringify(aBounds).c_str(),
       Stringify(aClip).c_str(), Stringify(aStretchSize).c_str(),
       Stringify(aTileSpacing).c_str());
-  wr_dp_push_image(mWrState, aBounds, aClip, aIsBackfaceVisible, aStretchSize, aTileSpacing, aFilter, aImage, aPremultipliedAlpha);
+  wr_dp_push_image(mWrState, aBounds, aClip, aIsBackfaceVisible, aStretchSize, aTileSpacing, aFilter, aImage, aPremultipliedAlpha, aColor);
 }
 
 void
 DisplayListBuilder::PushYCbCrPlanarImage(const wr::LayoutRect& aBounds,
                                          const wr::LayoutRect& aClip,
                                          bool aIsBackfaceVisible,
                                          wr::ImageKey aImageChannel0,
                                          wr::ImageKey aImageChannel1,
--- a/gfx/webrender_bindings/WebRenderAPI.h
+++ b/gfx/webrender_bindings/WebRenderAPI.h
@@ -366,26 +366,28 @@ public:
                           const wr::LayoutSize aTileSize,
                           const wr::LayoutSize aTileSpacing);
 
   void PushImage(const wr::LayoutRect& aBounds,
                  const wr::LayoutRect& aClip,
                  bool aIsBackfaceVisible,
                  wr::ImageRendering aFilter,
                  wr::ImageKey aImage,
-                 bool aPremultipliedAlpha = true);
+                 bool aPremultipliedAlpha = true,
+                 const wr::ColorF& aColor = wr::ColorF{1.0f, 1.0f, 1.0f, 1.0f});
 
   void PushImage(const wr::LayoutRect& aBounds,
                  const wr::LayoutRect& aClip,
                  bool aIsBackfaceVisible,
                  const wr::LayoutSize& aStretchSize,
                  const wr::LayoutSize& aTileSpacing,
                  wr::ImageRendering aFilter,
                  wr::ImageKey aImage,
-                 bool aPremultipliedAlpha = true);
+                 bool aPremultipliedAlpha = true,
+                 const wr::ColorF& aColor = wr::ColorF{1.0f, 1.0f, 1.0f, 1.0f});
 
   void PushYCbCrPlanarImage(const wr::LayoutRect& aBounds,
                             const wr::LayoutRect& aClip,
                             bool aIsBackfaceVisible,
                             wr::ImageKey aImageChannel0,
                             wr::ImageKey aImageChannel1,
                             wr::ImageKey aImageChannel2,
                             wr::WrYuvColorSpace aColorSpace,
--- a/gfx/webrender_bindings/src/bindings.rs
+++ b/gfx/webrender_bindings/src/bindings.rs
@@ -1955,17 +1955,18 @@ pub extern "C" fn wr_dp_push_clear_rect(
 pub extern "C" fn wr_dp_push_image(state: &mut WrState,
                                    bounds: LayoutRect,
                                    clip: LayoutRect,
                                    is_backface_visible: bool,
                                    stretch_size: LayoutSize,
                                    tile_spacing: LayoutSize,
                                    image_rendering: ImageRendering,
                                    key: WrImageKey,
-                                   premultiplied_alpha: bool) {
+                                   premultiplied_alpha: bool,
+                                   color: ColorF) {
     debug_assert!(unsafe { is_in_main_thread() || is_in_compositor_thread() });
 
     let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(bounds, clip.into());
     prim_info.is_backface_visible = is_backface_visible;
     prim_info.tag = state.current_tag;
     let alpha_type = if premultiplied_alpha {
         AlphaType::PremultipliedAlpha
     } else {
@@ -1974,17 +1975,17 @@ pub extern "C" fn wr_dp_push_image(state
     state.frame_builder
          .dl_builder
          .push_image(&prim_info,
                      stretch_size,
                      tile_spacing,
                      image_rendering,
                      alpha_type,
                      key,
-                     ColorF::WHITE);
+                     color);
 }
 
 /// Push a 3 planar yuv image.
 #[no_mangle]
 pub extern "C" fn wr_dp_push_yuv_planar_image(state: &mut WrState,
                                               bounds: LayoutRect,
                                               clip: LayoutRect,
                                               is_backface_visible: bool,
--- a/gfx/webrender_bindings/webrender_ffi_generated.h
+++ b/gfx/webrender_bindings/webrender_ffi_generated.h
@@ -1290,17 +1290,18 @@ WR_INLINE
 void wr_dp_push_image(WrState *aState,
                       LayoutRect aBounds,
                       LayoutRect aClip,
                       bool aIsBackfaceVisible,
                       LayoutSize aStretchSize,
                       LayoutSize aTileSpacing,
                       ImageRendering aImageRendering,
                       WrImageKey aKey,
-                      bool aPremultipliedAlpha)
+                      bool aPremultipliedAlpha,
+                      ColorF color)
 WR_FUNC;
 
 WR_INLINE
 void wr_dp_push_line(WrState *aState,
                      const LayoutRect *aClip,
                      bool aIsBackfaceVisible,
                      const LayoutRect *aBounds,
                      float aWavyLineThickness,
--- a/js/src/jit/ProcessExecutableMemory.cpp
+++ b/js/src/jit/ProcessExecutableMemory.cpp
@@ -39,16 +39,21 @@
 #ifdef MOZ_VALGRIND
 # include <valgrind/valgrind.h>
 #endif
 
 using namespace js;
 using namespace js::jit;
 
 #ifdef XP_WIN
+// TODO: implement the necessary support for AArch64.
+# if defined(HAVE_64BIT_BUILD) && defined(_M_X64)
+#  define NEED_JIT_UNWIND_HANDLING
+# endif
+
 static void*
 ComputeRandomAllocationAddress()
 {
     /*
      * Inspiration is V8's OS::Allocate in platform-win32.cc.
      *
      * VirtualAlloc takes 64K chunks out of the virtual address space, so we
      * keep 16b alignment.
@@ -67,17 +72,17 @@ ComputeRandomAllocationAddress()
 # else
 #  error "Unsupported architecture"
 # endif
 
     uint64_t rand = js::GenerateRandomSeed();
     return (void*) (base | (rand & mask));
 }
 
-# ifdef HAVE_64BIT_BUILD
+# ifdef NEED_JIT_UNWIND_HANDLING
 static js::JitExceptionHandler sJitExceptionHandler;
 
 JS_FRIEND_API(void)
 js::SetJitExceptionHandler(JitExceptionHandler handler)
 {
     MOZ_ASSERT(!sJitExceptionHandler);
     sJitExceptionHandler = handler;
 }
@@ -178,17 +183,17 @@ UnregisterExecutableMemory(void* p, size
     AutoSuppressStackWalking suppress;
     RtlDeleteFunctionTable(&r->runtimeFunction);
 }
 # endif
 
 static void*
 ReserveProcessExecutableMemory(size_t bytes)
 {
-# ifdef HAVE_64BIT_BUILD
+# ifdef NEED_JIT_UNWIND_HANDLING
     size_t pageSize = gc::SystemPageSize();
     if (sJitExceptionHandler)
         bytes += pageSize;
 # endif
 
     void* p = nullptr;
     for (size_t i = 0; i < 10; i++) {
         void* randomAddr = ComputeRandomAllocationAddress();
@@ -199,17 +204,17 @@ ReserveProcessExecutableMemory(size_t by
 
     if (!p) {
         // Try again without randomization.
         p = VirtualAlloc(nullptr, bytes, MEM_RESERVE, PAGE_NOACCESS);
         if (!p)
             return nullptr;
     }
 
-# ifdef HAVE_64BIT_BUILD
+# ifdef NEED_JIT_UNWIND_HANDLING
     if (sJitExceptionHandler) {
         if (!RegisterExecutableMemory(p, bytes, pageSize)) {
             VirtualFree(p, 0, MEM_RELEASE);
             return nullptr;
         }
 
         p = (uint8_t*)p + pageSize;
         bytes -= pageSize;
@@ -219,17 +224,17 @@ ReserveProcessExecutableMemory(size_t by
 # endif
 
     return p;
 }
 
 static void
 DeallocateProcessExecutableMemory(void* addr, size_t bytes)
 {
-# ifdef HAVE_64BIT_BUILD
+# ifdef NEED_JIT_UNWIND_HANDLING
     UnregisterJitCodeRegion((uint8_t*)addr, bytes);
 
     if (sJitExceptionHandler) {
         size_t pageSize = gc::SystemPageSize();
         addr = (uint8_t*)addr - pageSize;
         UnregisterExecutableMemory(addr, bytes, pageSize);
     }
 # endif
--- a/js/src/jit/mips32/Simulator-mips32.cpp
+++ b/js/src/jit/mips32/Simulator-mips32.cpp
@@ -1368,37 +1368,31 @@ class Redirection
 Simulator::~Simulator()
 {
     js_free(stack_);
 }
 
 SimulatorProcess::SimulatorProcess()
   : cacheLock_(mutexid::SimulatorCacheLock)
   , redirection_(nullptr)
-{}
+{
+    if (getenv("MIPS_SIM_ICACHE_CHECKS"))
+        ICacheCheckingDisableCount = 0;
+}
 
 SimulatorProcess::~SimulatorProcess()
 {
     Redirection* r = redirection_;
     while (r) {
         Redirection* next = r->next_;
         js_delete(r);
         r = next;
     }
 }
 
-bool
-SimulatorProcess::init()
-{
-    if (getenv("MIPS_SIM_ICACHE_CHECKS"))
-        ICacheCheckingDisableCount = 0;
-
-    return icache_.init();
-}
-
 /* static */ void*
 Simulator::RedirectNativeFunction(void* nativeFunction, ABIFunctionType type)
 {
     Redirection* redirection = Redirection::Get(nativeFunction, type);
     return redirection->addressOfSwiInstruction();
 }
 
 // Get the active Simulator for the current thread.
--- a/js/src/jit/mips32/Simulator-mips32.h
+++ b/js/src/jit/mips32/Simulator-mips32.h
@@ -415,29 +415,27 @@ class SimulatorProcess
 
     static mozilla::Atomic<size_t, mozilla::ReleaseAcquire> ICacheCheckingDisableCount;
     static void FlushICache(void* start, size_t size);
 
     static void checkICacheLocked(SimInstruction* instr);
 
     static bool initialize() {
         singleton_ = js_new<SimulatorProcess>();
-        return singleton_ && singleton_->init();
+        return singleton_;
     }
     static void destroy() {
         js_delete(singleton_);
         singleton_ = nullptr;
     }
 
     SimulatorProcess();
     ~SimulatorProcess();
 
   private:
-    bool init();
-
     static SimulatorProcess* singleton_;
 
     // This lock creates a critical section around 'redirection_' and
     // 'icache_', which are referenced both by the execution engine
     // and by the off-thread compiler (see Redirection::Get in the cpp file).
     Mutex cacheLock_;
 
     Redirection* redirection_;
--- a/js/src/jit/mips64/Simulator-mips64.cpp
+++ b/js/src/jit/mips64/Simulator-mips64.cpp
@@ -1376,37 +1376,31 @@ class Redirection
 Simulator::~Simulator()
 {
     js_free(stack_);
 }
 
 SimulatorProcess::SimulatorProcess()
   : cacheLock_(mutexid::SimulatorCacheLock)
   , redirection_(nullptr)
-{}
+{
+    if (getenv("MIPS_SIM_ICACHE_CHECKS"))
+        ICacheCheckingDisableCount = 0;
+}
 
 SimulatorProcess::~SimulatorProcess()
 {
     Redirection* r = redirection_;
     while (r) {
         Redirection* next = r->next_;
         js_delete(r);
         r = next;
     }
 }
 
-bool
-SimulatorProcess::init()
-{
-    if (getenv("MIPS_SIM_ICACHE_CHECKS"))
-        ICacheCheckingDisableCount = 0;
-
-    return icache_.init();
-}
-
 /* static */ void*
 Simulator::RedirectNativeFunction(void* nativeFunction, ABIFunctionType type)
 {
     Redirection* redirection = Redirection::Get(nativeFunction, type);
     return redirection->addressOfSwiInstruction();
 }
 
 // Get the active Simulator for the current thread.
--- a/js/src/jit/mips64/Simulator-mips64.h
+++ b/js/src/jit/mips64/Simulator-mips64.h
@@ -422,29 +422,27 @@ class SimulatorProcess
 
     static mozilla::Atomic<size_t, mozilla::ReleaseAcquire> ICacheCheckingDisableCount;
     static void FlushICache(void* start, size_t size);
 
     static void checkICacheLocked(SimInstruction* instr);
 
     static bool initialize() {
         singleton_ = js_new<SimulatorProcess>();
-        return singleton_ && singleton_->init();
+        return singleton_;
     }
     static void destroy() {
         js_delete(singleton_);
         singleton_ = nullptr;
     }
 
     SimulatorProcess();
     ~SimulatorProcess();
 
   private:
-    bool init();
-
     static SimulatorProcess* singleton_;
 
     // This lock creates a critical section around 'redirection_' and
     // 'icache_', which are referenced both by the execution engine
     // and by the off-thread compiler (see Redirection::Get in the cpp file).
     Mutex cacheLock_;
 
     Redirection* redirection_;
--- a/js/src/vm/JSScript.cpp
+++ b/js/src/vm/JSScript.cpp
@@ -4443,18 +4443,30 @@ JSScript::updateJitCodeRaw(JSRuntime* rt
 bool
 JSScript::hasLoops()
 {
     if (!hasTrynotes())
         return false;
     JSTryNote* tn = trynotes()->vector;
     JSTryNote* tnlimit = tn + trynotes()->length;
     for (; tn < tnlimit; tn++) {
-        if (tn->kind == JSTRY_FOR_IN || tn->kind == JSTRY_LOOP)
+        switch (tn->kind) {
+          case JSTRY_FOR_IN:
+          case JSTRY_FOR_OF:
+          case JSTRY_LOOP:
             return true;
+          case JSTRY_CATCH:
+          case JSTRY_FINALLY:
+          case JSTRY_FOR_OF_ITERCLOSE:
+          case JSTRY_DESTRUCTURING_ITERCLOSE:
+            break;
+          default:
+            MOZ_ASSERT(false, "Add new try note type to JSScript::hasLoops");
+            break;
+        }
     }
     return false;
 }
 
 bool
 JSScript::mayReadFrameArgsDirectly()
 {
     return argumentsHasVarBinding() || hasRest();
--- a/layout/generic/TextDrawTarget.h
+++ b/layout/generic/TextDrawTarget.h
@@ -7,16 +7,17 @@
 #ifndef TextDrawTarget_h
 #define TextDrawTarget_h
 
 #include "mozilla/gfx/2D.h"
 #include "mozilla/layers/WebRenderLayerManager.h"
 #include "mozilla/layers/WebRenderBridgeChild.h"
 #include "mozilla/webrender/WebRenderAPI.h"
 #include "mozilla/layers/StackingContextHelper.h"
+#include "mozilla/layers/IpcResourceUpdateQueue.h"
 
 namespace mozilla {
 namespace layout {
 
 using namespace gfx;
 
 // This class is fake DrawTarget, used to intercept text draw calls, while
 // also collecting up the other aspects of text natively.
@@ -45,21 +46,22 @@ using namespace gfx;
 // while we further develop the design.
 //
 // TextDrawTarget doesn't yet support all features. See mHasUnsupportedFeatures
 // for details.
 class TextDrawTarget : public DrawTarget
 {
 public:
   explicit TextDrawTarget(wr::DisplayListBuilder& aBuilder,
+                          wr::IpcResourceUpdateQueue& aResources,
                           const layers::StackingContextHelper& aSc,
                           layers::WebRenderLayerManager* aManager,
                           nsDisplayItem* aItem,
                           nsRect& aBounds)
-    : mBuilder(aBuilder), mSc(aSc), mManager(aManager)
+    : mBuilder(aBuilder), mResources(aResources), mSc(aSc), mManager(aManager)
   {
     SetPermitSubpixelAA(!aItem->IsSubpixelAADisabled());
 
     // Compute clip/bounds
     auto appUnitsPerDevPixel = aItem->Frame()->PresContext()->AppUnitsPerDevPixel();
     LayoutDeviceRect layoutBoundsRect = LayoutDeviceRect::FromAppUnits(
         aBounds, appUnitsPerDevPixel);
     LayoutDeviceRect layoutClipRect = layoutBoundsRect;
@@ -297,16 +299,43 @@ public:
     decoration.orientation = aVertical
       ? wr::LineOrientation::Vertical
       : wr::LineOrientation::Horizontal;
     decoration.style = wr::LineStyle::Wavy;
 
     mBuilder.PushLine(ClipRect(), mBackfaceVisible, decoration);
   }
 
+  layers::WebRenderBridgeChild* WrBridge() { return mManager->WrBridge(); }
+  layers::WebRenderLayerManager* WrLayerManager() { return mManager; }
+
+  Maybe<wr::ImageKey>
+  DefineImage(const IntSize& aSize,
+              uint32_t aStride,
+              SurfaceFormat aFormat,
+              const uint8_t* aData)
+  {
+    wr::ImageKey key = mManager->WrBridge()->GetNextImageKey();
+    wr::ImageDescriptor desc(aSize, aStride, aFormat);
+    Range<uint8_t> bytes(const_cast<uint8_t*>(aData), aStride * aSize.height);
+    if (mResources.AddImage(key, desc, bytes)) {
+        return Some(key);
+    }
+    return Nothing();
+  }
+
+  void PushImage(wr::ImageKey aKey,
+                 const wr::LayoutRect& aBounds,
+                 const wr::LayoutRect& aClip,
+                 wr::ImageRendering aFilter,
+                 const wr::ColorF& aColor)
+  {
+    mBuilder.PushImage(aBounds, aClip, true, aFilter, aKey, true, aColor);
+  }
+
 private:
   wr::LayoutRect ClipRect()
   {
     return wr::ToRoundedLayoutRect(mClipStack.LastElement());
   }
   // Whether anything unsupported was encountered. Currently:
   //
   // * Synthetic bold/italics
@@ -318,16 +347,17 @@ private:
   // * Text stroke
   bool mHasUnsupportedFeatures = false;
 
   // Whether PopAllShadows needs to be called
   bool mHasShadows = false;
 
   // Things used to push to webrender
   wr::DisplayListBuilder& mBuilder;
+  wr::IpcResourceUpdateQueue& mResources;
   const layers::StackingContextHelper& mSc;
   layers::WebRenderLayerManager* mManager;
 
   // Computed facts
   IntSize mSize;
   wr::LayoutRect mBoundsRect;
   nsTArray<LayoutDeviceRect> mClipStack;
   bool mBackfaceVisible;
@@ -413,44 +443,39 @@ public:
 
   void StrokeRect(const Rect &aRect,
                   const Pattern &aPattern,
                   const StrokeOptions &aStrokeOptions,
                   const DrawOptions &aOptions) override {
     MOZ_RELEASE_ASSERT(aPattern.GetType() == PatternType::COLOR &&
                        aStrokeOptions.mDashLength == 0);
 
-    wr::Line line;
-    line.wavyLineThickness = 0; // dummy value, unused
-    line.color = wr::ToColorF(static_cast<const ColorPattern&>(aPattern).mColor);
-    line.style = wr::LineStyle::Solid;
-
-    // Top horizontal line
-    LayoutDevicePoint top(aRect.x, aRect.y - aStrokeOptions.mLineWidth / 2);
-    LayoutDeviceSize horiSize(aRect.width, aStrokeOptions.mLineWidth);
-    line.bounds = wr::ToRoundedLayoutRect(LayoutDeviceRect(top, horiSize));
-    line.orientation = wr::LineOrientation::Horizontal;
-    mBuilder.PushLine(ClipRect(), mBackfaceVisible, line);
-
-    // Bottom horizontal line
-    LayoutDevicePoint bottom(aRect.x, aRect.YMost() - aStrokeOptions.mLineWidth / 2);
-    line.bounds = wr::ToRoundedLayoutRect(LayoutDeviceRect(bottom, horiSize));
-    mBuilder.PushLine(ClipRect(), mBackfaceVisible, line);
-
-    // Left vertical line
-    LayoutDevicePoint left(aRect.x + aStrokeOptions.mLineWidth / 2, aRect.y + aStrokeOptions.mLineWidth / 2);
-    LayoutDeviceSize vertSize(aStrokeOptions.mLineWidth, aRect.height - aStrokeOptions.mLineWidth);
-    line.bounds = wr::ToRoundedLayoutRect(LayoutDeviceRect(left, vertSize));
-    line.orientation = wr::LineOrientation::Vertical;
-    mBuilder.PushLine(ClipRect(), mBackfaceVisible, line);
-
-    // Right vertical line
-    LayoutDevicePoint right(aRect.XMost() - aStrokeOptions.mLineWidth / 2, aRect.y + aStrokeOptions.mLineWidth / 2);
-    line.bounds = wr::ToRoundedLayoutRect(LayoutDeviceRect(right, vertSize));
-    mBuilder.PushLine(ClipRect(), mBackfaceVisible, line);
+    wr::BorderWidths widths = {
+        aStrokeOptions.mLineWidth,
+        aStrokeOptions.mLineWidth,
+        aStrokeOptions.mLineWidth,
+        aStrokeOptions.mLineWidth
+    };
+    wr::ColorF color = wr::ToColorF(static_cast<const ColorPattern&>(aPattern).mColor);
+    wr::BorderSide sides[4] = {
+        { color, wr::BorderStyle::Solid },
+        { color, wr::BorderStyle::Solid },
+        { color, wr::BorderStyle::Solid },
+        { color, wr::BorderStyle::Solid }
+    };
+    wr::BorderRadius radius = {
+        { 0, 0 },
+        { 0, 0 },
+        { 0, 0 },
+        { 0, 0 }
+    };
+    Rect rect(aRect);
+    rect.Inflate(aStrokeOptions.mLineWidth / 2);
+    wr::LayoutRect bounds = wr::ToRoundedLayoutRect(LayoutDeviceRect::FromUnknownRect(rect));
+    mBuilder.PushBorder(bounds, ClipRect(), true, widths, Range<const wr::BorderSide>(sides, 4), radius);
   }
 
   void StrokeLine(const Point &aStart,
                   const Point &aEnd,
                   const Pattern &aPattern,
                   const StrokeOptions &aStrokeOptions,
                   const DrawOptions &aOptions) override {
     MOZ_CRASH("TextDrawTarget: Method shouldn't be called");
--- a/layout/generic/TextOverflow.cpp
+++ b/layout/generic/TextOverflow.cpp
@@ -299,17 +299,17 @@ nsDisplayTextOverflowMarker::CreateWebRe
 {
   bool snap;
   nsRect bounds = GetBounds(aDisplayListBuilder, &snap);
   if (bounds.IsEmpty()) {
     return true;
   }
 
   // Run the rendering algorithm to capture the glyphs and shadows
-  RefPtr<TextDrawTarget> textDrawer = new TextDrawTarget(aBuilder, aSc, aManager, this, bounds);
+  RefPtr<TextDrawTarget> textDrawer = new TextDrawTarget(aBuilder, aResources, aSc, aManager, this, bounds);
   RefPtr<gfxContext> captureCtx = gfxContext::CreateOrNull(textDrawer);
   Paint(aDisplayListBuilder, captureCtx);
   textDrawer->TerminateShadows();
 
   return !textDrawer->HasUnsupportedFeatures();
 }
 
 
--- a/layout/generic/nsBulletFrame.cpp
+++ b/layout/generic/nsBulletFrame.cpp
@@ -565,17 +565,17 @@ BulletRenderer::CreateWebRenderCommandsF
 
   bool dummy;
   nsRect bounds = aItem->GetBounds(aDisplayListBuilder, &dummy);
 
   if (bounds.IsEmpty()) {
     return true;
   }
 
-  RefPtr<TextDrawTarget> textDrawer = new TextDrawTarget(aBuilder, aSc, aManager, aItem, bounds);
+  RefPtr<TextDrawTarget> textDrawer = new TextDrawTarget(aBuilder, aResources, aSc, aManager, aItem, bounds);
   RefPtr<gfxContext> captureCtx = gfxContext::CreateOrNull(textDrawer);
   PaintTextToContext(aItem->Frame(), captureCtx, aItem->IsSubpixelAADisabled());
   textDrawer->TerminateShadows();
 
   return !textDrawer->HasUnsupportedFeatures();
 }
 
 class nsDisplayBullet final : public nsDisplayItem {
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -5083,17 +5083,17 @@ nsDisplayText::CreateWebRenderCommands(m
     return true;
   }
 
 
   auto appUnitsPerDevPixel = Frame()->PresContext()->AppUnitsPerDevPixel();
   gfx::Point deviceOffset = LayoutDevicePoint::FromAppUnits(
       mBounds.TopLeft(), appUnitsPerDevPixel).ToUnknownPoint();
 
-  RefPtr<TextDrawTarget> textDrawer = new TextDrawTarget(aBuilder, aSc, aManager, this, mBounds);
+  RefPtr<TextDrawTarget> textDrawer = new TextDrawTarget(aBuilder, aResources, aSc, aManager, this, mBounds);
   RefPtr<gfxContext> captureCtx = gfxContext::CreateOrNull(textDrawer, deviceOffset);
 
   RenderToContext(captureCtx, aDisplayListBuilder, true);
 
   return !textDrawer->HasUnsupportedFeatures();
 }
 
 void
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -1384,17 +1384,17 @@ random-if(/^Windows\x20NT\x206\.1/.test(
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 495385-3.html 495385-3-ref.html # Bug 1392106
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 495385-4.html 495385-4-ref.html # Bug 1392106
 == 496032-1.html 496032-1-ref.html
 == 496840-1.html 496840-1-ref.html
 == 501037.html 501037-ref.html
 == 501257-1a.html 501257-1-ref.html
 == 501257-1b.html 501257-1-ref.html
 == 501257-1.xhtml 501257-1-ref.xhtml
-fuzzy-if(webrender,5-6,83244-97456) == 501627-1.html 501627-1-ref.html
+fuzzy-if(webrender,2-6,39042-97456) == 501627-1.html 501627-1-ref.html # Bug 1481664
 == 502288-1.html 502288-1-ref.html
 fuzzy-if(gtkWidget,0-1,0-2) == 502447-1.html 502447-1-ref.html #Bug 1315834
 == 502795-1.html 502795-1-ref.html
 == 502942-1.html 502942-1-ref.html
 == 503364-1a.html 503364-1-ref.html
 == 503364-1b.html 503364-1-ref.html
 # Reftest for bug 503531 marked as failing; should be re-enabled when
 # bug 607548 gets resolved.
--- a/mobile/android/base/java/org/mozilla/gecko/customtabs/CustomTabsActivity.java
+++ b/mobile/android/base/java/org/mozilla/gecko/customtabs/CustomTabsActivity.java
@@ -146,28 +146,16 @@ public class CustomTabsActivity extends 
             finish();
         }
 
         sendTelemetry();
         recordCustomTabUsage(getReferrerHost());
     }
 
     @Override
-    public void onResume() {
-        mGeckoSession.setActive(true);
-        super.onResume();
-    }
-
-    @Override
-    public void onPause() {
-        mGeckoSession.setActive(false);
-        super.onPause();
-    }
-
-    @Override
     public void onDestroy() {
         mGeckoSession.close();
         mTextSelection.destroy();
         mFormAssistPopup.destroy();
         mDoorHangerPopup.destroy();
         mPromptService.destroy();
 
         super.onDestroy();
--- a/mobile/android/base/java/org/mozilla/gecko/webapps/WebAppActivity.java
+++ b/mobile/android/base/java/org/mozilla/gecko/webapps/WebAppActivity.java
@@ -192,28 +192,16 @@ public class WebAppActivity extends AppC
         if (android.os.Build.VERSION.SDK_INT >= 21) {
             finishAndRemoveTask();
         } else {
             finish();
         }
     }
 
     @Override
-    public void onResume() {
-        mGeckoSession.setActive(true);
-        super.onResume();
-    }
-
-    @Override
-    public void onPause() {
-        mGeckoSession.setActive(false);
-        super.onPause();
-    }
-
-    @Override
     public void onDestroy() {
         mGeckoSession.close();
         mTextSelection.destroy();
         mFormAssistPopup.destroy();
         mDoorHangerPopup.destroy();
         mPromptService.destroy();
         super.onDestroy();
     }
--- a/mobile/android/chrome/geckoview/GeckoViewContent.js
+++ b/mobile/android/chrome/geckoview/GeckoViewContent.js
@@ -2,21 +2,23 @@
 /* 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/. */
 
 ChromeUtils.import("resource://gre/modules/GeckoViewContentModule.jsm");
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetters(this, {
+  DeferredTask: "resource://gre/modules/DeferredTask.jsm",
+  FormData: "resource://gre/modules/FormData.jsm",
+  FormLikeFactory: "resource://gre/modules/FormLikeFactory.jsm",
+  PrivacyFilter: "resource://gre/modules/sessionstore/PrivacyFilter.jsm",
+  ScrollPosition: "resource://gre/modules/ScrollPosition.jsm",
   Services: "resource://gre/modules/Services.jsm",
   SessionHistory: "resource://gre/modules/sessionstore/SessionHistory.jsm",
-  FormData: "resource://gre/modules/FormData.jsm",
-  PrivacyFilter: "resource://gre/modules/sessionstore/PrivacyFilter.jsm",
-  ScrollPosition: "resource://gre/modules/ScrollPosition.jsm",
 });
 
 class GeckoViewContent extends GeckoViewContentModule {
   onInit() {
     debug `onInit`;
 
     // We don't load this in the global namespace because
     // a Utils.jsm in a11y will clobber us.
@@ -30,16 +32,27 @@ class GeckoViewContent extends GeckoView
                                            this);
     this.messageManager.addMessageListener("GeckoView:DOMFullscreenEntered",
                                            this);
     this.messageManager.addMessageListener("GeckoView:DOMFullscreenExited",
                                            this);
     this.messageManager.addMessageListener("GeckoView:ZoomToInput",
                                            this);
 
+    const options = {
+        mozSystemGroup: true,
+        capture: false,
+    };
+    addEventListener("DOMFormHasPassword", this, options);
+    addEventListener("DOMInputPasswordAdded", this, options);
+    addEventListener("pagehide", this, options);
+    addEventListener("pageshow", this, options);
+    addEventListener("focusin", this, options);
+    addEventListener("focusout", this, options);
+
     // Notify WebExtension process script that this tab is ready for extension content to load.
     Services.obs.notifyObservers(this.messageManager, "tab-content-frameloader-created");
   }
 
   onEnable() {
     debug `onEnable`;
 
     addEventListener("DOMTitleChanged", this, false);
@@ -174,18 +187,30 @@ class GeckoViewContent extends GeckoView
         break;
 
       case "GeckoView:RestoreState":
         this._savedState = JSON.parse(aMsg.data.state);
 
         if (this._savedState.history) {
           let restoredHistory = SessionHistory.restore(docShell, this._savedState.history);
 
-          addEventListener("load", this, {capture: true, mozSystemGroup: true, once: true});
-          addEventListener("pageshow", this, {capture: true, mozSystemGroup: true, once: true});
+          addEventListener("load", _ => {
+            const formdata = this._savedState.formdata;
+            if (formdata) {
+              FormData.restoreTree(content, formdata);
+            }
+          }, {capture: true, mozSystemGroup: true, once: true});
+
+          addEventListener("pageshow", _ => {
+            const scrolldata = this._savedState.scrolldata;
+            if (scrolldata) {
+              ScrollPosition.restoreTree(content, scrolldata);
+            }
+            delete this._savedState;
+          }, {capture: true, mozSystemGroup: true, once: true});
 
           if (!this.progressFilter) {
             this.progressFilter =
               Cc["@mozilla.org/appshell/component/browser-status-filter;1"]
               .createInstance(Ci.nsIWebProgress);
             this.flags = Ci.nsIWebProgress.NOTIFY_LOCATION;
           }
 
@@ -228,16 +253,27 @@ class GeckoViewContent extends GeckoView
             elementType,
             elementSrc: (isImage || isMedia)
                         ? node.currentSrc || node.src
                         : null
           });
           aEvent.preventDefault();
         }
         break;
+      case "DOMFormHasPassword":
+        this._addAutoFillElement(
+            FormLikeFactory.createFromForm(aEvent.composedTarget));
+        break;
+      case "DOMInputPasswordAdded": {
+        const input = aEvent.composedTarget;
+        if (!input.form) {
+          this._addAutoFillElement(FormLikeFactory.createFromField(input));
+        }
+        break;
+      }
       case "MozDOMFullscreen:Request":
         sendAsyncMessage("GeckoView:DOMFullscreenRequest");
         break;
       case "MozDOMFullscreen:Entered":
       case "MozDOMFullscreen:Exited":
         // Content may change fullscreen state by itself, and we should ensure
         // that the parent always exits fullscreen when content has left
         // full screen mode.
@@ -264,31 +300,36 @@ class GeckoViewContent extends GeckoView
           return;
         }
 
         aEvent.preventDefault();
         this.eventDispatcher.sendRequest({
           type: "GeckoView:DOMWindowClose"
         });
         break;
-      case "load": {
-        const formdata = this._savedState.formdata;
-        if (formdata) {
-          FormData.restoreTree(content, formdata);
+      case "focusin":
+        if (aEvent.composedTarget instanceof content.HTMLInputElement) {
+          this._onAutoFillFocus(aEvent.composedTarget);
+        }
+        break;
+      case "focusout":
+        if (aEvent.composedTarget instanceof content.HTMLInputElement) {
+          this._onAutoFillFocus(null);
         }
         break;
-      }
-      case "pageshow": {
-        const scrolldata = this._savedState.scrolldata;
-        if (scrolldata) {
-          ScrollPosition.restoreTree(content, scrolldata);
+      case "pagehide":
+        if (aEvent.target === content.document) {
+          this._clearAutoFillElements();
         }
-        delete this._savedState;
         break;
-      }
+      case "pageshow":
+        if (aEvent.target === content.document && aEvent.persisted) {
+          this._scanAutoFillDocument(aEvent.target);
+        }
+        break;
     }
   }
 
   // WebProgress event handler.
   onLocationChange(aWebProgress, aRequest, aLocationURI, aFlags) {
     debug `onLocationChange`;
 
     if (this._savedState) {
@@ -302,12 +343,206 @@ class GeckoViewContent extends GeckoView
       }
     }
 
     this.progressFilter.removeProgressListener(this);
     let webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
                               .getInterface(Ci.nsIWebProgress);
     webProgress.removeProgressListener(this.progressFilter);
   }
+
+  /**
+   * Process an auto-fillable form and send the relevant details of the form
+   * to Java. Multiple calls within a short time period for the same form are
+   * coalesced, so that, e.g., if multiple inputs are added to a form in
+   * succession, we will only perform one processing pass. Note that for inputs
+   * without forms, FormLikeFactory treats the document as the "form", but
+   * there is no difference in how we process them.
+   *
+   * @param aFormLike A FormLike object produced by FormLikeFactory.
+   * @param aFromDeferredTask Signal that this call came from our internal
+   *                          coalescing task. Other caller must not use this
+   *                          parameter.
+   */
+  _addAutoFillElement(aFormLike, aFromDeferredTask) {
+    let task = this._autoFillTasks &&
+               this._autoFillTasks.get(aFormLike.rootElement);
+    if (task && !aFromDeferredTask) {
+      // We already have a pending task; cancel that and start a new one.
+      debug `Canceling previous auto-fill task`;
+      task.disarm();
+      task = null;
+    }
+
+    if (!task) {
+      if (aFromDeferredTask) {
+        // Canceled before we could run the task.
+        debug `Auto-fill task canceled`;
+        return;
+      }
+      // Start a new task so we can coalesce adding elements in one batch.
+      debug `Deferring auto-fill task`;
+      task = new DeferredTask(
+          () => this._addAutoFillElement(aFormLike, true), 100);
+      task.arm();
+      if (!this._autoFillTasks) {
+        this._autoFillTasks = new WeakMap();
+      }
+      this._autoFillTasks.set(aFormLike.rootElement, task);
+      return;
+    }
+
+    debug `Adding auto-fill ${aFormLike}`;
+
+    this._autoFillTasks.delete(aFormLike.rootElement);
+    this._autoFillId = this._autoFillId || 0;
+
+    if (!this._autoFillInfos) {
+      this._autoFillInfos = new WeakMap();
+      this._autoFillElements = new Map();
+    }
+
+    let sendFocusEvent = false;
+    const getInfo = (element, parent) => {
+      let info = this._autoFillInfos.get(element);
+      if (info) {
+        return info;
+      }
+      info = {
+        id: ++this._autoFillId,
+        parent,
+        tag: element.tagName,
+        type: element instanceof content.HTMLInputElement ? element.type : null,
+        editable: (element instanceof content.HTMLInputElement) &&
+                  ["color", "date", "datetime-local", "email", "month",
+                   "number", "password", "range", "search", "tel", "text",
+                   "time", "url", "week"].includes(element.type),
+        disabled: element instanceof content.HTMLInputElement ? element.disabled
+                                                              : null,
+        attributes: Object.assign({}, ...Array.from(element.attributes)
+            .filter(attr => attr.localName !== "value")
+            .map(attr => ({[attr.localName]: attr.value}))),
+        origin: element.ownerDocument.location.origin,
+      };
+      this._autoFillInfos.set(element, info);
+      this._autoFillElements.set(info.id, Cu.getWeakReference(element));
+      sendFocusEvent |= (element === element.ownerDocument.activeElement);
+      return info;
+    };
+
+    const rootInfo = getInfo(aFormLike.rootElement, null);
+    rootInfo.children = aFormLike.elements.map(
+        element => getInfo(element, rootInfo.id));
+
+    this.eventDispatcher.dispatch("GeckoView:AddAutoFill", rootInfo, {
+      onSuccess: responses => {
+        // `responses` is an object with IDs as keys.
+        debug `Performing auto-fill ${responses}`;
+
+        const AUTOFILL_STATE = "-moz-autofill";
+        const winUtils = content.windowUtils;
+
+        for (let id in responses) {
+          const entry = this._autoFillElements &&
+                        this._autoFillElements.get(+id);
+          const element = entry && entry.get();
+          const value = responses[id] || "";
+
+          if (element instanceof content.HTMLInputElement &&
+              !element.disabled && element.parentElement) {
+            element.value = value;
+
+            // Fire both "input" and "change" events.
+            element.dispatchEvent(new element.ownerGlobal.Event(
+                "input", { bubbles: true }));
+            element.dispatchEvent(new element.ownerGlobal.Event(
+                "change", { bubbles: true }));
+
+            if (winUtils && element.value === value) {
+              // Add highlighting for autofilled fields.
+              winUtils.addManuallyManagedState(element, AUTOFILL_STATE);
+
+              // Remove highlighting when the field is changed.
+              element.addEventListener("input", _ =>
+                  winUtils.removeManuallyManagedState(element, AUTOFILL_STATE),
+                  { mozSystemGroup: true, once: true });
+            }
+
+          } else if (element) {
+            warn `Don't know how to auto-fill ${element.tagName}`;
+          }
+        }
+      },
+      onError: error => {
+        warn `Cannot perform autofill ${error}`;
+      },
+    });
+
+    if (sendFocusEvent) {
+      // We might have missed sending a focus event for the active element.
+      this._onAutoFillFocus(aFormLike.ownerDocument.activeElement);
+    }
+  }
+
+  /**
+   * Called when an auto-fillable field is focused or blurred.
+   *
+   * @param aTarget Focused element, or null if an element has lost focus.
+   */
+  _onAutoFillFocus(aTarget) {
+    debug `Auto-fill focus on ${aTarget && aTarget.tagName}`;
+
+    let info = aTarget && this._autoFillInfos &&
+               this._autoFillInfos.get(aTarget);
+    if (!aTarget || info) {
+      this.eventDispatcher.dispatch("GeckoView:OnAutoFillFocus", info);
+    }
+  }
+
+  /**
+   * Clear all tracked auto-fill forms and notify Java.
+   */
+  _clearAutoFillElements() {
+    debug `Clearing auto-fill`;
+
+    this._autoFillTasks = undefined;
+    this._autoFillInfos = undefined;
+    this._autoFillElements = undefined;
+
+    this.eventDispatcher.sendRequest({
+      type: "GeckoView:ClearAutoFill",
+    });
+  }
+
+  /**
+   * Scan for auto-fillable forms and add them if necessary. Called when a page
+   * is navigated to through history, in which case we don't get our typical
+   * "input added" notifications.
+   *
+   * @param aDoc Document to scan.
+   */
+  _scanAutoFillDocument(aDoc) {
+    // Add forms first; only check forms with password inputs.
+    const inputs = aDoc.querySelectorAll("input[type=password]");
+    let inputAdded = false;
+    for (let i = 0; i < inputs.length; i++) {
+      if (inputs[i].form) {
+        // Let _addAutoFillElement coalesce multiple calls for the same form.
+        this._addAutoFillElement(
+            FormLikeFactory.createFromForm(inputs[i].form));
+      } else if (!inputAdded) {
+        // Treat inputs without forms as one unit, and process them only once.
+        inputAdded = true;
+        this._addAutoFillElement(
+            FormLikeFactory.createFromField(inputs[i]));
+      }
+    }
+
+    // Finally add frames.
+    const frames = aDoc.defaultView.frames;
+    for (let i = 0; i < frames.length; i++) {
+      this._scanAutoFillDocument(frames[i].document);
+    }
+  }
 }
 
 let {debug, warn} = GeckoViewContent.initLogging("GeckoViewContent");
 let module = GeckoViewContent.create(this);
new file mode 100644
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/forms.html
@@ -0,0 +1,26 @@
+<html>
+    <head><title>Forms</title></head>
+    <body>
+        <form>
+            <input type="text" id="user1" value="foo">
+            <input type="password" id="pass1", value="foo">
+            <input type="email" id="email1", value="@">
+            <input type="number" id="number1", value="0">
+            <input type="tel" id="tel1", value="0">
+        </form>
+        <input type="Text" id="user2" value="foo">
+        <input type="PassWord" id="pass2" maxlength="8" value="foo">
+        <input type="button" id="button1" value="foo"/>
+        <input type="checkbox" id="checkbox1"/>
+        <input type="hidden" id="hidden1" value="foo"/>
+
+        <iframe id="iframe"></iframe>
+    </body>
+    <script>
+        addEventListener("load", function(e) {
+            if (window.parent === window) {
+                document.getElementById("iframe").contentWindow.location.href = window.location.href;
+            }
+        });
+    </script>
+</html>
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/AccessibilityTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/AccessibilityTest.kt
@@ -1,33 +1,37 @@
 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
  * Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 package org.mozilla.geckoview.test
 
 import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.AssertCalled
+import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.ReuseSession
 import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.WithDisplay
 import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.WithDevToolsAPI
 
 import android.graphics.Rect
 
 import android.os.Build
 import android.os.Bundle
 
 import android.support.test.filters.MediumTest
 import android.support.test.InstrumentationRegistry
 import android.support.test.runner.AndroidJUnit4
+import android.text.InputType
+import android.util.SparseLongArray
 
 import android.view.accessibility.AccessibilityNodeInfo
 import android.view.accessibility.AccessibilityNodeProvider
 import android.view.accessibility.AccessibilityEvent
 import android.view.accessibility.AccessibilityRecord
 import android.view.View
 import android.view.ViewGroup
+import android.widget.EditText
 
 import android.widget.FrameLayout
 
 import org.hamcrest.Matchers.*
 import org.junit.Test
 import org.junit.Before
 import org.junit.After
 import org.junit.runner.RunWith
@@ -61,16 +65,26 @@ class AccessibilityTest : BaseSessionTes
             val getSourceIdMethod =
                 AccessibilityRecord::class.java.getMethod("getSourceNodeId")
             return getVirtualDescendantId(getSourceIdMethod.invoke(event) as Long)
         } catch (ex: Exception) {
             return 0
         }
     }
 
+    // Get a child ID by index.
+    private fun AccessibilityNodeInfo.getChildId(index: Int): Int =
+            getVirtualDescendantId(
+                    if (Build.VERSION.SDK_INT >= 21)
+                        AccessibilityNodeInfo::class.java.getMethod(
+                                "getChildId", Int::class.java).invoke(this, index) as Long
+                    else
+                        (AccessibilityNodeInfo::class.java.getMethod("getChildNodeIds")
+                                .invoke(this) as SparseLongArray).get(index))
+
     private interface EventDelegate {
         fun onAccessibilityFocused(event: AccessibilityEvent) { }
         fun onClicked(event: AccessibilityEvent) { }
         fun onFocused(event: AccessibilityEvent) { }
         fun onSelected(event: AccessibilityEvent) { }
         fun onScrolled(event: AccessibilityEvent) { }
         fun onTextSelectionChanged(event: AccessibilityEvent) { }
         fun onTextChanged(event: AccessibilityEvent) { }
@@ -557,9 +571,161 @@ class AccessibilityTest : BaseSessionTes
 
             @AssertCalled(count = 1, order = [3])
             override fun onWinContentChanged(event: AccessibilityEvent) {
                 nodeId = getSourceId(event)
                 assertThat("Focused node is onscreen", screenContainsNode(nodeId), equalTo(true))
             }
         })
     }
+
+    @ReuseSession(false) // XXX automation crash fix (bug 1485107)
+    @WithDevToolsAPI
+    @Test fun autoFill() {
+        // Wait for the accessibility nodes to populate.
+        mainSession.loadTestPath(FORMS_HTML_PATH)
+        sessionRule.waitUntilCalled(object : EventDelegate {
+            // For the root document and the iframe document, each has a form group and
+            // a group for inputs outside of forms, so the total count is 4.
+            @AssertCalled(count = 4)
+            override fun onWinContentChanged(event: AccessibilityEvent) {
+            }
+        })
+
+        val autoFills = mapOf(
+                "#user1" to "bar", "#pass1" to "baz", "#user2" to "bar", "#pass2" to "baz") +
+                if (Build.VERSION.SDK_INT >= 19) mapOf(
+                        "#email1" to "a@b.c", "#number1" to "24", "#tel1" to "42")
+                else mapOf(
+                        "#email1" to "bar", "#number1" to "", "#tel1" to "bar")
+
+        // Set up promises to monitor the values changing.
+        val promises = autoFills.flatMap { entry ->
+            // Repeat each test with both the top document and the iframe document.
+            arrayOf("document", "$('#iframe').contentDocument").map { doc ->
+                mainSession.evaluateJS("""new Promise(resolve =>
+                    $doc.querySelector('${entry.key}').addEventListener(
+                        'input', event => resolve([event.target.value, '${entry.value}']),
+                        { once: true }))""").asJSPromise()
+            }
+        }
+
+        // Perform auto-fill and return number of auto-fills performed.
+        fun autoFillChild(id: Int, child: AccessibilityNodeInfo) {
+            // Seal the node info instance so we can perform actions on it.
+            if (child.childCount > 0) {
+                for (i in 0 until child.childCount) {
+                    val childId = child.getChildId(i)
+                    autoFillChild(childId, provider.createAccessibilityNodeInfo(childId))
+                }
+            }
+
+            if (EditText::class.java.name == child.className) {
+                assertThat("Input should be enabled", child.isEnabled, equalTo(true))
+                assertThat("Input should be focusable", child.isFocusable, equalTo(true))
+                if (Build.VERSION.SDK_INT >= 19) {
+                    assertThat("Password type should match", child.isPassword, equalTo(
+                            child.inputType == InputType.TYPE_CLASS_TEXT or
+                                    InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD))
+                }
+
+                val args = Bundle(1)
+                val value = if (child.isPassword) "baz" else
+                    if (Build.VERSION.SDK_INT < 19) "bar" else
+                        when (child.inputType) {
+                            InputType.TYPE_CLASS_TEXT or
+                                    InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS -> "a@b.c"
+                            InputType.TYPE_CLASS_NUMBER -> "24"
+                            InputType.TYPE_CLASS_PHONE -> "42"
+                            else -> "bar"
+                        }
+
+                val ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE = if (Build.VERSION.SDK_INT >= 21)
+                    AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE else
+                    "ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE"
+                val ACTION_SET_TEXT = if (Build.VERSION.SDK_INT >= 21)
+                    AccessibilityNodeInfo.ACTION_SET_TEXT else 0x200000
+
+                args.putCharSequence(ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, value)
+                assertThat("Can perform auto-fill",
+                           provider.performAction(id, ACTION_SET_TEXT, args), equalTo(true))
+            }
+            child.recycle()
+        }
+
+        autoFillChild(View.NO_ID, provider.createAccessibilityNodeInfo(View.NO_ID))
+
+        // Wait on the promises and check for correct values.
+        for ((actual, expected) in promises.map { it.value.asJSList<String>() }) {
+            assertThat("Auto-filled value must match", actual, equalTo(expected))
+        }
+    }
+
+    @ReuseSession(false) // XXX automation crash fix (bug 1485107)
+    @Test fun autoFill_navigation() {
+        fun countAutoFillNodes(cond: (AccessibilityNodeInfo) -> Boolean =
+                                       { it.className == "android.widget.EditText" },
+                               id: Int = View.NO_ID): Int {
+            val info = provider.createAccessibilityNodeInfo(id)
+            try {
+                return (if (cond(info)) 1 else 0) + (if (info.childCount > 0)
+                    (0 until info.childCount).sumBy {
+                        countAutoFillNodes(cond, info.getChildId(it))
+                    } else 0)
+            } finally {
+                info.recycle()
+            }
+        }
+
+        // Wait for the accessibility nodes to populate.
+        mainSession.loadTestPath(FORMS_HTML_PATH)
+        sessionRule.waitUntilCalled(object : EventDelegate {
+            @AssertCalled(count = 4)
+            override fun onWinContentChanged(event: AccessibilityEvent) {
+            }
+        })
+        assertThat("Initial auto-fill count should match",
+                   countAutoFillNodes(), equalTo(14))
+        assertThat("Password auto-fill count should match",
+                   countAutoFillNodes({ it.isPassword }), equalTo(4))
+
+        // Now wait for the nodes to clear.
+        mainSession.loadTestPath(HELLO_HTML_PATH)
+        mainSession.waitForPageStop()
+        assertThat("Should not have auto-fill fields",
+                   countAutoFillNodes(), equalTo(0))
+
+        // Now wait for the nodes to reappear.
+        mainSession.goBack()
+        sessionRule.waitUntilCalled(object : EventDelegate {
+            @AssertCalled(count = 4)
+            override fun onWinContentChanged(event: AccessibilityEvent) {
+            }
+        })
+        assertThat("Should have auto-fill fields again",
+                   countAutoFillNodes(), equalTo(14))
+        assertThat("Should not have focused field",
+                   countAutoFillNodes({ it.isFocused }), equalTo(0))
+
+        mainSession.evaluateJS("$('#pass1').focus()")
+        sessionRule.waitUntilCalled(object : EventDelegate {
+            @AssertCalled
+            override fun onFocused(event: AccessibilityEvent) {
+            }
+        })
+        assertThat("Should have one focused field",
+                   countAutoFillNodes({ it.isFocused }), equalTo(1))
+        // The focused field, its siblings, and its parent should be visible.
+        assertThat("Should have at least six visible fields",
+                   countAutoFillNodes({ node -> node.isVisibleToUser &&
+                           !(Rect().also({ node.getBoundsInScreen(it) }).isEmpty) }),
+                   greaterThanOrEqualTo(6))
+
+        mainSession.evaluateJS("$('#pass1').blur()")
+        sessionRule.waitUntilCalled(object : EventDelegate {
+            @AssertCalled
+            override fun onFocused(event: AccessibilityEvent) {
+            }
+        })
+        assertThat("Should not have focused field",
+                   countAutoFillNodes({ it.isFocused }), equalTo(0))
+    }
 }
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/BaseSessionTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/BaseSessionTest.kt
@@ -23,16 +23,17 @@ import kotlin.reflect.KClass
  * Common base class for tests using GeckoSessionTestRule,
  * providing the test rule and other utilities.
  */
 open class BaseSessionTest(noErrorCollector: Boolean = false) {
     companion object {
         const val CLICK_TO_RELOAD_HTML_PATH = "/assets/www/clickToReload.html"
         const val CONTENT_CRASH_URL = "about:crashcontent"
         const val DOWNLOAD_HTML_PATH = "/assets/www/download.html"
+        const val FORMS_HTML_PATH = "/assets/www/forms.html"
         const val HELLO_HTML_PATH = "/assets/www/hello.html"
         const val HELLO2_HTML_PATH = "/assets/www/hello2.html"
         const val INPUTS_PATH = "/assets/www/inputs.html"
         const val INVALID_URI = "http://www.test.invalid/"
         const val LOREM_IPSUM_HTML_PATH = "/assets/www/loremIpsum.html"
         const val NEW_SESSION_HTML_PATH = "/assets/www/newSession.html"
         const val NEW_SESSION_CHILD_HTML_PATH = "/assets/www/newSession_child.html"
         const val SAVE_STATE_PATH = "/assets/www/saveState.html"
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/util/Callbacks.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/util/Callbacks.kt
@@ -160,10 +160,13 @@ class Callbacks private constructor() {
         override fun updateSelection(session: GeckoSession, selStart: Int, selEnd: Int, compositionStart: Int, compositionEnd: Int) {
         }
 
         override fun updateExtractedText(session: GeckoSession, request: ExtractedTextRequest, text: ExtractedText) {
         }
 
         override fun updateCursorAnchorInfo(session: GeckoSession, info: CursorAnchorInfo) {
         }
+
+        override fun notifyAutoFill(session: GeckoSession, notification: Int, virtualId: Int) {
+        }
     }
 }
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java
@@ -1003,16 +1003,22 @@ public class GeckoSession extends LayerS
 
         onWindowChanged(WINDOW_CLOSE, /* inProgress */ false);
     }
 
     private void onWindowChanged(int change, boolean inProgress) {
         if ((change == WINDOW_OPEN || change == WINDOW_TRANSFER_IN) && !inProgress) {
             mTextInput.onWindowChanged(mWindow);
         }
+        if ((change == WINDOW_CLOSE || change == WINDOW_TRANSFER_OUT) && !inProgress) {
+            if (mAccessibility != null) {
+                mAccessibility.clearAutoFill();
+            }
+            mTextInput.clearAutoFill();
+        }
     }
 
     /**
      * Get the SessionTextInput instance for this session. May be called on any thread.
      *
      * @return SessionTextInput instance.
      */
     public @NonNull SessionTextInput getTextInput() {
@@ -1292,28 +1298,51 @@ public class GeckoSession extends LayerS
     public SessionFinder getFinder() {
         if (mFinder == null) {
             mFinder = new SessionFinder(getEventDispatcher());
         }
         return mFinder;
     }
 
     /**
-    * Set this GeckoSession as active or inactive. Setting a GeckoSession to inactive will
-    * significantly reduce its memory footprint, but should only be done if the
-    * GeckoSession is not currently visible.
-    * @param active A boolean determining whether the GeckoSession is active
-    */
+     * Set this GeckoSession as active or inactive, which represents if the session is currently
+     * visible or not. Setting a GeckoSession to inactive will significantly reduce its memory
+     * footprint, but should only be done if the GeckoSession is not currently visible. Note that
+     * a session can be active (i.e. visible) but not focused.
+     *
+     * @param active A boolean determining whether the GeckoSession is active.
+     *
+     * @see #setFocused
+     */
     public void setActive(boolean active) {
-        final GeckoBundle msg = new GeckoBundle();
+        final GeckoBundle msg = new GeckoBundle(1);
         msg.putBoolean("active", active);
         mEventDispatcher.dispatch("GeckoView:SetActive", msg);
     }
 
     /**
+     * Move focus to this session or away from this session. Only one session has focus at
+     * a given time. Note that a session can be unfocused but still active (i.e. visible).
+     *
+     * @param focused True if the session should gain focus or
+     *                false if the session should lose focus.
+     *
+     * @see #setActive
+     */
+    public void setFocused(boolean focused) {
+        final GeckoBundle msg = new GeckoBundle(1);
+        msg.putBoolean("focused", focused);
+        mEventDispatcher.dispatch("GeckoView:SetFocused", msg);
+
+        if (focused && mAccessibility != null) {
+            mAccessibility.onWindowFocus();
+        }
+    }
+
+    /**
      * Class representing a saved session state.
      */
     public static class SessionState implements Parcelable {
         private String mState;
 
         /**
          * Construct a SessionState from a String.
          *
@@ -3338,10 +3367,50 @@ public class GeckoSession extends LayerS
          * Update the cursor-anchor information as requested through
          * {@link android.view.inputmethod.InputConnection#requestCursorUpdates}.
          * Consequently, this method is <i>not</i> called in viewless mode.
          *
          * @param session Session instance.
          * @param info Cursor-anchor information.
          */
         void updateCursorAnchorInfo(@NonNull GeckoSession session, @NonNull CursorAnchorInfo info);
+
+        @Retention(RetentionPolicy.SOURCE)
+        @IntDef({AUTO_FILL_NOTIFY_STARTED, AUTO_FILL_NOTIFY_COMMITTED, AUTO_FILL_NOTIFY_CANCELED,
+                AUTO_FILL_NOTIFY_VIEW_ADDED, AUTO_FILL_NOTIFY_VIEW_REMOVED,
+                AUTO_FILL_NOTIFY_VIEW_UPDATED, AUTO_FILL_NOTIFY_VIEW_ENTERED,
+                AUTO_FILL_NOTIFY_VIEW_EXITED})
+        /* package */ @interface AutoFillNotification {}
+
+        /** An auto-fill session has started, usually as a result of loading a page. */
+        int AUTO_FILL_NOTIFY_STARTED = 0;
+        /** An auto-fill session has been committed, usually as a result of submitting a form. */
+        int AUTO_FILL_NOTIFY_COMMITTED = 1;
+        /** An auto-fill session has been canceled, usually as a result of unloading a page. */
+        int AUTO_FILL_NOTIFY_CANCELED = 2;
+        /** A view within the auto-fill session has been added. */
+        int AUTO_FILL_NOTIFY_VIEW_ADDED = 3;
+        /** A view within the auto-fill session has been removed. */
+        int AUTO_FILL_NOTIFY_VIEW_REMOVED = 4;
+        /** A view within the auto-fill session has been updated (e.g. change in state). */
+        int AUTO_FILL_NOTIFY_VIEW_UPDATED = 5;
+        /** A view within the auto-fill session has gained focus. */
+        int AUTO_FILL_NOTIFY_VIEW_ENTERED = 6;
+        /** A view within the auto-fill session has lost focus. */
+        int AUTO_FILL_NOTIFY_VIEW_EXITED = 7;
+
+        /**
+         * Notify that an auto-fill event has occurred. The default implementation forwards the
+         * notification to the system {@link android.view.autofill.AutofillManager}. This method is
+         * only called on Android 6.0 and above, and it is called in viewless mode as well.
+         *
+         * @param session Session instance.
+         * @param notification Notification type as one of the {@link #AUTO_FILL_NOTIFY_STARTED
+         *                     AUTO_FILL_NOTIFY_*} constants.
+         * @param virtualId Virtual ID of the target, or {@link android.view.View#NO_ID} if not
+         *                  applicable. The ID matches one of the virtual IDs provided by {@link
+         *                  SessionTextInput#onProvideAutofillVirtualStructure} and can be used
+         *                  with {@link SessionTextInput#autofill}.
+         */
+        void notifyAutoFill(@NonNull GeckoSession session, @AutoFillNotification int notification,
+                            int virtualId);
     }
 }
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoView.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoView.java
@@ -9,38 +9,42 @@ package org.mozilla.geckoview;
 import org.mozilla.gecko.AndroidGamepadManager;
 import org.mozilla.gecko.EventDispatcher;
 import org.mozilla.gecko.gfx.DynamicToolbarAnimator;
 import org.mozilla.gecko.gfx.PanZoomController;
 import org.mozilla.gecko.gfx.GeckoDisplay;
 import org.mozilla.gecko.InputMethods;
 import org.mozilla.gecko.util.ActivityUtils;
 
+import android.annotation.TargetApi;
 import android.app.Activity;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.os.Build;
 import android.os.Handler;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.support.annotation.Nullable;
 import android.support.annotation.NonNull;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
+import android.util.SparseArray;
 import android.util.TypedValue;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewStructure;
+import android.view.autofill.AutofillValue;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputConnection;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.FrameLayout;
 
 public class GeckoView extends FrameLayout {
     private static final String LOGTAG = "GeckoView";
     private static final boolean DEBUG = false;
@@ -103,21 +107,23 @@ public class GeckoView extends FrameLayo
 
             // Tell display there is already a surface.
             onGlobalLayout();
             if (GeckoView.this.mSurfaceView != null) {
                 final SurfaceHolder holder = GeckoView.this.mSurfaceView.getHolder();
                 final Rect frame = holder.getSurfaceFrame();
                 mDisplay.surfaceChanged(holder.getSurface(), frame.right, frame.bottom);
             }
+            GeckoView.this.setActive(true);
         }
 
         public GeckoDisplay release() {
             if (mValid) {
                 mDisplay.surfaceDestroyed();
+                GeckoView.this.setActive(false);
             }
 
             final GeckoDisplay display = mDisplay;
             mDisplay = null;
             return display;
         }
 
         @Override // SurfaceHolder.Callback
@@ -125,24 +131,26 @@ public class GeckoView extends FrameLayo
         }
 
         @Override // SurfaceHolder.Callback
         public void surfaceChanged(final SurfaceHolder holder, final int format,
                                    final int width, final int height) {
             if (mDisplay != null) {
                 mDisplay.surfaceChanged(holder.getSurface(), width, height);
             }
+            GeckoView.this.setActive(true);
             mValid = true;
         }
 
         @Override // SurfaceHolder.Callback
         public void surfaceDestroyed(final SurfaceHolder holder) {
             if (mDisplay != null) {
                 mDisplay.surfaceDestroyed();
             }
+            GeckoView.this.setActive(false);
             mValid = false;
         }
 
         public void onGlobalLayout() {
             if (mDisplay == null) {
                 return;
             }
             if (GeckoView.this.mSurfaceView != null) {
@@ -198,16 +206,22 @@ public class GeckoView extends FrameLayo
      * @param color Cover color.
      */
     public void coverUntilFirstPaint(final int color) {
         if (mSurfaceView != null) {
             mSurfaceView.setBackgroundColor(color);
         }
     }
 
+    /* package */ void setActive(final boolean active) {
+        if (mSession != null) {
+            mSession.setActive(active);
+        }
+    }
+
     public GeckoSession releaseSession() {
         if (mSession == null) {
             return null;
         }
 
         // Cover the view while we are not drawing to the surface.
         coverUntilFirstPaint(Color.WHITE);
 
@@ -219,20 +233,23 @@ public class GeckoView extends FrameLayo
         if (mSession.getAccessibility().getView() == this) {
             mSession.getAccessibility().setView(null);
         }
 
         if (mSession.getTextInput().getView() == this) {
             mSession.getTextInput().setView(null);
         }
 
-        if (session.getSelectionActionDelegate() == mSelectionActionDelegate) {
+        if (mSession.getSelectionActionDelegate() == mSelectionActionDelegate) {
             mSession.setSelectionActionDelegate(null);
         }
 
+        if (isFocused()) {
+            mSession.setFocused(false);
+        }
         mSession = null;
         return session;
     }
 
     /**
      * Attach a session to this view. The session should be opened before
      * attaching.
      *
@@ -310,16 +327,20 @@ public class GeckoView extends FrameLayo
 
         if (session.getAccessibility().getView() == null) {
             session.getAccessibility().setView(this);
         }
 
         if (session.getSelectionActionDelegate() == null && mSelectionActionDelegate != null) {
             session.setSelectionActionDelegate(mSelectionActionDelegate);
         }
+
+        if (isFocused()) {
+            session.setFocused(true);
+        }
     }
 
     public GeckoSession getSession() {
         return mSession;
     }
 
     public EventDispatcher getEventDispatcher() {
         return mSession.getEventDispatcher();
@@ -411,20 +432,37 @@ public class GeckoView extends FrameLayo
             setSession(ss.session, ss.session.getRuntime());
         } else if (ss.session != null) {
             mSession.transferFrom(ss.session);
             mRuntime = mSession.getRuntime();
         }
     }
 
     @Override
+    public void onWindowFocusChanged(boolean hasWindowFocus) {
+        super.onWindowFocusChanged(hasWindowFocus);
+
+        if (mSession != null) {
+            mSession.setFocused(hasWindowFocus && isFocused());
+        }
+    }
+
+    @Override
     public void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) {
         super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
 
-        if (!gainFocus || mIsResettingFocus) {
+        if (mIsResettingFocus) {
+            return;
+        }
+
+        if (mSession != null) {
+            mSession.setFocused(gainFocus);
+        }
+
+        if (!gainFocus) {
             return;
         }
 
         post(new Runnable() {
             @Override
             public void run() {
                 if (!isFocused()) {
                     return;
@@ -547,9 +585,37 @@ public class GeckoView extends FrameLayo
 
         if (mSession == null) {
             return false;
         }
 
         return mSession.getAccessibility().onMotionEvent(event) ||
                mSession.getPanZoomController().onMotionEvent(event);
     }
+
+    @Override
+    public void onProvideAutofillVirtualStructure(final ViewStructure structure, int flags) {
+        super.onProvideAutofillVirtualStructure(structure, flags);
+
+        if (mSession != null) {
+            mSession.getTextInput().onProvideAutofillVirtualStructure(structure, flags);
+        }
+    }
+
+    @Override
+    @TargetApi(26)
+    public void autofill(@NonNull final SparseArray<AutofillValue> values) {
+        super.autofill(values);
+
+        if (mSession == null) {
+            return;
+        }
+        final SparseArray<CharSequence> strValues = new SparseArray<>(values.size());
+        for (int i = 0; i < values.size(); i++) {
+            final AutofillValue value = values.valueAt(i);
+            if (value.isText()) {
+                // Only text is currently supported.
+                strValues.put(values.keyAt(i), value.getTextValue());
+            }
+        }
+        mSession.getTextInput().autofill(strValues);
+    }
 }
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/SessionAccessibility.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/SessionAccessibility.java
@@ -12,56 +12,265 @@ import org.mozilla.gecko.util.BundleEven
 import org.mozilla.gecko.util.EventCallback;
 import org.mozilla.gecko.util.GeckoBundle;
 
 import android.content.Context;
 import android.graphics.Matrix;
 import android.graphics.Rect;
 import android.os.Build;
 import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.text.InputType;
 import android.util.Log;
+import android.util.SparseArray;
 import android.view.InputDevice;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewParent;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.accessibility.AccessibilityNodeProvider;
 
 public class SessionAccessibility {
     private static final String LOGTAG = "GeckoAccessibility";
-    // This is a special ID we use for nodes that are eent sources.
+    private static final boolean DEBUG = false;
+
+    // This is a special ID we use for nodes that are event sources.
     // We expose it as a fragment and not an actual child of the View node.
     private static final int VIRTUAL_CONTENT_ID = -2;
 
     // This is the number BrailleBack uses to start indexing routing keys.
     private static final int BRAILLE_CLICK_BASE_INDEX = -275000000;
 
+    private static final int ACTION_SET_TEXT = 0x200000;
+    private static final String ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE =
+            "ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE";
+
+    /* package */ final class NodeProvider extends AccessibilityNodeProvider {
+        @Override
+        public AccessibilityNodeInfo createAccessibilityNodeInfo(int virtualDescendantId) {
+            AccessibilityNodeInfo info = getAutoFillNode(virtualDescendantId);
+            if (info != null) {
+                // Try auto-fill nodes first.
+                return info;
+            }
+
+            info = (virtualDescendantId == VIRTUAL_CONTENT_ID && mVirtualContentNode != null)
+                   ? AccessibilityNodeInfo.obtain(mVirtualContentNode)
+                   : AccessibilityNodeInfo.obtain(mView, virtualDescendantId);
+
+            switch (virtualDescendantId) {
+            case View.NO_ID:
+                // This is the parent View node.
+                // We intentionally don't add VIRTUAL_CONTENT_ID
+                // as a child. It is a source for events,
+                // but not a member of the tree you
+                // can get to by traversing down.
+                if (Build.VERSION.SDK_INT < 17 || mView.getDisplay() != null) {
+                    // When running junit tests we don't have a display
+                    mView.onInitializeAccessibilityNodeInfo(info);
+                }
+                info.setPackageName(GeckoAppShell.getApplicationContext().getPackageName());
+                info.setClassName("android.webkit.WebView"); // TODO: WTF
+
+                if (Build.VERSION.SDK_INT >= 19) {
+                    Bundle bundle = info.getExtras();
+                    bundle.putCharSequence(
+                        "ACTION_ARGUMENT_HTML_ELEMENT_STRING_VALUES",
+                        "ARTICLE,BUTTON,CHECKBOX,COMBOBOX,CONTROL," +
+                        "FOCUSABLE,FRAME,GRAPHIC,H1,H2,H3,H4,H5,H6," +
+                        "HEADING,LANDMARK,LINK,LIST,LIST_ITEM,MAIN," +
+                        "MEDIA,RADIO,SECTION,TABLE,TEXT_FIELD," +
+                        "UNVISITED_LINK,VISITED_LINK");
+                }
+                info.addAction(AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT);
+
+                if (mAutoFillRoots != null) {
+                    // Add auto-fill nodes.
+                    if (DEBUG) {
+                        Log.d(LOGTAG, "Adding roots " + mAutoFillRoots);
+                    }
+                    for (int i = 0; i < mAutoFillRoots.size(); i++) {
+                        info.addChild(mView, mAutoFillRoots.keyAt(i));
+                    }
+                }
+                break;
+            default:
+                info.setParent(mView);
+                info.setSource(mView, virtualDescendantId);
+                info.setVisibleToUser(mView.isShown());
+                info.setPackageName(GeckoAppShell.getApplicationContext().getPackageName());
+                info.setEnabled(true);
+                info.addAction(AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY);
+                info.addAction(AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY);
+                info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
+                info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
+                info.addAction(AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT);
+                info.addAction(AccessibilityNodeInfo.ACTION_PREVIOUS_HTML_ELEMENT);
+                info.setMovementGranularities(AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER |
+                                              AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD |
+                                              AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
+                break;
+            }
+            return info;
+        }
+
+        @Override
+        public boolean performAction(int virtualViewId, int action, Bundle arguments) {
+            if (virtualViewId == View.NO_ID) {
+                return performRootAction(action, arguments);
+            }
+            if (action == AccessibilityNodeInfo.ACTION_SET_TEXT) {
+                final String value = arguments.getString(Build.VERSION.SDK_INT >= 21
+                        ? AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE
+                        : ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE);
+                return performAutoFill(virtualViewId, value);
+            }
+            return performContentAction(action, arguments);
+        }
+
+        private boolean performRootAction(int action, Bundle arguments) {
+            switch (action) {
+            case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS:
+            case AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS:
+                final GeckoBundle data = new GeckoBundle(1);
+                data.putBoolean("gainFocus", action == AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS);
+                mSession.getEventDispatcher().dispatch("GeckoView:AccessibilityViewFocused", data);
+                return true;
+            }
+
+            return mView.performAccessibilityAction(action, arguments);
+        }
+
+        @SuppressWarnings("fallthrough")
+        private boolean performContentAction(int action, Bundle arguments) {
+            final GeckoBundle data;
+            switch (action) {
+            case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS:
+                final AccessibilityEvent event = obtainEvent(AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED, VIRTUAL_CONTENT_ID);
+                ((ViewParent) mView).requestSendAccessibilityEvent(mView, event);
+                return true;
+            case AccessibilityNodeInfo.ACTION_CLICK:
+                mSession.getEventDispatcher().dispatch("GeckoView:AccessibilityActivate", null);
+                return true;
+            case AccessibilityNodeInfo.ACTION_LONG_CLICK:
+                mSession.getEventDispatcher().dispatch("GeckoView:AccessibilityLongPress", null);
+                return true;
+            case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD:
+                mSession.getEventDispatcher().dispatch("GeckoView:AccessibilityScrollForward", null);
+                return true;
+            case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD:
+                mSession.getEventDispatcher().dispatch("GeckoView:AccessibilityScrollBackward", null);
+                return true;
+            case AccessibilityNodeInfo.ACTION_SELECT:
+                mSession.getEventDispatcher().dispatch("GeckoView:AccessibilitySelect", null);
+                return true;
+            case AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT:
+                if (mLastItem) {
+                    return false;
+                }
+                // fall-through
+            case AccessibilityNodeInfo.ACTION_PREVIOUS_HTML_ELEMENT:
+                if (arguments != null) {
+                    data = new GeckoBundle(1);
+                    data.putString("rule", arguments.getString(AccessibilityNodeInfo.ACTION_ARGUMENT_HTML_ELEMENT_STRING));
+                } else {
+                    data = null;
+                }
+                mSession.getEventDispatcher().dispatch(action == AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT ?
+                                                       "GeckoView:AccessibilityNext" : "GeckoView:AccessibilityPrevious", data);
+                return true;
+            case AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY:
+            case AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY:
+                // XXX: Self brailling gives this action with a bogus argument instead of an actual click action;
+                // the argument value is the BRAILLE_CLICK_BASE_INDEX - the index of the routing key that was hit.
+                // Other negative values are used by ChromeVox, but we don't support them.
+                // FAKE_GRANULARITY_READ_CURRENT = -1
+                // FAKE_GRANULARITY_READ_TITLE = -2
+                // FAKE_GRANULARITY_STOP_SPEECH = -3
+                // FAKE_GRANULARITY_CHANGE_SHIFTER = -4
+                int granularity = arguments.getInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT);
+                if (granularity <= BRAILLE_CLICK_BASE_INDEX) {
+                    int keyIndex = BRAILLE_CLICK_BASE_INDEX - granularity;
+                    data = new GeckoBundle(1);
+                    data.putInt("keyIndex", keyIndex);
+                    mSession.getEventDispatcher().dispatch("GeckoView:AccessibilityActivate", data);
+                } else if (granularity > 0) {
+                    boolean extendSelection = arguments.getBoolean(AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN);
+                    data = new GeckoBundle(3);
+                    data.putString("direction", action == AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY ? "Next" : "Previous");
+                    data.putInt("granularity", granularity);
+                    data.putBoolean("select", extendSelection);
+                    mSession.getEventDispatcher().dispatch("GeckoView:AccessibilityByGranularity", data);
+                }
+                return true;
+            case AccessibilityNodeInfo.ACTION_SET_SELECTION:
+                if (arguments == null) {
+                    return false;
+                }
+                int selectionStart = arguments.getInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT);
+                int selectionEnd = arguments.getInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT);
+                data = new GeckoBundle(2);
+                data.putInt("start", selectionStart);
+                data.putInt("end", selectionEnd);
+                mSession.getEventDispatcher().dispatch("GeckoView:AccessibilitySetSelection", data);
+                return true;
+            case AccessibilityNodeInfo.ACTION_CUT:
+            case AccessibilityNodeInfo.ACTION_COPY:
+            case AccessibilityNodeInfo.ACTION_PASTE:
+                data = new GeckoBundle(1);
+                data.putInt("action", action);
+                mSession.getEventDispatcher().dispatch("GeckoView:AccessibilityClipboard", data);
+                return true;
+            }
+
+            return mView.performAccessibilityAction(action, arguments);
+        }
+    };
+
     // Gecko session we are proxying
     /* package */  final GeckoSession mSession;
     // This is the view that delegates accessibility to us. We also sends event through it.
     private View mView;
-    // Aave we reached the last item in content?
+    // Have we reached the last item in content?
     private boolean mLastItem;
     // Used to store the JSON message and populate the event later in the code path.
     private AccessibilityNodeInfo mVirtualContentNode;
+    // Auto-fill nodes.
+    private SparseArray<GeckoBundle> mAutoFillNodes;
+    private SparseArray<EventCallback> mAutoFillRoots;
+    private int mAutoFillFocusedId = View.NO_ID;
 
     /* package */ SessionAccessibility(final GeckoSession session) {
         mSession = session;
 
-        Settings.getInstance().dispatch();
+        Settings.updateAccessibilitySettings();
 
         session.getEventDispatcher().registerUiThreadListener(new BundleEventListener() {
-            @Override
-            public void handleMessage(final String event, final GeckoBundle message,
-                                      final EventCallback callback) {
-                sendAccessibilityEvent(message);
-            }
-        }, "GeckoView:AccessibilityEvent", null);
+                @Override
+                public void handleMessage(final String event, final GeckoBundle message,
+                                          final EventCallback callback) {
+                    if ("GeckoView:AccessibilityEvent".equals(event)) {
+                        sendAccessibilityEvent(message);
+                    } else if ("GeckoView:AddAutoFill".equals(event)) {
+                        addAutoFill(message, callback);
+                    } else if ("GeckoView:ClearAutoFill".equals(event)) {
+                        clearAutoFill();
+                    } else if ("GeckoView:OnAutoFillFocus".equals(event)) {
+                        onAutoFillFocus(message);
+                    }
+                }
+            },
+            "GeckoView:AccessibilityEvent",
+            "GeckoView:AddAutoFill",
+            "GeckoView:ClearAutoFill",
+            "GeckoView:OnAutoFillFocus",
+            null);
     }
 
     /**
       * Get the View instance that delegates accessibility to this session.
       *
       * @return View instance.
       */
     public View getView() {
@@ -81,212 +290,43 @@ public class SessionAccessibility {
         mView = view;
         mLastItem = false;
 
         if (mView == null) {
             return;
         }
 
         mView.setAccessibilityDelegate(new View.AccessibilityDelegate() {
-            private AccessibilityNodeProvider mAccessibilityNodeProvider;
+            private NodeProvider mProvider;
 
             @Override
             public AccessibilityNodeProvider getAccessibilityNodeProvider(final View hostView) {
-
-                if (mAccessibilityNodeProvider == null)
-                    mAccessibilityNodeProvider = new AccessibilityNodeProvider() {
-                    @Override
-                    public AccessibilityNodeInfo createAccessibilityNodeInfo(int virtualDescendantId) {
-                        assertAttachedView(hostView);
-
-                        AccessibilityNodeInfo info = (virtualDescendantId == VIRTUAL_CONTENT_ID && mVirtualContentNode != null) ?
-                                                     AccessibilityNodeInfo.obtain(mVirtualContentNode) :
-                                                     AccessibilityNodeInfo.obtain(mView, virtualDescendantId);
-
-                        switch (virtualDescendantId) {
-                        case View.NO_ID:
-                            // This is the parent View node.
-                            // We intentionally don't add VIRTUAL_CONTENT_ID
-                            // as a child. It is a source for events,
-                            // but not a member of the tree you
-                            // can get to by traversing down.
-                            if (mView.getDisplay() != null) {
-                                // When running junit tests we don't have a display
-                                onInitializeAccessibilityNodeInfo(mView, info);
-                            }
-                            info.setClassName("android.webkit.WebView"); // TODO: WTF
-                            if (Build.VERSION.SDK_INT >= 19) {
-                                Bundle bundle = info.getExtras();
-                                bundle.putCharSequence(
-                                    "ACTION_ARGUMENT_HTML_ELEMENT_STRING_VALUES",
-                                    "ARTICLE,BUTTON,CHECKBOX,COMBOBOX,CONTROL," +
-                                    "FOCUSABLE,FRAME,GRAPHIC,H1,H2,H3,H4,H5,H6," +
-                                    "HEADING,LANDMARK,LINK,LIST,LIST_ITEM,MAIN," +
-                                    "MEDIA,RADIO,SECTION,TABLE,TEXT_FIELD," +
-                                    "UNVISITED_LINK,VISITED_LINK");
-                            }
-                            info.addAction(AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT);
-                            info.addChild(hostView, VIRTUAL_CONTENT_ID);
-                            break;
-                        default:
-                            info.setParent(mView);
-                            info.setSource(mView, virtualDescendantId);
-                            info.setVisibleToUser(mView.isShown());
-                            info.setPackageName(GeckoAppShell.getApplicationContext().getPackageName());
-                            info.setEnabled(true);
-                            info.addAction(AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY);
-                            info.addAction(AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY);
-                            info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
-                            info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
-                            info.addAction(AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT);
-                            info.addAction(AccessibilityNodeInfo.ACTION_PREVIOUS_HTML_ELEMENT);
-                            info.setMovementGranularities(AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER |
-                                                          AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD |
-                                                          AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
-                            break;
-                        }
-                        return info;
-                    }
-
-                    @Override
-                    public boolean performAction(int virtualViewId, int action, Bundle arguments) {
-                        assertAttachedView(hostView);
-
-                        if (virtualViewId == View.NO_ID) {
-                            return performRootAction(action, arguments);
-                        }
-                        return performContentAction(action, arguments);
-                    }
-
-                    private boolean performRootAction(int action, Bundle arguments) {
-                        switch (action) {
-                        case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS:
-                        case AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS:
-                            final GeckoBundle data = new GeckoBundle(1);
-                            data.putBoolean("gainFocus", action == AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS);
-                            mSession.getEventDispatcher().dispatch("GeckoView:AccessibilityViewFocused", data);
-                            return true;
-                        }
-
-                        return mView.performAccessibilityAction(action, arguments);
-                    }
-
-                    @SuppressWarnings("fallthrough")
-                    private boolean performContentAction(int action, Bundle arguments) {
-                        final GeckoBundle data;
-                        switch (action) {
-                        case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS:
-                            final AccessibilityEvent event = obtainEvent(AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED, VIRTUAL_CONTENT_ID);
-                            ((ViewParent) mView).requestSendAccessibilityEvent(mView, event);
-                            return true;
-                        case AccessibilityNodeInfo.ACTION_CLICK:
-                            mSession.getEventDispatcher().dispatch("GeckoView:AccessibilityActivate", null);
-                            return true;
-                        case AccessibilityNodeInfo.ACTION_LONG_CLICK:
-                            mSession.getEventDispatcher().dispatch("GeckoView:AccessibilityLongPress", null);
-                            return true;
-                        case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD:
-                            mSession.getEventDispatcher().dispatch("GeckoView:AccessibilityScrollForward", null);
-                            return true;
-                        case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD:
-                            mSession.getEventDispatcher().dispatch("GeckoView:AccessibilityScrollBackward", null);
-                            return true;
-                        case AccessibilityNodeInfo.ACTION_SELECT:
-                            mSession.getEventDispatcher().dispatch("GeckoView:AccessibilitySelect", null);
-                            return true;
-                        case AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT:
-                            if (mLastItem) {
-                                return false;
-                            }
-                            // fall-through
-                        case AccessibilityNodeInfo.ACTION_PREVIOUS_HTML_ELEMENT:
-                            if (arguments != null) {
-                                data = new GeckoBundle(1);
-                                data.putString("rule", arguments.getString(AccessibilityNodeInfo.ACTION_ARGUMENT_HTML_ELEMENT_STRING));
-                            } else {
-                                data = null;
-                            }
-                            mSession.getEventDispatcher().dispatch(action == AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT ?
-                                                                   "GeckoView:AccessibilityNext" : "GeckoView:AccessibilityPrevious", data);
-                            return true;
-                        case AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY:
-                        case AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY:
-                            // XXX: Self brailling gives this action with a bogus argument instead of an actual click action;
-                            // the argument value is the BRAILLE_CLICK_BASE_INDEX - the index of the routing key that was hit.
-                            // Other negative values are used by ChromeVox, but we don't support them.
-                            // FAKE_GRANULARITY_READ_CURRENT = -1
-                            // FAKE_GRANULARITY_READ_TITLE = -2
-                            // FAKE_GRANULARITY_STOP_SPEECH = -3
-                            // FAKE_GRANULARITY_CHANGE_SHIFTER = -4
-                            int granularity = arguments.getInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT);
-                            if (granularity <= BRAILLE_CLICK_BASE_INDEX) {
-                                int keyIndex = BRAILLE_CLICK_BASE_INDEX - granularity;
-                                data = new GeckoBundle(1);
-                                data.putInt("keyIndex", keyIndex);
-                                mSession.getEventDispatcher().dispatch("GeckoView:AccessibilityActivate", data);
-                            } else if (granularity > 0) {
-                                boolean extendSelection = arguments.getBoolean(AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN);
-                                data = new GeckoBundle(3);
-                                data.putString("direction", action == AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY ? "Next" : "Previous");
-                                data.putInt("granularity", granularity);
-                                data.putBoolean("select", extendSelection);
-                                mSession.getEventDispatcher().dispatch("GeckoView:AccessibilityByGranularity", data);
-                            }
-                            return true;
-                        case AccessibilityNodeInfo.ACTION_SET_SELECTION:
-                            if (arguments == null) {
-                                return false;
-                            }
-                            int selectionStart = arguments.getInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT);
-                            int selectionEnd = arguments.getInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT);
-                            data = new GeckoBundle(2);
-                            data.putInt("start", selectionStart);
-                            data.putInt("end", selectionEnd);
-                            mSession.getEventDispatcher().dispatch("GeckoView:AccessibilitySetSelection", data);
-                            return true;
-                        case AccessibilityNodeInfo.ACTION_CUT:
-                        case AccessibilityNodeInfo.ACTION_COPY:
-                        case AccessibilityNodeInfo.ACTION_PASTE:
-                            data = new GeckoBundle(1);
-                            data.putInt("action", action);
-                            mSession.getEventDispatcher().dispatch("GeckoView:AccessibilityClipboard", data);
-                            return true;
-                        }
-
-                        return mView.performAccessibilityAction(action, arguments);
-                    }
-
-                    private void assertAttachedView(final View view) {
-                        if (view != mView) {
-                            throw new AssertionError("delegate used with wrong view.");
-                        }
-                    }
-                };
-
-                return mAccessibilityNodeProvider;
+                if (hostView != mView) {
+                    return null;
+                }
+                if (mProvider == null) {
+                    mProvider = new NodeProvider();
+                }
+                return mProvider;
             }
-
         });
     }
 
     private static class Settings {
-        private static final Settings INSTANCE = new Settings();
         private static final String FORCE_ACCESSIBILITY_PREF = "accessibility.force_disabled";
 
-        private volatile boolean mEnabled;
-        /* package */ volatile boolean mForceEnabled;
+        private static volatile boolean sEnabled;
+        private static volatile boolean sTouchExplorationEnabled;
+        /* package */ static volatile boolean sForceEnabled;
 
-        public Settings() {
+        static {
             final Context context = GeckoAppShell.getApplicationContext();
             AccessibilityManager accessibilityManager =
                 (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
 
-            mEnabled = accessibilityManager.isEnabled() &&
-                       accessibilityManager.isTouchExplorationEnabled();
-
             accessibilityManager.addAccessibilityStateChangeListener(
             new AccessibilityManager.AccessibilityStateChangeListener() {
                 @Override
                 public void onAccessibilityStateChanged(boolean enabled) {
                     updateAccessibilitySettings();
                 }
             }
             );
@@ -301,43 +341,43 @@ public class SessionAccessibility {
                 }
                 );
             }
 
             PrefsHelper.PrefHandler prefHandler = new PrefsHelper.PrefHandlerBase() {
                 @Override
                 public void prefValue(String pref, int value) {
                     if (pref.equals(FORCE_ACCESSIBILITY_PREF)) {
-                        mForceEnabled = value < 0;
+                        sForceEnabled = value < 0;
                         dispatch();
                     }
                 }
             };
             PrefsHelper.addObserver(new String[]{ FORCE_ACCESSIBILITY_PREF }, prefHandler);
         }
 
-        public static Settings getInstance() {
-            return INSTANCE;
+        public static boolean isEnabled() {
+            return sEnabled || sForceEnabled;
         }
 
-        public static boolean isEnabled() {
-            return INSTANCE.mEnabled || INSTANCE.mForceEnabled;
+        public static boolean isTouchExplorationEnabled() {
+            return sTouchExplorationEnabled || sForceEnabled;
         }
 
-        private void updateAccessibilitySettings() {
+        public static void updateAccessibilitySettings() {
             final AccessibilityManager accessibilityManager = (AccessibilityManager)
                     GeckoAppShell.getApplicationContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
-            mEnabled = accessibilityManager.isEnabled() && accessibilityManager.isTouchExplorationEnabled();
-
+            sEnabled = accessibilityManager.isEnabled();
+            sTouchExplorationEnabled = sEnabled && accessibilityManager.isTouchExplorationEnabled();
             dispatch();
         }
 
-        private void dispatch() {
+        /* package */ static void dispatch() {
             final GeckoBundle ret = new GeckoBundle(1);
-            ret.putBoolean("enabled", mEnabled || mForceEnabled);
+            ret.putBoolean("enabled", isTouchExplorationEnabled());
             // "GeckoView:AccessibilitySettings" is dispatched to the Gecko thread.
             EventDispatcher.getInstance().dispatch("GeckoView:AccessibilitySettings", ret);
             // "GeckoView:AccessibilityEnabled" is dispatched to the UI thread.
             EventDispatcher.getInstance().dispatch("GeckoView:AccessibilityEnabled", ret);
         }
     }
 
     private AccessibilityEvent obtainEvent(final int eventType, final int sourceId) {
@@ -440,17 +480,17 @@ public class SessionAccessibility {
             node.setChecked(message.getBoolean("checked"));
         }
         if (message.containsKey("selected")) {
             node.setSelected(message.getBoolean("selected"));
         }
     }
 
     private void sendAccessibilityEvent(final GeckoBundle message) {
-        if (mView == null || !Settings.isEnabled())
+        if (mView == null || !Settings.isTouchExplorationEnabled())
             return;
 
         final int eventType = message.getInt("eventType", -1);
         if (eventType < 0) {
             Log.e(LOGTAG, "No accessibility event type provided");
             return;
         }
 
@@ -494,17 +534,17 @@ public class SessionAccessibility {
         }
 
         final AccessibilityEvent accessibilityEvent = obtainEvent(eventType, eventSource);
         populateEventFromJSON(accessibilityEvent, message);
         ((ViewParent) mView).requestSendAccessibilityEvent(mView, accessibilityEvent);
     }
 
     public boolean onMotionEvent(final MotionEvent event) {
-        if (!Settings.isEnabled()) {
+        if (!Settings.isTouchExplorationEnabled()) {
             return false;
         }
 
         if (event.getSource() != InputDevice.SOURCE_TOUCHSCREEN) {
             return false;
         }
 
         final int action = event.getActionMasked();
@@ -514,9 +554,253 @@ public class SessionAccessibility {
             return false;
         }
 
         final GeckoBundle data = new GeckoBundle(2);
         data.putDoubleArray("coordinates", new double[] {event.getRawX(), event.getRawY()});
         mSession.getEventDispatcher().dispatch("GeckoView:AccessibilityExploreByTouch", data);
         return true;
     }
+
+    private int getAutoFillRootId(final int id) {
+        int root = View.NO_ID;
+        for (int newId = id; newId != View.NO_ID;) {
+            root = newId;
+            newId = mAutoFillNodes.get(newId).getInt("parent", View.NO_ID);
+        }
+        return root;
+    }
+
+    /* package */ AccessibilityNodeInfo getAutoFillNode(final int id) {
+        if (mView == null || mAutoFillRoots == null) {
+            return null;
+        }
+
+        final GeckoBundle bundle = mAutoFillNodes.get(id);
+        if (bundle == null) {
+            return null;
+        }
+
+        if (DEBUG) {
+            Log.d(LOGTAG, "getAutoFillNode(" + id + ')');
+        }
+
+        final AccessibilityNodeInfo node = AccessibilityNodeInfo.obtain(mView, id);
+        node.setPackageName(GeckoAppShell.getApplicationContext().getPackageName());
+        node.setParent(mView, bundle.getInt("parent", View.NO_ID));
+        node.setEnabled(true);
+
+        if (getAutoFillRootId(mAutoFillFocusedId) == getAutoFillRootId(id)) {
+            // Some auto-fill clients require a dummy rect for the focused View.
+            final Rect rect = new Rect();
+            mSession.getSurfaceBounds(rect);
+            node.setVisibleToUser(!rect.isEmpty());
+            node.setBoundsInParent(rect);
+
+            final int[] offset = new int[2];
+            mView.getLocationOnScreen(offset);
+            rect.offset(offset[0], offset[1]);
+            node.setBoundsInScreen(rect);
+        }
+
+        final GeckoBundle[] children = bundle.getBundleArray("children");
+        if (children != null) {
+            for (final GeckoBundle child : children) {
+                final int childId = child.getInt("id");
+                node.addChild(mView, childId);
+                mAutoFillNodes.append(childId, child);
+            }
+        }
+
+        String tag = bundle.getString("tag", "");
+        final String type = bundle.getString("type", "text");
+        final GeckoBundle attrs = bundle.getBundle("attributes");
+
+        if ("INPUT".equals(tag) && !bundle.getBoolean("editable", false)) {
+            tag = ""; // Don't process non-editable inputs (e.g. type="button").
+        }
+        switch (tag) {
+            case "INPUT":
+            case "TEXTAREA": {
+                final boolean disabled = bundle.getBoolean("disabled");
+                node.setClassName("android.widget.EditText");
+                node.setEnabled(!disabled);
+                node.setFocusable(!disabled);
+                node.setFocused(id == mAutoFillFocusedId);
+
+                if ("password".equals(type)) {
+                    node.setPassword(true);
+                }
+                if (Build.VERSION.SDK_INT >= 18) {
+                    node.setEditable(!disabled);
+                }
+                if (Build.VERSION.SDK_INT >= 19) {
+                    node.setMultiLine("TEXTAREA".equals(tag));
+                }
+                if (Build.VERSION.SDK_INT >= 21) {
+                    try {
+                        node.setMaxTextLength(Integer.parseInt(
+                                String.valueOf(attrs.get("maxlength"))));
+                    } catch (final NumberFormatException ignore) {
+                    }
+                }
+
+                if (!disabled) {
+                    if (Build.VERSION.SDK_INT >= 21) {
+                        node.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SET_TEXT);
+                    } else {
+                        node.addAction(ACTION_SET_TEXT);
+                    }
+                }
+                break;
+            }
+            default:
+                if (children != null) {
+                    node.setClassName("android.view.ViewGroup");
+                } else {
+                    node.setClassName("android.view.View");
+                }
+                break;
+        }
+
+        if (Build.VERSION.SDK_INT >= 19 && "INPUT".equals(tag)) {
+            switch (type) {
+                case "email":
+                    node.setInputType(InputType.TYPE_CLASS_TEXT |
+                                      InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS);
+                    break;
+                case "number":
+                    node.setInputType(InputType.TYPE_CLASS_NUMBER);
+                    break;
+                case "password":
+                    node.setInputType(InputType.TYPE_CLASS_TEXT |
+                                      InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD);
+                    break;
+                case "tel":
+                    node.setInputType(InputType.TYPE_CLASS_PHONE);
+                    break;
+                case "text":
+                    node.setInputType(InputType.TYPE_CLASS_TEXT |
+                                      InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT);
+                    break;
+                case "url":
+                    node.setInputType(InputType.TYPE_CLASS_TEXT |
+                                      InputType.TYPE_TEXT_VARIATION_URI);
+                    break;
+            }
+        }
+        return node;
+    }
+
+    /* package */ boolean performAutoFill(final int id, final String value) {
+        if (mAutoFillRoots == null) {
+            return false;
+        }
+
+        int rootId = id;
+        for (int currentId = id; currentId != View.NO_ID;) {
+            final GeckoBundle bundle = mAutoFillNodes.get(currentId);
+            if (bundle == null) {
+                return false;
+            }
+            rootId = currentId;
+            currentId = bundle.getInt("parent", View.NO_ID);
+        }
+
+        if (DEBUG) {
+            Log.d(LOGTAG, "performAutoFill(" + id + ", " + value + ')');
+        }
+
+        final EventCallback callback = mAutoFillRoots.get(rootId);
+        if (callback == null) {
+            return false;
+        }
+
+        final GeckoBundle response = new GeckoBundle(1);
+        response.putString(String.valueOf(id), value);
+        callback.sendSuccess(response);
+        return true;
+    }
+
+    private void fireWindowChangedEvent(final int id) {
+        if (mView instanceof ViewParent) {
+            final AccessibilityEvent event = obtainEvent(
+                    AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED, id);
+            if (Build.VERSION.SDK_INT >= 19) {
+                event.setContentChangeTypes(AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE);
+            }
+            ((ViewParent) mView).requestSendAccessibilityEvent(mView, event);
+        }
+    }
+
+    /* package */ void addAutoFill(final GeckoBundle message, final EventCallback callback) {
+        if (!Settings.isEnabled()) {
+            return;
+        }
+
+        if (mAutoFillRoots == null) {
+            mAutoFillRoots = new SparseArray<>();
+            mAutoFillNodes = new SparseArray<>();
+        }
+
+        final int id = message.getInt("id");
+        if (DEBUG) {
+            Log.d(LOGTAG, "addAutoFill(" + id + ')');
+        }
+
+        mAutoFillRoots.append(id, callback);
+        mAutoFillNodes.append(id, message);
+        fireWindowChangedEvent(id);
+    }
+
+    /* package */ void clearAutoFill() {
+        if (mAutoFillRoots != null) {
+            if (DEBUG) {
+                Log.d(LOGTAG, "clearAutoFill()");
+            }
+            mAutoFillRoots = null;
+            mAutoFillNodes = null;
+            mAutoFillFocusedId = View.NO_ID;
+            fireWindowChangedEvent(View.NO_ID);
+        }
+    }
+
+    /* package */ void onAutoFillFocus(final GeckoBundle message) {
+        if (!Settings.isEnabled() || !(mView instanceof ViewParent) || mAutoFillNodes == null) {
+            return;
+        }
+
+        final int id;
+        if (message != null) {
+            id = message.getInt("id");
+            mAutoFillNodes.put(id, message);
+        } else {
+            id = View.NO_ID;
+        }
+
+        if (DEBUG) {
+            Log.d(LOGTAG, "onAutoFillFocus(" + id + ')');
+        }
+        if (mAutoFillFocusedId == id) {
+            return;
+        }
+        mAutoFillFocusedId = id;
+
+        // We already send "TYPE_VIEW_FOCUSED" in touch exploration mode,
+        // so in that case don't send it here.
+        if (!Settings.isTouchExplorationEnabled()) {
+            AccessibilityEvent event = obtainEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED, id);
+            ((ViewParent) mView).requestSendAccessibilityEvent(mView, event);
+        }
+    }
+
+    /* package */ void onWindowFocus() {
+        // Auto-fill clients expect a state change event on focus.
+        if (Settings.isEnabled() && mView instanceof ViewParent) {
+            if (DEBUG) {
+                Log.d(LOGTAG, "onWindowFocus()");
+            }
+            final AccessibilityEvent event = obtainEvent(
+                    AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED, View.NO_ID);
+            ((ViewParent) mView).requestSendAccessibilityEvent(mView, event);
+        }
+    }
 }
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/SessionTextInput.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/SessionTextInput.java
@@ -6,50 +6,62 @@
 package org.mozilla.geckoview;
 
 import org.mozilla.gecko.InputMethods;
 import org.mozilla.gecko.annotation.WrapForJNI;
 import org.mozilla.gecko.GeckoEditableChild;
 import org.mozilla.gecko.IGeckoEditableParent;
 import org.mozilla.gecko.NativeQueue;
 import org.mozilla.gecko.util.ActivityUtils;
+import org.mozilla.gecko.util.BundleEventListener;
+import org.mozilla.gecko.util.EventCallback;
+import org.mozilla.gecko.util.GeckoBundle;
 import org.mozilla.gecko.util.ThreadUtils;
 
 import android.annotation.TargetApi;
 import android.app.Activity;
 import android.content.Context;
+import android.graphics.Rect;
 import android.graphics.RectF;
+import android.os.Build;
 import android.os.Handler;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.text.Editable;
+import android.text.InputType;
 import android.util.Log;
+import android.util.SparseArray;
 import android.view.KeyEvent;
 import android.view.View;
+import android.view.ViewStructure;
+import android.view.autofill.AutofillManager;
 import android.view.inputmethod.CursorAnchorInfo;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.ExtractedText;
 import android.view.inputmethod.ExtractedTextRequest;
 import android.view.inputmethod.InputConnection;
 import android.view.inputmethod.InputMethodManager;
 
+import java.util.Locale;
+
 /**
  * {@code SessionTextInput} handles text input for {@code GeckoSession} through key events or input
  * methods. It is typically used to implement certain methods in {@link android.view.View}
  * such as {@link android.view.View#onCreateInputConnection}, by forwarding such calls to
  * corresponding methods in {@code SessionTextInput}.
  * <p>
  * For full functionality, {@code SessionTextInput} requires a {@link android.view.View} to be set
  * first through {@link #setView}. When a {@link android.view.View} is not set or set to null,
  * {@code SessionTextInput} will operate in a reduced functionality mode. See {@link
  * #onCreateInputConnection} and methods in {@link GeckoSession.TextInputDelegate} for changes in
  * behavior in this viewless mode.
  */
 public final class SessionTextInput {
     /* package */ static final String LOGTAG = "GeckoSessionTextInput";
+    private static final boolean DEBUG = false;
 
     // Interface to access GeckoInputConnection from SessionTextInput.
     /* package */ interface InputConnectionClient {
         View getView();
         Handler getHandler(Handler defHandler);
         InputConnection onCreateInputConnection(EditorInfo attrs);
     }
 
@@ -213,32 +225,93 @@ public final class SessionTextInput {
                                            @NonNull final CursorAnchorInfo info) {
             ThreadUtils.assertOnUiThread();
             final View view = session.getTextInput().getView();
             final InputMethodManager imm = getInputMethodManager(view);
             if (imm != null) {
                 imm.updateCursorAnchorInfo(view, info);
             }
         }
+
+        @Override
+        public void notifyAutoFill(@NonNull final GeckoSession session,
+                                   @AutoFillNotification final int notification,
+                                   final int virtualId) {
+            ThreadUtils.assertOnUiThread();
+            final View view = session.getTextInput().getView();
+            if (Build.VERSION.SDK_INT < 26 || view == null) {
+                return;
+            }
+
+            final AutofillManager manager =
+                    view.getContext().getSystemService(AutofillManager.class);
+            if (manager == null) {
+                return;
+            }
+
+            switch (notification) {
+                case AUTO_FILL_NOTIFY_STARTED:
+                    // This line seems necessary for auto-fill to work on the initial page.
+                    manager.cancel();
+                    break;
+                case AUTO_FILL_NOTIFY_COMMITTED:
+                    manager.commit();
+                    break;
+                case AUTO_FILL_NOTIFY_CANCELED:
+                    manager.cancel();
+                    break;
+                case AUTO_FILL_NOTIFY_VIEW_ENTERED:
+                    // Use a dummy rect for the View.
+                    manager.notifyViewEntered(view, virtualId, getDummyAutoFillRect(
+                            session, /* screen */ true, view));
+                    break;
+                case AUTO_FILL_NOTIFY_VIEW_EXITED:
+                    manager.notifyViewExited(view, virtualId);
+                    break;
+            }
+        }
     }
 
     private final GeckoSession mSession;
     private final NativeQueue mQueue;
     private final GeckoEditable mEditable;
     private final GeckoEditableChild mEditableChild;
     private InputConnectionClient mInputConnection;
     private GeckoSession.TextInputDelegate mDelegate;
+    // Auto-fill nodes.
+    private SparseArray<GeckoBundle> mAutoFillNodes;
+    private SparseArray<EventCallback> mAutoFillRoots;
+    private int mAutoFillFocusedId = View.NO_ID;
 
     /* package */ SessionTextInput(final @NonNull GeckoSession session,
                                    final @NonNull NativeQueue queue) {
         mSession = session;
         mQueue = queue;
         mEditable = new GeckoEditable(session);
         mEditableChild = new GeckoEditableChild(mEditable);
         mEditable.setDefaultEditableChild(mEditableChild);
+
+        session.getEventDispatcher().registerUiThreadListener(
+                new BundleEventListener() {
+                    @Override
+                    public void handleMessage(final String event, final GeckoBundle message,
+                                              final EventCallback callback) {
+                        if ("GeckoView:AddAutoFill".equals(event)) {
+                            addAutoFill(message, callback);
+                        } else if ("GeckoView:ClearAutoFill".equals(event)) {
+                            clearAutoFill();
+                        } else if ("GeckoView:OnAutoFillFocus".equals(event)) {
+                            onAutoFillFocus(message);
+                        }
+                    }
+                },
+                "GeckoView:AddAutoFill",
+                "GeckoView:ClearAutoFill",
+                "GeckoView:OnAutoFillFocus",
+                null);
     }
 
     /* package */ void onWindowChanged(final GeckoSession.Window window) {
         if (mQueue.isReady()) {
             window.attachEditable(mEditable, mEditableChild);
         } else {
             mQueue.queueUntilReady(window, "attachEditable",
                                    IGeckoEditableParent.class, mEditable,
@@ -402,9 +475,302 @@ public final class SessionTextInput {
      */
     public GeckoSession.TextInputDelegate getDelegate() {
         ThreadUtils.assertOnUiThread();
         if (mDelegate == null) {
             mDelegate = DefaultDelegate.INSTANCE;
         }
         return mDelegate;
     }
+
+    /**
+     * Fill the specified {@link ViewStructure} with auto-fill fields from the current page.
+     *
+     * @param structure Structure to be filled.
+     * @param flags Zero or a combination of {@link View#AUTOFILL_FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
+     *              AUTOFILL_FLAG_*} constants.
+     */
+    @TargetApi(23)
+    public void onProvideAutofillVirtualStructure(@NonNull final ViewStructure structure,
+                                                  final int flags) {
+        final View view = getView();
+        if (view != null) {
+            structure.setClassName(view.getClass().getName());
+        }
+        structure.setEnabled(true);
+        structure.setVisibility(View.VISIBLE);
+
+        final Rect rect = getDummyAutoFillRect(mSession, /* screen */ false,
+                                               /* view */ null);
+        structure.setDimens(rect.left, rect.top, 0, 0, rect.width(), rect.height());
+
+        if (mAutoFillRoots == null) {
+            structure.setChildCount(0);
+            return;
+        }
+
+        final int size = mAutoFillRoots.size();
+        structure.setChildCount(size);
+
+        int focusedRoot = View.NO_ID;
+        for (int newId = mAutoFillFocusedId; newId != View.NO_ID;) {
+            focusedRoot = newId;
+            newId = mAutoFillNodes.get(newId).getInt("parent", View.NO_ID);
+        }
+
+        for (int i = 0; i < size; i++) {
+            final int id = mAutoFillRoots.keyAt(i);
+            final GeckoBundle root = mAutoFillNodes.get(id);
+            fillAutoFillStructure(view, id, root, structure.newChild(i),
+                                  (focusedRoot == id) ? rect : null);
+        }
+    }
+
+    /**
+     * Perform auto-fill using the specified values.
+     *
+     * @param values Map of auto-fill IDs to values.
+     */
+    public void autofill(final SparseArray<CharSequence> values) {
+        if (mAutoFillRoots == null) {
+            return;
+        }
+
+        GeckoBundle response = null;
+        EventCallback callback = null;
+
+        for (int i = 0; i < values.size(); i++) {
+            final int id = values.keyAt(i);
+            final CharSequence value = values.valueAt(i);
+
+            if (DEBUG) {
+                Log.d(LOGTAG,
+                      "performAutoFill(" + id + ", " + values + ')');
+            }
+            int rootId = id;
+            for (int currentId = id; currentId != View.NO_ID; ) {
+                final GeckoBundle bundle = mAutoFillNodes.get(currentId);
+                if (bundle == null) {
+                    return;
+                }
+                rootId = currentId;
+                currentId = bundle.getInt("parent", View.NO_ID);
+            }
+
+            final EventCallback newCallback = mAutoFillRoots.get(rootId);
+            if (callback == null || newCallback != callback) {
+                if (callback != null) {
+                    callback.sendSuccess(response);
+                }
+                response = new GeckoBundle(values.size() - i);
+                callback = newCallback;
+            }
+            response.putString(String.valueOf(id), String.valueOf(value));
+        }
+
+        if (callback != null) {
+            callback.sendSuccess(response);
+        }
+    }
+
+    @TargetApi(23)
+    private void fillAutoFillStructure(@Nullable final View view, final int id,
+                                       @NonNull final GeckoBundle bundle,
+                                       @NonNull final ViewStructure structure,
+                                       @Nullable final Rect rect) {
+        if (mAutoFillRoots == null) {
+            return;
+        }
+
+        if (DEBUG) {
+            Log.d(LOGTAG, "fillAutoFillStructure(" + id + ')');
+        }
+
+        if (Build.VERSION.SDK_INT >= 26) {
+            if (view != null) {
+                structure.setAutofillId(view.getAutofillId(), id);
+            }
+            structure.setWebDomain(bundle.getString("origin"));
+        }
+        structure.setId(id, null, null, null);
+
+        if (rect != null) {
+            structure.setDimens(0, 0, 0, 0, rect.width(), rect.height());
+        }
+
+        final GeckoBundle[] children = bundle.getBundleArray("children");
+        if (children != null) {
+            structure.setChildCount(children.length);
+            for (int i = 0; i < children.length; i++) {
+                final GeckoBundle childBundle = children[i];
+                final int childId = childBundle.getInt("id");
+                final ViewStructure childStructure = structure.newChild(i);
+                fillAutoFillStructure(view, childId, childBundle, childStructure, rect);
+                mAutoFillNodes.append(childId, childBundle);
+            }
+        }
+
+        String tag = bundle.getString("tag", "");
+        final String type = bundle.getString("type", "text");
+
+        if (Build.VERSION.SDK_INT >= 26) {
+            final GeckoBundle attrs = bundle.getBundle("attributes");
+            final ViewStructure.HtmlInfo.Builder builder =
+                    structure.newHtmlInfoBuilder(tag.toLowerCase(Locale.US));
+            for (final String key : attrs.keys()) {
+                builder.addAttribute(key, String.valueOf(attrs.get(key)));
+            }
+            structure.setHtmlInfo(builder.build());
+        }
+
+        if ("INPUT".equals(tag) && !bundle.getBoolean("editable", false)) {
+            tag = ""; // Don't process non-editable inputs (e.g. type="button").
+        }
+        switch (tag) {
+            case "INPUT":
+            case "TEXTAREA": {
+                final boolean disabled = bundle.getBoolean("disabled");
+                structure.setClassName("android.widget.EditText");
+                structure.setEnabled(!disabled);
+                structure.setFocusable(!disabled);
+                structure.setFocused(id == mAutoFillFocusedId);
+                structure.setVisibility(View.VISIBLE);
+
+                if (Build.VERSION.SDK_INT >= 26) {
+                    structure.setAutofillType(View.AUTOFILL_TYPE_TEXT);
+                }
+                break;
+            }
+            default:
+                if (children != null) {
+                    structure.setClassName("android.view.ViewGroup");
+                } else {
+                    structure.setClassName("android.view.View");
+                }
+                break;
+        }
+
+        if (Build.VERSION.SDK_INT >= 26 && "INPUT".equals(tag)) {
+            switch (type) {
+                case "email":
+                    structure.setAutofillHints(new String[] { View.AUTOFILL_HINT_EMAIL_ADDRESS });
+                    structure.setInputType(InputType.TYPE_CLASS_TEXT |
+                                              InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS);
+                    break;
+                case "number":
+                    structure.setInputType(InputType.TYPE_CLASS_NUMBER);
+                    break;
+                case "password":
+                    structure.setAutofillHints(new String[] { View.AUTOFILL_HINT_PASSWORD });
+                    structure.setInputType(InputType.TYPE_CLASS_TEXT |
+                                           InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD);
+                    break;
+                case "tel":
+                    structure.setAutofillHints(new String[] { View.AUTOFILL_HINT_PHONE });
+                    structure.setInputType(InputType.TYPE_CLASS_PHONE);
+                    break;
+                case "text":
+                    structure.setInputType(InputType.TYPE_CLASS_TEXT |
+                                           InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT);
+                    break;
+                case "url":
+                    structure.setInputType(InputType.TYPE_CLASS_TEXT |
+                                           InputType.TYPE_TEXT_VARIATION_URI);
+                    break;
+            }
+        }
+    }
+
+    /* package */ void addAutoFill(@NonNull final GeckoBundle message,
+                                   @NonNull final EventCallback callback) {
+        if (Build.VERSION.SDK_INT < 23) {
+            return;
+        }
+
+        final boolean initializing;
+        if (mAutoFillRoots == null) {
+            mAutoFillRoots = new SparseArray<>();
+            mAutoFillNodes = new SparseArray<>();
+            initializing = true;
+        } else {
+            initializing = false;
+        }
+
+        final int id = message.getInt("id");
+        if (DEBUG) {
+            Log.d(LOGTAG, "addAutoFill(" + id + ')');
+        }
+
+        mAutoFillRoots.append(id, callback);
+        mAutoFillNodes.append(id, message);
+
+        if (initializing) {
+            getDelegate().notifyAutoFill(
+                    mSession, GeckoSession.TextInputDelegate.AUTO_FILL_NOTIFY_STARTED, id);
+        } else {
+            getDelegate().notifyAutoFill(
+                    mSession, GeckoSession.TextInputDelegate.AUTO_FILL_NOTIFY_VIEW_ADDED, id);
+        }
+    }
+
+    /* package */ void clearAutoFill() {
+        if (mAutoFillRoots == null) {
+            return;
+        }
+        if (DEBUG) {
+            Log.d(LOGTAG, "clearAutoFill()");
+        }
+        mAutoFillRoots = null;
+        mAutoFillNodes = null;
+        mAutoFillFocusedId = View.NO_ID;
+
+        getDelegate().notifyAutoFill(
+                mSession, GeckoSession.TextInputDelegate.AUTO_FILL_NOTIFY_CANCELED, View.NO_ID);
+    }
+
+    /* package */ void onAutoFillFocus(@Nullable final GeckoBundle message) {
+        if (mAutoFillRoots == null) {
+            return;
+        }
+
+        final int id;
+        if (message != null) {
+            id = message.getInt("id");
+            mAutoFillNodes.put(id, message);
+        } else {
+            id = View.NO_ID;
+        }
+
+        if (DEBUG) {
+            Log.d(LOGTAG, "onAutoFillFocus(" + id + ')');
+        }
+        if (mAutoFillFocusedId == id) {
+            return;
+        }
+        if (mAutoFillFocusedId != View.NO_ID) {
+            getDelegate().notifyAutoFill(
+                    mSession, GeckoSession.TextInputDelegate.AUTO_FILL_NOTIFY_VIEW_EXITED,
+                    mAutoFillFocusedId);
+        }
+
+        mAutoFillFocusedId = id;
+        if (id != View.NO_ID) {
+            getDelegate().notifyAutoFill(
+                    mSession, GeckoSession.TextInputDelegate.AUTO_FILL_NOTIFY_VIEW_ENTERED, id);
+        }
+    }
+
+    /* package */ static Rect getDummyAutoFillRect(@NonNull final GeckoSession session,
+                                                   final boolean screen,
+                                                   @Nullable final View view) {
+        final Rect rect = new Rect();
+        session.getSurfaceBounds(rect);
+        if (screen) {
+            if (view == null) {
+                throw new IllegalArgumentException();
+            }
+            final int[] offset = new int[2];
+            view.getLocationOnScreen(offset);
+            rect.offset(offset[0], offset[1]);
+        }
+        return rect;
+    }
 }
--- a/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/GeckoViewActivity.java
+++ b/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/GeckoViewActivity.java
@@ -189,28 +189,16 @@ public class GeckoViewActivity extends A
     }
 
     private void updateTrackingProtection(GeckoSession session) {
         session.getSettings().setBoolean(
             GeckoSessionSettings.USE_TRACKING_PROTECTION, mUseTrackingProtection);
     }
 
     @Override
-    protected void onPause() {
-        mGeckoSession.setActive(false);
-        super.onPause();
-    }
-
-    @Override
-    protected void onResume() {
-        mGeckoSession.setActive(true);
-        super.onResume();
-    }
-
-    @Override
     public void onBackPressed() {
         if (mFullScreen) {
             mGeckoSession.exitFullScreen();
             return;
         }
 
         if (mCanGoBack && mGeckoSession != null) {
             mGeckoSession.goBack();
--- a/mobile/android/modules/geckoview/GeckoViewContent.jsm
+++ b/mobile/android/modules/geckoview/GeckoViewContent.jsm
@@ -18,16 +18,17 @@ class GeckoViewContent extends GeckoView
     this.registerListener([
         "GeckoViewContent:ExitFullScreen",
         "GeckoView:ClearMatches",
         "GeckoView:DisplayMatches",
         "GeckoView:FindInPage",
         "GeckoView:RestoreState",
         "GeckoView:SaveState",
         "GeckoView:SetActive",
+        "GeckoView:SetFocused",
         "GeckoView:ZoomToInput",
     ]);
 
     this.messageManager.addMessageListener("GeckoView:SaveStateFinish", this);
   }
 
   onEnable() {
     this.window.addEventListener("MozDOMFullscreen:Entered", this,
@@ -73,22 +74,27 @@ class GeckoViewContent extends GeckoView
         this._findInPage(aData, aCallback);
         break;
       }
       case "GeckoView:ZoomToInput":
         this.messageManager.sendAsyncMessage(aEvent);
         break;
       case "GeckoView:SetActive":
         if (aData.active) {
-          this.browser.setAttribute("primary", "true");
-          this.browser.focus();
           this.browser.docShellIsActive = true;
         } else {
+          this.browser.docShellIsActive = false;
+        }
+        break;
+      case "GeckoView:SetFocused":
+        if (aData.focused) {
+          this.browser.focus();
+          this.browser.setAttribute("primary", "true");
+        } else {
           this.browser.removeAttribute("primary");
-          this.browser.docShellIsActive = false;
           this.browser.blur();
         }
         break;
       case "GeckoView:SaveState":
         if (!this._saveStateCallbacks) {
           this._saveStateCallbacks = new Map();
           this._saveStateNextId = 0;
         }
--- a/netwerk/base/nsIPermissionManager.idl
+++ b/netwerk/base/nsIPermissionManager.idl
@@ -171,16 +171,21 @@ interface nsIPermissionManager : nsISupp
   void removeAll();
 
   /**
    * Clear all permission information added since the specified time.
    */
   void removeAllSince(in int64_t since);
 
   /**
+   * Clear all permissions of the passed type.
+   */
+  void removeByType(in string type);
+
+  /**
    * Test whether a website has permission to perform the given action.
    * This function will perform a pref lookup to permissions.default.<type>
    * if the specific permission type is part of the whitelist for that functionality.
    * @param uri     the uri to be tested
    * @param type    a case-sensitive ASCII string, identifying the consumer
    * @param return  see add(), param permission. returns UNKNOWN_ACTION when
    *                there is no stored permission for this uri and / or type.
    */
--- a/old-configure.in
+++ b/old-configure.in
@@ -859,16 +859,20 @@ case "$target" in
             # Silence problematic clang warnings
             CXXFLAGS="$CXXFLAGS -Wno-incompatible-ms-struct"
         fi
     else
         TARGET_COMPILER_ABI=msvc
         if test "$AS_BIN"; then
             AS="$(basename "$AS_BIN")"
         fi
+        # armasm64 doesn't understand -c.
+        if test "$CPU_ARCH" = "aarch64"; then
+            AS_DASH_C_FLAG=
+        fi
         case "$LINKER" in
         *lld*)
             AR='llvm-lib'
             AR_FLAGS='-llvmlibthin -out:$@'
             ;;
         *)
             AR='lib'
             AR_FLAGS='-NOLOGO -OUT:$@'
--- a/python/mozbuild/mozbuild/frontend/context.py
+++ b/python/mozbuild/mozbuild/frontend/context.py
@@ -368,16 +368,20 @@ class AsmFlags(BaseCompileFlags):
         if (self._context.config.substs.get('MOZ_DEBUG') or
             self._context.config.substs.get('MOZ_DEBUG_SYMBOLS')):
             if self._context.get('USE_YASM'):
                 if (self._context.config.substs.get('OS_ARCH') == 'WINNT' and
                     not self._context.config.substs.get('GNU_CC')):
                     debug_flags += ['-g', 'cv8']
                 elif self._context.config.substs.get('OS_ARCH') != 'Darwin':
                     debug_flags += ['-g', 'dwarf2']
+            elif (self._context.config.substs.get('OS_ARCH') == 'WINNT' and
+                  self._context.config.substs.get('CPU_ARCH') == 'aarch64'):
+                # armasm64 accepts a paucity of options compared to ml/ml64.
+                pass
             else:
                 debug_flags += self._context.config.substs.get('MOZ_DEBUG_FLAGS', '').split()
         return debug_flags
 
 
 class LinkFlags(BaseCompileFlags):
     def __init__(self, context):
         self._context = context
@@ -402,29 +406,16 @@ class LinkFlags(BaseCompileFlags):
             flags += self._context.config.substs.get('MOZ_DEBUG_LDFLAGS', [])
 
         # TODO: This is pretty convoluted, and isn't really a per-context thing,
         # configure would be a better place to aggregate these.
         if all([self._context.config.substs.get('OS_ARCH') == 'WINNT',
                 not self._context.config.substs.get('GNU_CC'),
                 not self._context.config.substs.get('MOZ_DEBUG')]):
 
-            # MOZ_DEBUG_SYMBOLS generates debug symbols in separate PDB files.
-            # Used for generating an optimized build with debugging symbols.
-            # Used in the Windows nightlies to generate symbols for crash reporting.
-            if self._context.config.substs.get('MOZ_DEBUG_SYMBOLS'):
-                flags.append('-DEBUG')
-
-
-            if self._context.config.substs.get('MOZ_DMD'):
-                # On Windows Opt DMD builds we actually override everything
-                # from OS_LDFLAGS. Bug 1413728 is on file to figure out whether
-                # this is necessary.
-                flags = ['-DEBUG']
-
             if self._context.config.substs.get('MOZ_OPTIMIZE'):
                 flags.append('-OPT:REF,ICF')
 
         return flags
 
 
 class CompileFlags(BaseCompileFlags):
     def __init__(self, context):
--- a/python/mozbuild/mozbuild/mach_commands.py
+++ b/python/mozbuild/mozbuild/mach_commands.py
@@ -900,16 +900,20 @@ class RunProgram(MachCommandBase):
                 args.extend(params)
 
             if not remote:
                 args.append('-no-remote')
 
             if not background and sys.platform == 'darwin':
                 args.append('-foreground')
 
+            if sys.platform.startswith('win') and \
+               'MOZ_LAUNCHER_PROCESS' in self.defines:
+                args.append('-wait-for-browser')
+
             no_profile_option_given = \
                 all(p not in params for p in ['-profile', '--profile', '-P'])
             if no_profile_option_given and not noprofile:
                 prefs = {
                    'browser.shell.checkDefaultBrowser': False,
                    'general.warnOnAboutConfig': False,
                 }
                 prefs.update(self._mach_context.settings.runprefs)
--- a/python/mozbuild/mozbuild/test/configure/test_toolchain_configure.py
+++ b/python/mozbuild/mozbuild/test/configure/test_toolchain_configure.py
@@ -962,17 +962,22 @@ class WindowsToolchainTest(BaseToolchain
     GXX_5_RESULT = LinuxToolchainTest.GXX_5_RESULT
     GCC_6_RESULT = LinuxToolchainTest.GCC_6_RESULT
     GXX_6_RESULT = LinuxToolchainTest.GXX_6_RESULT
     DEFAULT_GCC_RESULT = LinuxToolchainTest.DEFAULT_GCC_RESULT
     DEFAULT_GXX_RESULT = LinuxToolchainTest.DEFAULT_GXX_RESULT
 
     # VS2017u6 or greater is required.
     def test_msvc(self):
-        self.do_toolchain_test(self.PATHS, {
+        # We'll pick msvc if clang-cl can't be found.
+        paths = {
+            k: v for k, v in self.PATHS.iteritems()
+            if os.path.basename(k) != 'clang-cl'
+        }
+        self.do_toolchain_test(paths, {
             'c_compiler': self.VS_2017u6_RESULT,
             'cxx_compiler': self.VSXX_2017u6_RESULT,
         })
 
     def test_unsupported_msvc(self):
         self.do_toolchain_test(self.PATHS, {
             'c_compiler': self.VS_2017u4_RESULT,
         }, environ={
@@ -1011,22 +1016,17 @@ class WindowsToolchainTest(BaseToolchain
 
         self.do_toolchain_test(self.PATHS, {
             'c_compiler': self.VS_2013u2_RESULT,
         }, environ={
             'CC': '/opt/VS_2013u2/bin/cl',
         })
 
     def test_clang_cl(self):
-        # We'll pick clang-cl if msvc can't be found.
-        paths = {
-            k: v for k, v in self.PATHS.iteritems()
-            if os.path.basename(k) != 'cl'
-        }
-        self.do_toolchain_test(paths, {
+        self.do_toolchain_test(self.PATHS, {
             'c_compiler': self.CLANG_CL_3_9_RESULT,
             'cxx_compiler': self.CLANGXX_CL_3_9_RESULT,
         })
 
     def test_gcc(self):
         # We'll pick GCC if msvc and clang-cl can't be found.
         paths = {
             k: v for k, v in self.PATHS.iteritems()
--- a/python/mozbuild/mozbuild/test/frontend/test_emitter.py
+++ b/python/mozbuild/mozbuild/test/frontend/test_emitter.py
@@ -262,34 +262,35 @@ class TestEmitterBasic(unittest.TestCase
         self.assertEqual(ldflags.flags['OS'],
                          reader.config.substs['MOZ_DEBUG_LDFLAGS'])
 
     def test_windows_opt_link_flags(self):
         reader = self.reader('link-flags', extra_substs={
             'OS_ARCH': 'WINNT',
             'GNU_CC': '',
             'MOZ_OPTIMIZE': '1',
+            'MOZ_DEBUG_LDFLAGS': ['-DEBUG'],
             'MOZ_DEBUG_SYMBOLS': '1',
             'MOZ_OPTIMIZE_FLAGS': [],
             'MOZ_OPTIMIZE_LDFLAGS': [],
         })
         sources, ldflags, lib, compile_flags = self.read_topsrcdir(reader)
         self.assertIsInstance(ldflags, ComputedFlags)
         self.assertIn('-DEBUG', ldflags.flags['OS'])
         self.assertIn('-OPT:REF,ICF', ldflags.flags['OS'])
 
     def test_windows_dmd_link_flags(self):
         reader = self.reader('link-flags', extra_substs={
             'OS_ARCH': 'WINNT',
             'GNU_CC': '',
             'MOZ_DMD': '1',
+            'MOZ_DEBUG_LDFLAGS': ['-DEBUG'],
             'MOZ_DEBUG_SYMBOLS': '1',
             'MOZ_OPTIMIZE': '1',
             'MOZ_OPTIMIZE_FLAGS': [],
-            'OS_LDFLAGS': ['-Wl,-U_foo'],
         })
         sources, ldflags, lib, compile_flags = self.read_topsrcdir(reader)
         self.assertIsInstance(ldflags, ComputedFlags)
         self.assertEqual(ldflags.flags['OS'],
                          ['-DEBUG', '-OPT:REF,ICF'])
 
     def test_host_compile_flags(self):
         reader = self.reader('host-compile-flags', extra_substs={
--- a/testing/firefox-ui/tests/functional/security/test_ssl_disabled_error_page.py
+++ b/testing/firefox-ui/tests/functional/security/test_ssl_disabled_error_page.py
@@ -46,15 +46,21 @@ class TestSSLDisabledErrorPage(Puppeteer
             self.assertEquals(title.get_property('textContent'), nss_failure2title)
 
             # Verify the error message is correct
             short_description = self.marionette.find_element(By.ID, 'errorShortDescText')
             self.assertIn('SSL_ERROR_UNSUPPORTED_VERSION',
                           short_description.get_property('textContent'))
 
             # Verify that the "Restore" button appears and works
-            reset_button = self.marionette.find_element(By.ID, 'prefResetButton')
-            reset_button.click()
+            restore_button = self.marionette.find_element(By.ID, 'prefResetButton')
+            restore_button.click()
+            Wait(self.marionette).until(
+                expected.element_not_present(By.ID, "prefResetButton"),
+                message="Click on the restore button didn't trigger a page load"
+            )
 
             # With the preferences reset, the page has to load correctly
             el = Wait(self.marionette, timeout=self.marionette.timeout.page_load).until(
-                expected.element_present(By.TAG_NAME, 'h1'))
+                expected.element_present(By.TAG_NAME, 'h1'),
+                message="Expected target page has not been loaded"
+            )
             self.assertIn('tls-v1-0', el.get_property('innerText'))
--- a/testing/talos/talos/tests/devtools/addon/content/pages/custom/debugger/index.html
+++ b/testing/talos/talos/tests/devtools/addon/content/pages/custom/debugger/index.html
@@ -1,135 +1,1 @@
-<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <meta charset="utf-8">
-    <meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no">
-    <meta name="theme-color" content="#000000">
-    <!--
-      Notice the use of . in the tags above.
-      It will be replaced with the URL of the `public` folder during the build.
-      Only files inside the `public` folder can be referenced from the HTML.
-
-      Unlike "/favicon.ico" or "favicon.ico", "./favicon.ico" will
-      work correctly both with client-side routing and a non-root public URL.
-      Learn how to configure a non-root public URL by running `npm run build`.
-    -->
-    <title>React App</title>
-    <script type="text/javascript" src="./js/testfile.js?id=0"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=1"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=2"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=3"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=4"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=5"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=6"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=7"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=8"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=9"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=10"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=11"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=12"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=13"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=14"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=15"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=16"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=17"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=18"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=19"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=20"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=21"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=22"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=23"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=24"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=25"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=26"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=27"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=28"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=29"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=30"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=31"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=32"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=33"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=34"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=35"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=36"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=37"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=38"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=39"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=40"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=41"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=42"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=43"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=44"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=45"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=46"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=47"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=48"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=49"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=50"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=51"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=52"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=53"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=54"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=55"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=56"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=57"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=58"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=59"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=60"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=61"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=62"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=63"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=64"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=65"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=66"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=67"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=68"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=69"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=70"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=71"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=72"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=73"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=74"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=75"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=76"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=77"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=78"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=79"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=80"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=81"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=82"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=83"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=84"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=85"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=86"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=87"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=88"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=89"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=90"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=91"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=92"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=93"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=94"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=95"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=96"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=97"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=98"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=99"></script>
-    <script type="text/javascript" src="./js/testfile.js?id=100"></script>
-  </head>
-  <body>
-    <noscript>
-      You need to enable JavaScript to run this app.
-    </noscript>
-    <div id="root"></div>
-    <!--
-      This HTML file is a template.
-      If you open it directly in the browser, you will see an empty page.
-
-      You can add webfonts, meta tags, or analytics to this file.
-      The build step will place the bundled scripts into the <body> tag.
-
-      To begin the development, run `npm start` or `yarn start`.
-      To create a production bundle, use `npm run build` or `yarn build`.
-    -->
-  <script type="text/javascript" src="./static/js/main.js"></script></body>
-</html>
+<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta name="theme-color" content="#000000"><link rel="manifest" href="./manifest.json"><title>React App</title></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script type="text/javascript" src="./static/js/main.js"></script></body></html>
deleted file mode 100644
--- a/testing/talos/talos/tests/devtools/addon/content/pages/custom/debugger/js/testfile.js
+++ /dev/null
@@ -1,1001 +0,0 @@
-(function () {
-  function f0() {
-    f1();
-    return Math.random();
-  }
-
-  function f1() {
-    f2();
-    return Math.random();
-  }
-
-  function f2() {
-    f3();
-    return Math.random();
-  }
-
-  function f3() {
-    f4();
-    return Math.random();
-  }
-
-  function f4() {
-    f5();
-    return Math.random();
-  }
-
-  function f5() {
-    f6();
-    return Math.random();
-  }
-
-  function f6() {
-    f7();
-    return Math.random();
-  }
-
-  function f7() {
-    f8();
-    return Math.random();
-  }
-
-  function f8() {
-    f9();
-    return Math.random();
-  }
-
-  function f9() {
-    f10();
-    return Math.random();
-  }
-
-  function f10() {
-    f11();
-    return Math.random();
-  }
-
-  function f11() {
-    f12();
-    return Math.random();
-  }
-
-  function f12() {
-    f13();
-    return Math.random();
-  }
-
-  function f13() {
-    f14();
-    return Math.random();
-  }
-
-  function f14() {
-    f15();
-    return Math.random();
-  }
-
-  function f15() {
-    f16();
-    return Math.random();
-  }
-
-  function f16() {
-    f17();
-    return Math.random();
-  }
-
-  function f17() {
-    f18();
-    return Math.random();
-  }
-
-  function f18() {
-    f19();
-    return Math.random();
-  }
-
-  function f19() {
-    f20();
-    return Math.random();
-  }
-
-  function f20() {
-    f21();
-    return Math.random();
-  }
-
-  function f21() {
-    f22();
-    return Math.random();
-  }
-
-  function f22() {
-    f23();
-    return Math.random();
-  }
-
-  function f23() {
-    f24();
-    return Math.random();
-  }
-
-  function f24() {
-    f25();
-    return Math.random();
-  }
-
-  function f25() {
-    f26();
-    return Math.random();
-  }
-
-  function f26() {
-    f27();
-    return Math.random();
-  }
-
-  function f27() {
-    f28();
-    return Math.random();
-  }
-
-  function f28() {
-    f29();
-    return Math.random();
-  }
-
-  function f29() {
-    f30();
-    return Math.random();
-  }
-
-  function f30() {
-    f31();
-    return Math.random();
-  }
-
-  function f31() {
-    f32();
-    return Math.random();
-  }
-
-  function f32() {
-    f33();
-    return Math.random();
-  }
-
-  function f33() {
-    f34();
-    return Math.random();
-  }
-
-  function f34() {
-    f35();
-    return Math.random();
-  }
-
-  function f35() {
-    f36();
-    return Math.random();
-  }
-
-  function f36() {
-    f37();
-    return Math.random();
-  }
-
-  function f37() {
-    f38();
-    return Math.random();
-  }
-
-  function f38() {
-    f39();
-    return Math.random();
-  }
-
-  function f39() {
-    f40();
-    return Math.random();
-  }
-
-  function f40() {
-    f41();
-    return Math.random();
-  }
-
-  function f41() {
-    f42();
-    return Math.random();
-  }
-
-  function f42() {
-    f43();
-    return Math.random();
-  }
-
-  function f43() {
-    f44();
-    return Math.random();
-  }
-
-  function f44() {
-    f45();
-    return Math.random();
-  }
-
-  function f45() {
-    f46();
-    return Math.random();
-  }
-
-  function f46() {
-    f47();
-    return Math.random();
-  }
-
-  function f47() {
-    f48();
-    return Math.random();
-  }
-
-  function f48() {
-    f49();
-    return Math.random();
-  }
-
-  function f49() {
-    f50();
-    return Math.random();
-  }
-
-  function f50() {
-    f51();
-    return Math.random();
-  }
-
-  function f51() {
-    f52();
-    return Math.random();
-  }
-
-  function f52() {
-    f53();
-    return Math.random();
-  }
-
-  function f53() {
-    f54();
-    return Math.random();
-  }
-
-  function f54() {
-    f55();
-    return Math.random();
-  }
-
-  function f55() {
-    f56();
-    return Math.random();
-  }
-
-  function f56() {
-    f57();
-    return Math.random();
-  }
-
-  function f57() {
-    f58();
-    return Math.random();
-  }
-
-  function f58() {
-    f59();
-    return Math.random();
-  }
-
-  function f59() {
-    f60();
-    return Math.random();
-  }
-
-  function f60() {
-    f61();
-    return Math.random();
-  }
-
-  function f61() {
-    f62();
-    return Math.random();
-  }
-
-  function f62() {
-    f63();
-    return Math.random();
-  }
-
-  function f63() {
-    f64();
-    return Math.random();
-  }
-
-  function f64() {
-    f65();
-    return Math.random();
-  }
-
-  function f65() {
-    f66();
-    return Math.random();
-  }
-
-  function f66() {
-    f67();
-    return Math.random();
-  }
-
-  function f67() {
-    f68();
-    return Math.random();
-  }
-
-  function f68() {
-    f69();
-    return Math.random();
-  }
-
-  function f69() {
-    f70();
-    return Math.random();
-  }
-
-  function f70() {
-    f71();
-    return Math.random();
-  }
-
-  function f71() {
-    f72();
-    return Math.random();
-  }
-
-  function f72() {
-    f73();
-    return Math.random();
-  }
-
-  function f73() {
-    f74();
-    return Math.random();
-  }
-
-  function f74() {
-    f75();
-    return Math.random();
-  }
-
-  function f75() {
-    f76();
-    return Math.random();
-  }
-
-  function f76() {
-    f77();
-    return Math.random();
-  }
-
-  function f77() {
-    f78();
-    return Math.random();
-  }
-
-  function f78() {
-    f79();
-    return Math.random();
-  }
-
-  function f79() {
-    f80();
-    return Math.random();
-  }
-
-  function f80() {
-    f81();
-    return Math.random();
-  }
-
-  function f81() {
-    f82();
-    return Math.random();
-  }
-
-  function f82() {
-    f83();
-    return Math.random();
-  }
-
-  function f83() {
-    f84();
-    return Math.random();
-  }
-
-  function f84() {
-    f85();
-    return Math.random();
-  }
-
-  function f85() {
-    f86();
-    return Math.random();
-  }
-
-  function f86() {
-    f87();
-    return Math.random();
-  }
-
-  function f87() {
-    f88();
-    return Math.random();
-  }
-
-  function f88() {
-    f89();
-    return Math.random();
-  }
-
-  function f89() {
-    f90();
-    return Math.random();
-  }
-
-  function f90() {
-    f91();
-    return Math.random();
-  }
-
-  function f91() {
-    f92();
-    return Math.random();
-  }
-
-  function f92() {
-    f93();
-    return Math.random();
-  }
-
-  function f93() {
-    f94();
-    return Math.random();
-  }
-
-  function f94() {
-    f95();
-    return Math.random();
-  }
-
-  function f95() {
-    f96();
-    return Math.random();
-  }
-
-  function f96() {
-    f97();
-    return Math.random();
-  }
-
-  function f97() {
-    f98();
-    return Math.random();
-  }
-
-  function f98() {
-    f99();
-    return Math.random();
-  }
-
-  function f99() {
-    f100();
-    return Math.random();
-  }
-
-
-  function f100() {
-    f101();
-    return Math.random();
-  }
-
-  function f101() {
-    f102();
-    return Math.random();
-  }
-
-  function f102() {
-    f103();
-    return Math.random();
-  }
-
-  function f103() {
-    f104();
-    return Math.random();
-  }
-
-  function f104() {
-    f105();
-    return Math.random();
-  }
-
-  function f105() {
-    f106();
-    return Math.random();
-  }
-
-  function f106() {
-    f107();
-    return Math.random();
-  }
-
-  function f107() {
-    f108();
-    return Math.random();
-  }
-
-  function f108() {
-    f109();
-    return Math.random();
-  }
-
-  function f109() {
-    f110();
-    return Math.random();
-  }
-
-  function f110() {
-    f111();
-    return Math.random();
-  }
-
-  function f111() {
-    f112();
-    return Math.random();
-  }
-
-  function f112() {
-    f113();
-    return Math.random();
-  }
-
-  function f113() {
-    f114();
-    return Math.random();
-  }
-
-  function f114() {
-    f115();
-    return Math.random();
-  }
-
-  function f115() {
-    f116();
-    return Math.random();
-  }
-
-  function f116() {
-    f117();
-    return Math.random();
-  }
-
-  function f117() {
-    f118();
-    return Math.random();
-  }
-
-  function f118() {
-    f119();
-    return Math.random();
-  }
-
-  function f119() {
-    f120();
-    return Math.random();
-  }
-
-  function f120() {
-    f121();
-    return Math.random();
-  }
-
-  function f121() {
-    f122();
-    return Math.random();
-  }
-
-  function f122() {
-    f123();
-    return Math.random();
-  }
-
-  function f123() {
-    f124();
-    return Math.random();
-  }
-
-  function f124() {
-    f125();
-    return Math.random();
-  }
-
-  function f125() {
-    f126();
-    return Math.random();
-  }
-
-  function f126() {
-    f127();
-    return Math.random();
-  }
-
-  function f127() {
-    f128();
-    return Math.random();
-  }
-
-  function f128() {
-    f129();
-    return Math.random();
-  }
-
-  function f129() {
-    f130();
-    return Math.random();
-  }
-
-  function f130() {
-    f131();
-    return Math.random();
-  }
-
-  function f131() {
-    f132();
-    return Math.random();
-  }
-
-  function f132() {
-    f133();
-    return Math.random();
-  }
-
-  function f133() {
-    f134();
-    return Math.random();
-  }
-
-  function f134() {
-    f135();
-    return Math.random();
-  }
-
-  function f135() {
-    f136();
-    return Math.random();
-  }
-
-  function f136() {
-    f137();
-    return Math.random();
-  }
-
-  function f137() {
-    f138();
-    return Math.random();
-  }
-
-  function f138() {
-    f139();
-    return Math.random();
-  }
-
-  function f139() {
-    f140();
-    return Math.random();
-  }
-
-  function f140() {
-    f141();
-    return Math.random();
-  }
-
-  function f141() {
-    f142();
-    return Math.random();
-  }
-
-  function f142() {
-    f143();
-    return Math.random();
-  }
-
-  function f143() {
-    f144();
-    return Math.random();
-  }
-
-  function f144() {
-    f145();
-    return Math.random();
-  }
-
-  function f145() {
-    f146();
-    return Math.random();
-  }
-
-  function f146() {
-    f147();
-    return Math.random();
-  }
-
-  function f147() {
-    f148();
-    return Math.random();
-  }
-
-  function f148() {
-    f149();
-    return Math.random();
-  }
-
-  function f149() {
-    f150();
-    return Math.random();
-  }
-
-  function f150() {
-    f151();
-    return Math.random();
-  }
-
-  function f151() {
-    f152();
-    return Math.random();
-  }
-
-  function f152() {
-    f153();
-    return Math.random();
-  }
-
-  function f153() {
-    f154();
-    return Math.random();
-  }
-
-  function f154() {
-    f155();
-    return Math.random();
-  }
-
-  function f155() {
-    f156();
-    return Math.random();
-  }
-
-  function f156() {
-    f157();
-    return Math.random();
-  }
-
-  function f157() {
-    f158();
-    return Math.random();
-  }
-
-  function f158() {
-    f159();
-    return Math.random();
-  }
-
-  function f159() {
-    f160();
-    return Math.random();
-  }
-
-  function f160() {
-    f161();
-    return Math.random();
-  }
-
-  function f161() {
-    f162();
-    return Math.random();
-  }
-
-  function f162() {
-    f163();
-    return Math.random();
-  }
-
-  function f163() {
-    f164();
-    return Math.random();
-  }
-
-  function f164() {
-    f165();
-    return Math.random();
-  }
-
-  function f165() {
-    f166();
-    return Math.random();
-  }
-
-  function f166() {
-    f167();
-    return Math.random();
-  }
-
-  function f167() {
-    f168();
-    return Math.random();
-  }
-
-  function f168() {
-    f169();
-    return Math.random();
-  }
-
-  function f169() {
-    f170();
-    return Math.random();
-  }
-
-  function f170() {
-    f171();
-    return Math.random();
-  }
-
-  function f171() {
-    f172();
-    return Math.random();
-  }
-
-  function f172() {
-    f173();
-    return Math.random();
-  }
-
-  function f173() {
-    f174();
-    return Math.random();
-  }
-
-  function f174() {
-    f175();
-    return Math.random();
-  }
-
-  function f175() {
-    f176();
-    return Math.random();
-  }
-
-  function f176() {
-    f177();
-    return Math.random();
-  }
-
-  function f177() {
-    f178();
-    return Math.random();
-  }
-
-  function f178() {
-    f179();
-    return Math.random();
-  }
-
-  function f179() {
-    f180();
-    return Math.random();
-  }
-
-  function f180() {
-    f181();
-    return Math.random();
-  }
-
-  function f181() {
-    f182();
-    return Math.random();
-  }
-
-  function f182() {
-    f183();
-    return Math.random();
-  }
-
-  function f183() {
-    f184();
-    return Math.random();
-  }
-
-  function f184() {
-    f185();
-    return Math.random();
-  }
-
-  function f185() {
-    f186();
-    return Math.random();
-  }
-
-  function f186() {
-    f187();
-    return Math.random();
-  }
-
-  function f187() {
-    f188();
-    return Math.random();
-  }
-
-  function f188() {
-    f189();
-    return Math.random();
-  }
-
-  function f189() {
-    f190();
-    return Math.random();
-  }
-
-  function f190() {
-    f191();
-    return Math.random();
-  }
-
-  function f191() {
-    f192();
-    return Math.random();
-  }
-
-  function f192() {
-    f193();
-    return Math.random();
-  }
-
-  function f193() {
-    f194();
-    return Math.random();
-  }
-
-  function f194() {
-    f195();
-    return Math.random();
-  }
-
-  function f195() {
-    f196();
-    return Math.random();
-  }
-
-  function f196() {
-    f197();
-    return Math.random();
-  }
-
-  function f197() {
-    f198();
-    return Math.random();
-  }
-
-  function f198() {
-    f199();
-    return Math.random();
-  }
-
-  function f199() {
-    return Math.random();
-  }
-})();
--- a/testing/talos/talos/tests/devtools/addon/content/pages/custom/debugger/static/js/main.js
+++ b/testing/talos/talos/tests/devtools/addon/content/pages/custom/debugger/static/js/main.js
@@ -1,2 +1,2 @@
-!function(n){function t(r){if(e[r])return e[r].exports;var o=e[r]={i:r,l:!1,exports:{}};return n[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var e={};t.m=n,t.c=e,t.d=function(n,e,r){t.o(n,e)||Object.defineProperty(n,e,{configurable:!1,enumerable:!0,get:r})},t.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(e,"a",e),e},t.o=function(n,t){return Object.prototype.hasOwnProperty.call(n,t)},t.p="./",t(t.s=6)}([function(n,t,e){"use strict";function r(n){if(null===n||void 0===n)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(n)}var o=Object.getOwnPropertySymbols,a=Object.prototype.hasOwnProperty,u=Object.prototype.propertyIsEnumerable;n.exports=function(){try{if(!Object.assign)return!1;var n=new String("abc");if(n[5]="de","5"===Object.getOwnPropertyNames(n)[0])return!1;for(var t={},e=0;e<10;e++)t["_"+String.fromCharCode(e)]=e;if("0123456789"!==Object.getOwnPropertyNames(t).map(function(n){return t[n]}).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach(function(n){r[n]=n}),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(n){return!1}}()?Object.assign:function(n,t){for(var e,i,c=r(n),f=1;f<arguments.length;f++){e=Object(arguments[f]);for(var d in e)a.call(e,d)&&(c[d]=e[d]);if(o){i=o(e);for(var m=0;m<i.length;m++)u.call(e,i[m])&&(c[i[m]]=e[i[m]])}}return c}},function(n,t,e){"use strict";n.exports=e(14)},function(n,t,e){"use strict";function r(){}function o(n){try{return n.then}catch(n){return v=n,N}}function a(n,t){try{return n(t)}catch(n){return v=n,N}}function u(n,t,e){try{n(t,e)}catch(n){return v=n,N}}function i(n){if("object"!==typeof this)throw new TypeError("Promises must be constructed via new");if("function"!==typeof n)throw new TypeError("Promise constructor's argument is not a function");this._40=0,this._65=0,this._55=null,this._72=null,n!==r&&p(n,this)}function c(n,t,e){return new n.constructor(function(o,a){var u=new i(r);u.then(o,a),f(n,new s(t,e,u))})}function f(n,t){for(;3===n._65;)n=n._55;if(i._37&&i._37(n),0===n._65)return 0===n._40?(n._40=1,void(n._72=t)):1===n._40?(n._40=2,void(n._72=[n._72,t])):void n._72.push(t);d(n,t)}function d(n,t){M(function(){var e=1===n._65?t.onFulfilled:t.onRejected;if(null===e)return void(1===n._65?m(t.promise,n._55):l(t.promise,n._55));var r=a(e,n._55);r===N?l(t.promise,v):m(t.promise,r)})}function m(n,t){if(t===n)return l(n,new TypeError("A promise cannot be resolved with itself."));if(t&&("object"===typeof t||"function"===typeof t)){var e=o(t);if(e===N)return l(n,v);if(e===n.then&&t instanceof i)return n._65=3,n._55=t,void h(n);if("function"===typeof e)return void p(e.bind(t),n)}n._65=1,n._55=t,h(n)}function l(n,t){n._65=2,n._55=t,i._87&&i._87(n,t),h(n)}function h(n){if(1===n._40&&(f(n,n._72),n._72=null),2===n._40){for(var t=0;t<n._72.length;t++)f(n,n._72[t]);n._72=null}}function s(n,t,e){this.onFulfilled="function"===typeof n?n:null,this.onRejected="function"===typeof t?t:null,this.promise=e}function p(n,t){var e=!1,r=u(n,function(n){e||(e=!0,m(t,n))},function(n){e||(e=!0,l(t,n))});e||r!==N||(e=!0,l(t,v))}var M=e(9),v=null,N={};n.exports=i,i._37=null,i._87=null,i._61=r,i.prototype.then=function(n,t){if(this.constructor!==i)return c(this,n,t);var e=new i(r);return f(this,new s(n,t,e)),e}},function(n,t,e){"use strict";function r(n,t,e,r,a,u,i,c){if(o(t),!n){var f;if(void 0===t)f=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var d=[e,r,a,u,i,c],m=0;f=new Error(t.replace(/%s/g,function(){return d[m++]})),f.name="Invariant Violation"}throw f.framesToPop=1,f}}var o=function(n){};n.exports=r},function(n,t,e){"use strict";var r={};n.exports=r},function(n,t,e){"use strict";function r(n){return function(){return n}}var o=function(){};o.thatReturns=r,o.thatReturnsFalse=r(!1),o.thatReturnsTrue=r(!0),o.thatReturnsNull=r(null),o.thatReturnsThis=function(){return this},o.thatReturnsArgument=function(n){return n},n.exports=o},function(n,t,e){e(7),n.exports=e(13)},function(n,t,e){"use strict";"undefined"===typeof Promise&&(e(8).enable(),window.Promise=e(11)),e(12),Object.assign=e(0)},function(n,t,e){"use strict";function r(){f=!1,i._37=null,i._87=null}function o(n){function t(t){(n.allRejections||u(m[t].error,n.whitelist||c))&&(m[t].displayId=d++,n.onUnhandled?(m[t].logged=!0,n.onUnhandled(m[t].displayId,m[t].error)):(m[t].logged=!0,a(m[t].displayId,m[t].error)))}function e(t){m[t].logged&&(n.onHandled?n.onHandled(m[t].displayId,m[t].error):m[t].onUnhandled||(console.warn("Promise Rejection Handled (id: "+m[t].displayId+"):"),console.warn('  This means you can ignore any previous messages of the form "Possible Unhandled Promise Rejection" with id '+m[t].displayId+".")))}n=n||{},f&&r(),f=!0;var o=0,d=0,m={};i._37=function(n){2===n._65&&m[n._51]&&(m[n._51].logged?e(n._51):clearTimeout(m[n._51].timeout),delete m[n._51])},i._87=function(n,e){0===n._40&&(n._51=o++,m[n._51]={displayId:null,error:e,timeout:setTimeout(t.bind(null,n._51),u(e,c)?100:2e3),logged:!1})}}function a(n,t){console.warn("Possible Unhandled Promise Rejection (id: "+n+"):"),((t&&(t.stack||t))+"").split("\n").forEach(function(n){console.warn("  "+n)})}function u(n,t){return t.some(function(t){return n instanceof t})}var i=e(2),c=[ReferenceError,TypeError,RangeError],f=!1;t.disable=r,t.enable=o},function(n,t,e){"use strict";(function(t){function e(n){u.length||(a(),i=!0),u[u.length]=n}function r(){for(;c<u.length;){var n=c;if(c+=1,u[n].call(),c>f){for(var t=0,e=u.length-c;t<e;t++)u[t]=u[t+c];u.length-=c,c=0}}u.length=0,c=0,i=!1}function o(n){return function(){function t(){clearTimeout(e),clearInterval(r),n()}var e=setTimeout(t,0),r=setInterval(t,50)}}n.exports=e;var a,u=[],i=!1,c=0,f=1024,d="undefined"!==typeof t?t:self,m=d.MutationObserver||d.WebKitMutationObserver;a="function"===typeof m?function(n){var t=1,e=new m(n),r=document.createTextNode("");return e.observe(r,{characterData:!0}),function(){t=-t,r.data=t}}(r):o(r),e.requestFlush=a,e.makeRequestCallFromTimer=o}).call(t,e(10))},function(n,t){var e;e=function(){return this}();try{e=e||Function("return this")()||(0,eval)("this")}catch(n){"object"===typeof window&&(e=window)}n.exports=e},function(n,t,e){"use strict";function r(n){var t=new o(o._61);return t._65=1,t._55=n,t}var o=e(2);n.exports=o;var a=r(!0),u=r(!1),i=r(null),c=r(void 0),f=r(0),d=r("");o.resolve=function(n){if(n instanceof o)return n;if(null===n)return i;if(void 0===n)return c;if(!0===n)return a;if(!1===n)return u;if(0===n)return f;if(""===n)return d;if("object"===typeof n||"function"===typeof n)try{var t=n.then;if("function"===typeof t)return new o(t.bind(n))}catch(n){return new o(function(t,e){e(n)})}return r(n)},o.all=function(n){var t=Array.prototype.slice.call(n);return new o(function(n,e){function r(u,i){if(i&&("object"===typeof i||"function"===typeof i)){if(i instanceof o&&i.then===o.prototype.then){for(;3===i._65;)i=i._55;return 1===i._65?r(u,i._55):(2===i._65&&e(i._55),void i.then(function(n){r(u,n)},e))}var c=i.then;if("function"===typeof c){return void new o(c.bind(i)).then(function(n){r(u,n)},e)}}t[u]=i,0===--a&&n(t)}if(0===t.length)return n([]);for(var a=t.length,u=0;u<t.length;u++)r(u,t[u])})},o.reject=function(n){return new o(function(t,e){e(n)})},o.race=function(n){return new o(function(t,e){n.forEach(function(n){o.resolve(n).then(t,e)})})},o.prototype.catch=function(n){return this.then(null,n)}},function(n,t){!function(n){"use strict";function t(n){if("string"!==typeof n&&(n=String(n)),/[^a-z0-9\-#$%&'*+.\^_`|~]/i.test(n))throw new TypeError("Invalid character in header field name");return n.toLowerCase()}function e(n){return"string"!==typeof n&&(n=String(n)),n}function r(n){var t={next:function(){var t=n.shift();return{done:void 0===t,value:t}}};return v.iterable&&(t[Symbol.iterator]=function(){return t}),t}function o(n){this.map={},n instanceof o?n.forEach(function(n,t){this.append(t,n)},this):Array.isArray(n)?n.forEach(function(n){this.append(n[0],n[1])},this):n&&Object.getOwnPropertyNames(n).forEach(function(t){this.append(t,n[t])},this)}function a(n){if(n.bodyUsed)return Promise.reject(new TypeError("Already read"));n.bodyUsed=!0}function u(n){return new Promise(function(t,e){n.onload=function(){t(n.result)},n.onerror=function(){e(n.error)}})}function i(n){var t=new FileReader,e=u(t);return t.readAsArrayBuffer(n),e}function c(n){var t=new FileReader,e=u(t);return t.readAsText(n),e}function f(n){for(var t=new Uint8Array(n),e=new Array(t.length),r=0;r<t.length;r++)e[r]=String.fromCharCode(t[r]);return e.join("")}function d(n){if(n.slice)return n.slice(0);var t=new Uint8Array(n.byteLength);return t.set(new Uint8Array(n)),t.buffer}function m(){return this.bodyUsed=!1,this._initBody=function(n){if(this._bodyInit=n,n)if("string"===typeof n)this._bodyText=n;else if(v.blob&&Blob.prototype.isPrototypeOf(n))this._bodyBlob=n;else if(v.formData&&FormData.prototype.isPrototypeOf(n))this._bodyFormData=n;else if(v.searchParams&&URLSearchParams.prototype.isPrototypeOf(n))this._bodyText=n.toString();else if(v.arrayBuffer&&v.blob&&y(n))this._bodyArrayBuffer=d(n.buffer),this._bodyInit=new Blob([this._bodyArrayBuffer]);else{if(!v.arrayBuffer||!ArrayBuffer.prototype.isPrototypeOf(n)&&!x(n))throw new Error("unsupported BodyInit type");this._bodyArrayBuffer=d(n)}else this._bodyText="";this.headers.get("content-type")||("string"===typeof n?this.headers.set("content-type","text/plain;charset=UTF-8"):this._bodyBlob&&this._bodyBlob.type?this.headers.set("content-type",this._bodyBlob.type):v.searchParams&&URLSearchParams.prototype.isPrototypeOf(n)&&this.headers.set("content-type","application/x-www-form-urlencoded;charset=UTF-8"))},v.blob&&(this.blob=function(){var n=a(this);if(n)return n;if(this._bodyBlob)return Promise.resolve(this._bodyBlob);if(this._bodyArrayBuffer)return Promise.resolve(new Blob([this._bodyArrayBuffer]));if(this._bodyFormData)throw new Error("could not read FormData body as blob");return Promise.resolve(new Blob([this._bodyText]))},this.arrayBuffer=function(){return this._bodyArrayBuffer?a(this)||Promise.resolve(this._bodyArrayBuffer):this.blob().then(i)}),this.text=function(){var n=a(this);if(n)return n;if(this._bodyBlob)return c(this._bodyBlob);if(this._bodyArrayBuffer)return Promise.resolve(f(this._bodyArrayBuffer));if(this._bodyFormData)throw new Error("could not read FormData body as text");return Promise.resolve(this._bodyText)},v.formData&&(this.formData=function(){return this.text().then(s)}),this.json=function(){return this.text().then(JSON.parse)},this}function l(n){var t=n.toUpperCase();return C.indexOf(t)>-1?t:n}function h(n,t){t=t||{};var e=t.body;if(n instanceof h){if(n.bodyUsed)throw new TypeError("Already read");this.url=n.url,this.credentials=n.credentials,t.headers||(this.headers=new o(n.headers)),this.method=n.method,this.mode=n.mode,e||null==n._bodyInit||(e=n._bodyInit,n.bodyUsed=!0)}else this.url=String(n);if(this.credentials=t.credentials||this.credentials||"omit",!t.headers&&this.headers||(this.headers=new o(t.headers)),this.method=l(t.method||this.method||"GET"),this.mode=t.mode||this.mode||null,this.referrer=null,("GET"===this.method||"HEAD"===this.method)&&e)throw new TypeError("Body not allowed for GET or HEAD requests");this._initBody(e)}function s(n){var t=new FormData;return n.trim().split("&").forEach(function(n){if(n){var e=n.split("="),r=e.shift().replace(/\+/g," "),o=e.join("=").replace(/\+/g," ");t.append(decodeURIComponent(r),decodeURIComponent(o))}}),t}function p(n){var t=new o;return n.replace(/\r?\n[\t ]+/g," ").split(/\r?\n/).forEach(function(n){var e=n.split(":"),r=e.shift().trim();if(r){var o=e.join(":").trim();t.append(r,o)}}),t}function M(n,t){t||(t={}),this.type="default",this.status=void 0===t.status?200:t.status,this.ok=this.status>=200&&this.status<300,this.statusText="statusText"in t?t.statusText:"OK",this.headers=new o(t.headers),this.url=t.url||"",this._initBody(n)}if(!n.fetch){var v={searchParams:"URLSearchParams"in n,iterable:"Symbol"in n&&"iterator"in Symbol,blob:"FileReader"in n&&"Blob"in n&&function(){try{return new Blob,!0}catch(n){return!1}}(),formData:"FormData"in n,arrayBuffer:"ArrayBuffer"in n};if(v.arrayBuffer)var N=["[object Int8Array]","[object Uint8Array]","[object Uint8ClampedArray]","[object Int16Array]","[object Uint16Array]","[object Int32Array]","[object Uint32Array]","[object Float32Array]","[object Float64Array]"],y=function(n){return n&&DataView.prototype.isPrototypeOf(n)},x=ArrayBuffer.isView||function(n){return n&&N.indexOf(Object.prototype.toString.call(n))>-1};o.prototype.append=function(n,r){n=t(n),r=e(r);var o=this.map[n];this.map[n]=o?o+","+r:r},o.prototype.delete=function(n){delete this.map[t(n)]},o.prototype.get=function(n){return n=t(n),this.has(n)?this.map[n]:null},o.prototype.has=function(n){return this.map.hasOwnProperty(t(n))},o.prototype.set=function(n,r){this.map[t(n)]=e(r)},o.prototype.forEach=function(n,t){for(var e in this.map)this.map.hasOwnProperty(e)&&n.call(t,this.map[e],e,this)},o.prototype.keys=function(){var n=[];return this.forEach(function(t,e){n.push(e)}),r(n)},o.prototype.values=function(){var n=[];return this.forEach(function(t){n.push(t)}),r(n)},o.prototype.entries=function(){var n=[];return this.forEach(function(t,e){n.push([e,t])}),r(n)},v.iterable&&(o.prototype[Symbol.iterator]=o.prototype.entries);var C=["DELETE","GET","HEAD","OPTIONS","POST","PUT"];h.prototype.clone=function(){return new h(this,{body:this._bodyInit})},m.call(h.prototype),m.call(M.prototype),M.prototype.clone=function(){return new M(this._bodyInit,{status:this.status,statusText:this.statusText,headers:new o(this.headers),url:this.url})},M.error=function(){var n=new M(null,{status:0,statusText:""});return n.type="error",n};var g=[301,302,303,307,308];M.redirect=function(n,t){if(-1===g.indexOf(t))throw new RangeError("Invalid status code");return new M(null,{status:t,headers:{location:n}})},n.Headers=o,n.Request=h,n.Response=M,n.fetch=function(n,t){return new Promise(function(e,r){var o=new h(n,t),a=new XMLHttpRequest;a.onload=function(){var n={status:a.status,statusText:a.statusText,headers:p(a.getAllResponseHeaders()||"")};n.url="responseURL"in a?a.responseURL:n.headers.get("X-Request-URL");var t="response"in a?a.response:a.responseText;e(new M(t,n))},a.onerror=function(){r(new TypeError("Network request failed"))},a.ontimeout=function(){r(new TypeError("Network request failed"))},a.open(o.method,o.url,!0),"include"===o.credentials?a.withCredentials=!0:"omit"===o.credentials&&(a.withCredentials=!1),"responseType"in a&&v.blob&&(a.responseType="blob"),o.headers.forEach(function(n,t){a.setRequestHeader(t,n)}),a.send("undefined"===typeof o._bodyInit?null:o._bodyInit)})},n.fetch.polyfill=!0}}("undefined"!==typeof self?self:this)},function(n,t,e){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=e(1),o=e.n(r),a=e(15),u=e.n(a),i=e(23);u.a.render(o.a.createElement(i.a,null),document.getElementById("root"))},function(n,t,e){"use strict";function r(n){for(var t=arguments.length-1,e="https://reactjs.org/docs/error-decoder.html?invariant="+n,r=0;r<t;r++)e+="&args[]="+encodeURIComponent(arguments[r+1]);N(!1,"Minified React error #"+n+"; visit %s for the full message or use the non-minified dev environment for full errors and additional helpful warnings. ",e)}function o(n,t,e){this.props=n,this.context=t,this.refs=y,this.updater=e||T}function a(){}function u(n,t,e){this.props=n,this.context=t,this.refs=y,this.updater=e||T}function i(n,t,e){var r=void 0,o={},a=null,u=null;if(null!=t)for(r in void 0!==t.ref&&(u=t.ref),void 0!==t.key&&(a=""+t.key),t)O.call(t,r)&&!F.hasOwnProperty(r)&&(o[r]=t[r]);var i=arguments.length-2;if(1===i)o.children=e;else if(1<i){for(var c=Array(i),f=0;f<i;f++)c[f]=arguments[f+2];o.children=c}if(n&&n.defaultProps)for(r in i=n.defaultProps)void 0===o[r]&&(o[r]=i[r]);return{$$typeof:g,type:n,key:a,ref:u,props:o,_owner:P.current}}function c(n){return"object"===typeof n&&null!==n&&n.$$typeof===g}function f(n){var t={"=":"=0",":":"=2"};return"$"+(""+n).replace(/[=:]/g,function(n){return t[n]})}function d(n,t,e,r){if(A.length){var o=A.pop();return o.result=n,o.keyPrefix=t,o.func=e,o.context=r,o.count=0,o}return{result:n,keyPrefix:t,func:e,context:r,count:0}}function m(n){n.result=null,n.keyPrefix=null,n.func=null,n.context=null,n.count=0,10>A.length&&A.push(n)}function l(n,t,e,o){var a=typeof n;"undefined"!==a&&"boolean"!==a||(n=null);var u=!1;if(null===n)u=!0;else switch(a){case"string":case"number":u=!0;break;case"object":switch(n.$$typeof){case g:case b:u=!0}}if(u)return e(o,n,""===t?"."+h(n,0):t),1;if(u=0,t=""===t?".":t+":",Array.isArray(n))for(var i=0;i<n.length;i++){a=n[i];var c=t+h(a,i);u+=l(a,c,e,o)}else if(null===n||"undefined"===typeof n?c=null:(c=E&&n[E]||n["@@iterator"],c="function"===typeof c?c:null),"function"===typeof c)for(n=c.call(n),i=0;!(a=n.next()).done;)a=a.value,c=t+h(a,i++),u+=l(a,c,e,o);else"object"===a&&(e=""+n,r("31","[object Object]"===e?"object with keys {"+Object.keys(n).join(", ")+"}":e,""));return u}function h(n,t){return"object"===typeof n&&null!==n&&null!=n.key?f(n.key):t.toString(36)}function s(n,t){n.func.call(n.context,t,n.count++)}function p(n,t,e){var r=n.result,o=n.keyPrefix;n=n.func.call(n.context,t,n.count++),Array.isArray(n)?M(n,r,e,x.thatReturnsArgument):null!=n&&(c(n)&&(t=o+(!n.key||t&&t.key===n.key?"":(""+n.key).replace(D,"$&/")+"/")+e,n={$$typeof:g,type:n.type,key:t,ref:n.ref,props:n.props,_owner:n._owner}),r.push(n))}function M(n,t,e,r,o){var a="";null!=e&&(a=(""+e).replace(D,"$&/")+"/"),t=d(t,a,r,o),null==n||l(n,"",p,t),m(t)}var v=e(0),N=e(3),y=e(4),x=e(5),C="function"===typeof Symbol&&Symbol.for,g=C?Symbol.for("react.element"):60103,b=C?Symbol.for("react.portal"):60106,U=C?Symbol.for("react.fragment"):60107,R=C?Symbol.for("react.strict_mode"):60108,I=C?Symbol.for("react.profiler"):60114,Q=C?Symbol.for("react.provider"):60109,w=C?Symbol.for("react.context"):60110,_=C?Symbol.for("react.async_mode"):60111,k=C?Symbol.for("react.forward_ref"):60112;C&&Symbol.for("react.timeout");var E="function"===typeof Symbol&&Symbol.iterator,T={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}};o.prototype.isReactComponent={},o.prototype.setState=function(n,t){"object"!==typeof n&&"function"!==typeof n&&null!=n&&r("85"),this.updater.enqueueSetState(this,n,t,"setState")},o.prototype.forceUpdate=function(n){this.updater.enqueueForceUpdate(this,n,"forceUpdate")},a.prototype=o.prototype;var S=u.prototype=new a;S.constructor=u,v(S,o.prototype),S.isPureReactComponent=!0;var P={current:null},O=Object.prototype.hasOwnProperty,F={key:!0,ref:!0,__self:!0,__source:!0},D=/\/+/g,A=[],j={Children:{map:function(n,t,e){if(null==n)return n;var r=[];return M(n,r,null,t,e),r},forEach:function(n,t,e){if(null==n)return n;t=d(null,null,t,e),null==n||l(n,"",s,t),m(t)},count:function(n){return null==n?0:l(n,"",x.thatReturnsNull,null)},toArray:function(n){var t=[];return M(n,t,null,x.thatReturnsArgument),t},only:function(n){return c(n)||r("143"),n}},createRef:function(){return{current:null}},Component:o,PureComponent:u,createContext:function(n,t){return void 0===t&&(t=null),n={$$typeof:w,_calculateChangedBits:t,_defaultValue:n,_currentValue:n,_currentValue2:n,_changedBits:0,_changedBits2:0,Provider:null,Consumer:null},n.Provider={$$typeof:Q,_context:n},n.Consumer=n},forwardRef:function(n){return{$$typeof:k,render:n}},Fragment:U,StrictMode:R,unstable_AsyncMode:_,unstable_Profiler:I,createElement:i,cloneElement:function(n,t,e){(null===n||void 0===n)&&r("267",n);var o=void 0,a=v({},n.props),u=n.key,i=n.ref,c=n._owner;if(null!=t){void 0!==t.ref&&(i=t.ref,c=P.current),void 0!==t.key&&(u=""+t.key);var f=void 0;n.type&&n.type.defaultProps&&(f=n.type.defaultProps);for(o in t)O.call(t,o)&&!F.hasOwnProperty(o)&&(a[o]=void 0===t[o]&&void 0!==f?f[o]:t[o])}if(1===(o=arguments.length-2))a.children=e;else if(1<o){f=Array(o);for(var d=0;d<o;d++)f[d]=arguments[d+2];a.children=f}return{$$typeof:g,type:n.type,key:u,ref:i,props:a,_owner:c}},createFactory:function(n){var t=i.bind(null,n);return t.type=n,t},isValidElement:c,version:"16.4.2",__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED:{ReactCurrentOwner:P,assign:v}},L={default:j},z=L&&j||L;n.exports=z.default?z.default:z},function(n,t,e){"use strict";function r(){if("undefined"!==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"===typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE)try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(r)}catch(n){console.error(n)}}r(),n.exports=e(16)},function(n,t,e){"use strict";function r(n){for(var t=arguments.length-1,e="https://reactjs.org/docs/error-decoder.html?invariant="+n,r=0;r<t;r++)e+="&args[]="+encodeURIComponent(arguments[r+1]);Pr(!1,"Minified React error #"+n+"; visit %s for the full message or use the non-minified dev environment for full errors and additional helpful warnings. ",e)}function o(n,t,e,r,o,a,u,i,c){this._hasCaughtError=!1,this._caughtError=null;var f=Array.prototype.slice.call(arguments,3);try{t.apply(e,f)}catch(n){this._caughtError=n,this._hasCaughtError=!0}}function a(){if(Vr._hasRethrowError){var n=Vr._rethrowError;throw Vr._rethrowError=null,Vr._hasRethrowError=!1,n}}function u(){if(Wr)for(var n in Hr){var t=Hr[n],e=Wr.indexOf(n);if(-1<e||r("96",n),!$r[e]){t.extractEvents||r("97",n),$r[e]=t,e=t.eventTypes;for(var o in e){var a=void 0,u=e[o],c=t,f=o;qr.hasOwnProperty(f)&&r("99",f),qr[f]=u;var d=u.phasedRegistrationNames;if(d){for(a in d)d.hasOwnProperty(a)&&i(d[a],c,f);a=!0}else u.registrationName?(i(u.registrationName,c,f),a=!0):a=!1;a||r("98",o,n)}}}}function i(n,t,e){Kr[n]&&r("100",n),Kr[n]=t,Gr[n]=t.eventTypes[e].dependencies}function c(n){Wr&&r("101"),Wr=Array.prototype.slice.call(n),u()}function f(n){var t,e=!1;for(t in n)if(n.hasOwnProperty(t)){var o=n[t];Hr.hasOwnProperty(t)&&Hr[t]===o||(Hr[t]&&r("102",t),Hr[t]=o,e=!0)}e&&u()}function d(n,t,e,r){t=n.type||"unknown-event",n.currentTarget=Jr(r),Vr.invokeGuardedCallbackAndCatchFirstError(t,e,void 0,n),n.currentTarget=null}function m(n,t){return null==t&&r("30"),null==n?t:Array.isArray(n)?Array.isArray(t)?(n.push.apply(n,t),n):(n.push(t),n):Array.isArray(t)?[n].concat(t):[n,t]}function l(n,t,e){Array.isArray(n)?n.forEach(t,e):n&&t.call(e,n)}function h(n,t){if(n){var e=n._dispatchListeners,r=n._dispatchInstances;if(Array.isArray(e))for(var o=0;o<e.length&&!n.isPropagationStopped();o++)d(n,t,e[o],r[o]);else e&&d(n,t,e,r);n._dispatchListeners=null,n._dispatchInstances=null,n.isPersistent()||n.constructor.release(n)}}function s(n){return h(n,!0)}function p(n){return h(n,!1)}function M(n,t){var e=n.stateNode;if(!e)return null;var o=Yr(e);if(!o)return null;e=o[t];n:switch(t){case"onClick":case"onClickCapture":case"onDoubleClick":case"onDoubleClickCapture":case"onMouseDown":case"onMouseDownCapture":case"onMouseMove":case"onMouseMoveCapture":case"onMouseUp":case"onMouseUpCapture":(o=!o.disabled)||(n=n.type,o=!("button"===n||"input"===n||"select"===n||"textarea"===n)),n=!o;break n;default:n=!1}return n?null:(e&&"function"!==typeof e&&r("231",t,typeof e),e)}function v(n,t){null!==n&&(no=m(no,n)),n=no,no=null,n&&(t?l(n,s):l(n,p),no&&r("95"),Vr.rethrowCaughtError())}function N(n,t,e,r){for(var o=null,a=0;a<$r.length;a++){var u=$r[a];u&&(u=u.extractEvents(n,t,e,r))&&(o=m(o,u))}v(o,!1)}function y(n){if(n[oo])return n[oo];for(;!n[oo];){if(!n.parentNode)return null;n=n.parentNode}return n=n[oo],5===n.tag||6===n.tag?n:null}function x(n){if(5===n.tag||6===n.tag)return n.stateNode;r("33")}function C(n){return n[ao]||null}function g(n){do{n=n.return}while(n&&5!==n.tag);return n||null}function b(n,t,e){for(var r=[];n;)r.push(n),n=g(n);for(n=r.length;0<n--;)t(r[n],"captured",e);for(n=0;n<r.length;n++)t(r[n],"bubbled",e)}function U(n,t,e){(t=M(n,e.dispatchConfig.phasedRegistrationNames[t]))&&(e._dispatchListeners=m(e._dispatchListeners,t),e._dispatchInstances=m(e._dispatchInstances,n))}function R(n){n&&n.dispatchConfig.phasedRegistrationNames&&b(n._targetInst,U,n)}function I(n){if(n&&n.dispatchConfig.phasedRegistrationNames){var t=n._targetInst;t=t?g(t):null,b(t,U,n)}}function Q(n,t,e){n&&e&&e.dispatchConfig.registrationName&&(t=M(n,e.dispatchConfig.registrationName))&&(e._dispatchListeners=m(e._dispatchListeners,t),e._dispatchInstances=m(e._dispatchInstances,n))}function w(n){n&&n.dispatchConfig.registrationName&&Q(n._targetInst,null,n)}function _(n){l(n,R)}function k(n,t,e,r){if(e&&r)n:{for(var o=e,a=r,u=0,i=o;i;i=g(i))u++;i=0;for(var c=a;c;c=g(c))i++;for(;0<u-i;)o=g(o),u--;for(;0<i-u;)a=g(a),i--;for(;u--;){if(o===a||o===a.alternate)break n;o=g(o),a=g(a)}o=null}else o=null;for(a=o,o=[];e&&e!==a&&(null===(u=e.alternate)||u!==a);)o.push(e),e=g(e);for(e=[];r&&r!==a&&(null===(u=r.alternate)||u!==a);)e.push(r),r=g(r);for(r=0;r<o.length;r++)Q(o[r],"bubbled",n);for(n=e.length;0<n--;)Q(e[n],"captured",t)}function E(n,t){var e={};return e[n.toLowerCase()]=t.toLowerCase(),e["Webkit"+n]="webkit"+t,e["Moz"+n]="moz"+t,e["ms"+n]="MS"+t,e["O"+n]="o"+t.toLowerCase(),e}function T(n){if(fo[n])return fo[n];if(!co[n])return n;var t,e=co[n];for(t in e)if(e.hasOwnProperty(t)&&t in mo)return fo[n]=e[t];return n}function S(){return!vo&&Fr.canUseDOM&&(vo="textContent"in document.documentElement?"textContent":"innerText"),vo}function P(){if(No._fallbackText)return No._fallbackText;var n,t,e=No._startText,r=e.length,o=O(),a=o.length;for(n=0;n<r&&e[n]===o[n];n++);var u=r-n;for(t=1;t<=u&&e[r-t]===o[a-t];t++);return No._fallbackText=o.slice(n,1<t?1-t:void 0),No._fallbackText}function O(){return"value"in No._root?No._root.value:No._root[S()]}function F(n,t,e,r){this.dispatchConfig=n,this._targetInst=t,this.nativeEvent=e,n=this.constructor.Interface;for(var o in n)n.hasOwnProperty(o)&&((t=n[o])?this[o]=t(e):"target"===o?this.target=r:this[o]=e[o]);return this.isDefaultPrevented=(null!=e.defaultPrevented?e.defaultPrevented:!1===e.returnValue)?Ar.thatReturnsTrue:Ar.thatReturnsFalse,this.isPropagationStopped=Ar.thatReturnsFalse,this}function D(n,t,e,r){if(this.eventPool.length){var o=this.eventPool.pop();return this.call(o,n,t,e,r),o}return new this(n,t,e,r)}function A(n){n instanceof this||r("223"),n.destructor(),10>this.eventPool.length&&this.eventPool.push(n)}function j(n){n.eventPool=[],n.getPooled=D,n.release=A}function L(n,t){switch(n){case"keyup":return-1!==bo.indexOf(t.keyCode);case"keydown":return 229!==t.keyCode;case"keypress":case"mousedown":case"blur":return!0;default:return!1}}function z(n){return n=n.detail,"object"===typeof n&&"data"in n?n.data:null}function B(n,t){switch(n){case"compositionend":return z(t);case"keypress":return 32!==t.which?null:(ko=!0,wo);case"textInput":return n=t.data,n===wo&&ko?null:n;default:return null}}function V(n,t){if(Eo)return"compositionend"===n||!Uo&&L(n,t)?(n=P(),No._root=null,No._startText=null,No._fallbackText=null,Eo=!1,n):null;switch(n){case"paste":return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1<t.char.length)return t.char;if(t.which)return String.fromCharCode(t.which)}return null;case"compositionend":return Qo?null:t.data;default:return null}}function W(n){if(n=Zr(n)){So&&"function"===typeof So.restoreControlledState||r("194");var t=Yr(n.stateNode);So.restoreControlledState(n.stateNode,n.type,t)}}function H(n){Oo?Fo?Fo.push(n):Fo=[n]:Oo=n}function $(){return null!==Oo||null!==Fo}function q(){if(Oo){var n=Oo,t=Fo;if(Fo=Oo=null,W(n),t)for(n=0;n<t.length;n++)W(t[n])}}function K(n,t){return n(t)}function G(n,t,e){return n(t,e)}function X(){}function Y(n,t){if(Ao)return n(t);Ao=!0;try{return K(n,t)}finally{Ao=!1,$()&&(X(),q())}}function Z(n){var t=n&&n.nodeName&&n.nodeName.toLowerCase();return"input"===t?!!jo[n.type]:"textarea"===t}function J(n){return n=n.target||n.srcElement||window,n.correspondingUseElement&&(n=n.correspondingUseElement),3===n.nodeType?n.parentNode:n}function nn(n,t){return!(!Fr.canUseDOM||t&&!("addEventListener"in document))&&(n="on"+n,t=n in document,t||(t=document.createElement("div"),t.setAttribute(n,"return;"),t="function"===typeof t[n]),t)}function tn(n){var t=n.type;return(n=n.nodeName)&&"input"===n.toLowerCase()&&("checkbox"===t||"radio"===t)}function en(n){var t=tn(n)?"checked":"value",e=Object.getOwnPropertyDescriptor(n.constructor.prototype,t),r=""+n[t];if(!n.hasOwnProperty(t)&&"undefined"!==typeof e&&"function"===typeof e.get&&"function"===typeof e.set){var o=e.get,a=e.set;return Object.defineProperty(n,t,{configurable:!0,get:function(){return o.call(this)},set:function(n){r=""+n,a.call(this,n)}}),Object.defineProperty(n,t,{enumerable:e.enumerable}),{getValue:function(){return r},setValue:function(n){r=""+n},stopTracking:function(){n._valueTracker=null,delete n[t]}}}}function rn(n){n._valueTracker||(n._valueTracker=en(n))}function on(n){if(!n)return!1;var t=n._valueTracker;if(!t)return!0;var e=t.getValue(),r="";return n&&(r=tn(n)?n.checked?"true":"false":n.value),(n=r)!==e&&(t.setValue(n),!0)}function an(n){return null===n||"undefined"===typeof n?null:(n=Zo&&n[Zo]||n["@@iterator"],"function"===typeof n?n:null)}function un(n){var t=n.type;if("function"===typeof t)return t.displayName||t.name;if("string"===typeof t)return t;switch(t){case Go:return"AsyncMode";case Ko:return"Context.Consumer";case Wo:return"ReactFragment";case Vo:return"ReactPortal";case $o:return"Profiler("+n.pendingProps.id+")";case qo:return"Context.Provider";case Ho:return"StrictMode";case Yo:return"Timeout"}if("object"===typeof t&&null!==t)switch(t.$$typeof){case Xo:return n=t.render.displayName||t.render.name||"",""!==n?"ForwardRef("+n+")":"ForwardRef"}return null}function cn(n){var t="";do{n:switch(n.tag){case 0:case 1:case 2:case 5:var e=n._debugOwner,r=n._debugSource,o=un(n),a=null;e&&(a=un(e)),e=r,o="\n    in "+(o||"Unknown")+(e?" (at "+e.fileName.replace(/^.*[\\\/]/,"")+":"+e.lineNumber+")":a?" (created by "+a+")":"");break n;default:o=""}t+=o,n=n.return}while(n);return t}function fn(n){return!!na.call(ea,n)||!na.call(ta,n)&&(Jo.test(n)?ea[n]=!0:(ta[n]=!0,!1))}function dn(n,t,e,r){if(null!==e&&0===e.type)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":return!r&&(null!==e?!e.acceptsBooleans:"data-"!==(n=n.toLowerCase().slice(0,5))&&"aria-"!==n);default:return!1}}function mn(n,t,e,r){if(null===t||"undefined"===typeof t||dn(n,t,e,r))return!0;if(r)return!1;if(null!==e)switch(e.type){case 3:return!t;case 4:return!1===t;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}function ln(n,t,e,r,o){this.acceptsBooleans=2===t||3===t||4===t,this.attributeName=r,this.attributeNamespace=o,this.mustUseProperty=e,this.propertyName=n,this.type=t}function hn(n){return n[1].toUpperCase()}function sn(n,t,e,r){var o=ra.hasOwnProperty(t)?ra[t]:null;(null!==o?0===o.type:!r&&(2<t.length&&("o"===t[0]||"O"===t[0])&&("n"===t[1]||"N"===t[1])))||(mn(t,e,o,r)&&(e=null),r||null===o?fn(t)&&(null===e?n.removeAttribute(t):n.setAttribute(t,""+e)):o.mustUseProperty?n[o.propertyName]=null===e?3!==o.type&&"":e:(t=o.attributeName,r=o.attributeNamespace,null===e?n.removeAttribute(t):(o=o.type,e=3===o||4===o&&!0===e?"":""+e,r?n.setAttributeNS(r,t,e):n.setAttribute(t,e))))}function pn(n,t){var e=t.checked;return Dr({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:null!=e?e:n._wrapperState.initialChecked})}function Mn(n,t){var e=null==t.defaultValue?"":t.defaultValue,r=null!=t.checked?t.checked:t.defaultChecked;e=Cn(null!=t.value?t.value:e),n._wrapperState={initialChecked:r,initialValue:e,controlled:"checkbox"===t.type||"radio"===t.type?null!=t.checked:null!=t.value}}function vn(n,t){null!=(t=t.checked)&&sn(n,"checked",t,!1)}function Nn(n,t){vn(n,t);var e=Cn(t.value);null!=e&&("number"===t.type?(0===e&&""===n.value||n.value!=e)&&(n.value=""+e):n.value!==""+e&&(n.value=""+e)),t.hasOwnProperty("value")?xn(n,t.type,e):t.hasOwnProperty("defaultValue")&&xn(n,t.type,Cn(t.defaultValue)),null==t.checked&&null!=t.defaultChecked&&(n.defaultChecked=!!t.defaultChecked)}function yn(n,t,e){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){t=""+n._wrapperState.initialValue;var r=n.value;e||t===r||(n.value=t),n.defaultValue=t}e=n.name,""!==e&&(n.name=""),n.defaultChecked=!n.defaultChecked,n.defaultChecked=!n.defaultChecked,""!==e&&(n.name=e)}function xn(n,t,e){"number"===t&&n.ownerDocument.activeElement===n||(null==e?n.defaultValue=""+n._wrapperState.initialValue:n.defaultValue!==""+e&&(n.defaultValue=""+e))}function Cn(n){switch(typeof n){case"boolean":case"number":case"object":case"string":case"undefined":return n;default:return""}}function gn(n,t,e){return n=F.getPooled(aa.change,n,t,e),n.type="change",H(e),_(n),n}function bn(n){v(n,!1)}function Un(n){if(on(x(n)))return n}function Rn(n,t){if("change"===n)return t}function In(){ua&&(ua.detachEvent("onpropertychange",Qn),ia=ua=null)}function Qn(n){"value"===n.propertyName&&Un(ia)&&(n=gn(ia,n,J(n)),Y(bn,n))}function wn(n,t,e){"focus"===n?(In(),ua=t,ia=e,ua.attachEvent("onpropertychange",Qn)):"blur"===n&&In()}function _n(n){if("selectionchange"===n||"keyup"===n||"keydown"===n)return Un(ia)}function kn(n,t){if("click"===n)return Un(t)}function En(n,t){if("input"===n||"change"===n)return Un(t)}function Tn(n){var t=this.nativeEvent;return t.getModifierState?t.getModifierState(n):!!(n=ma[n])&&!!t[n]}function Sn(){return Tn}function Pn(n){var t=n;if(n.alternate)for(;t.return;)t=t.return;else{if(0!==(2&t.effectTag))return 1;for(;t.return;)if(t=t.return,0!==(2&t.effectTag))return 1}return 3===t.tag?2:3}function On(n){2!==Pn(n)&&r("188")}function Fn(n){var t=n.alternate;if(!t)return t=Pn(n),3===t&&r("188"),1===t?null:n;for(var e=n,o=t;;){var a=e.return,u=a?a.alternate:null;if(!a||!u)break;if(a.child===u.child){for(var i=a.child;i;){if(i===e)return On(a),n;if(i===o)return On(a),t;i=i.sibling}r("188")}if(e.return!==o.return)e=a,o=u;else{i=!1;for(var c=a.child;c;){if(c===e){i=!0,e=a,o=u;break}if(c===o){i=!0,o=a,e=u;break}c=c.sibling}if(!i){for(c=u.child;c;){if(c===e){i=!0,e=u,o=a;break}if(c===o){i=!0,o=u,e=a;break}c=c.sibling}i||r("189")}}e.alternate!==o&&r("190")}return 3!==e.tag&&r("188"),e.stateNode.current===e?n:t}function Dn(n){if(!(n=Fn(n)))return null;for(var t=n;;){if(5===t.tag||6===t.tag)return t;if(t.child)t.child.return=t,t=t.child;else{if(t===n)break;for(;!t.sibling;){if(!t.return||t.return===n)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}}return null}function An(n){if(!(n=Fn(n)))return null;for(var t=n;;){if(5===t.tag||6===t.tag)return t;if(t.child&&4!==t.tag)t.child.return=t,t=t.child;else{if(t===n)break;for(;!t.sibling;){if(!t.return||t.return===n)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}}return null}function jn(n){var t=n.keyCode;return"charCode"in n?0===(n=n.charCode)&&13===t&&(n=13):n=t,10===n&&(n=13),32<=n||13===n?n:0}function Ln(n,t){var e=n[0];n=n[1];var r="on"+(n[0].toUpperCase()+n.slice(1));t={phasedRegistrationNames:{bubbled:r,captured:r+"Capture"},dependencies:[e],isInteractive:t},Qa[n]=t,wa[e]=t}function zn(n){var t=n.targetInst;do{if(!t){n.ancestors.push(t);break}var e;for(e=t;e.return;)e=e.return;if(!(e=3!==e.tag?null:e.stateNode.containerInfo))break;n.ancestors.push(t),t=y(e)}while(t);for(e=0;e<n.ancestors.length;e++)t=n.ancestors[e],N(n.topLevelType,t,n.nativeEvent,J(n.nativeEvent))}function Bn(n){Ta=!!n}function Vn(n,t){if(!t)return null;var e=(ka(n)?Hn:$n).bind(null,n);t.addEventListener(n,e,!1)}function Wn(n,t){if(!t)return null;var e=(ka(n)?Hn:$n).bind(null,n);t.addEventListener(n,e,!0)}function Hn(n,t){G($n,n,t)}function $n(n,t){if(Ta){var e=J(t);if(e=y(e),null===e||"number"!==typeof e.tag||2===Pn(e)||(e=null),Ea.length){var r=Ea.pop();r.topLevelType=n,r.nativeEvent=t,r.targetInst=e,n=r}else n={topLevelType:n,nativeEvent:t,targetInst:e,ancestors:[]};try{Y(zn,n)}finally{n.topLevelType=null,n.nativeEvent=null,n.targetInst=null,n.ancestors.length=0,10>Ea.length&&Ea.push(n)}}}function qn(n){return Object.prototype.hasOwnProperty.call(n,Fa)||(n[Fa]=Oa++,Pa[n[Fa]]={}),Pa[n[Fa]]}function Kn(n){for(;n&&n.firstChild;)n=n.firstChild;return n}function Gn(n,t){var e=Kn(n);n=0;for(var r;e;){if(3===e.nodeType){if(r=n+e.textContent.length,n<=t&&r>=t)return{node:e,offset:t-n};n=r}n:{for(;e;){if(e.nextSibling){e=e.nextSibling;break n}e=e.parentNode}e=void 0}e=Kn(e)}}function Xn(n){var t=n&&n.nodeName&&n.nodeName.toLowerCase();return t&&("input"===t&&("text"===n.type||"search"===n.type||"tel"===n.type||"url"===n.type||"password"===n.type)||"textarea"===t||"true"===n.contentEditable)}function Yn(n,t){if(Ba||null==ja||ja!==jr())return null;var e=ja;return"selectionStart"in e&&Xn(e)?e={start:e.selectionStart,end:e.selectionEnd}:window.getSelection?(e=window.getSelection(),e={anchorNode:e.anchorNode,anchorOffset:e.anchorOffset,focusNode:e.focusNode,focusOffset:e.focusOffset}):e=void 0,za&&Lr(za,e)?null:(za=e,n=F.getPooled(Aa.select,La,n,t),n.type="select",n.target=ja,_(n),n)}function Zn(n){var t="";return Or.Children.forEach(n,function(n){null==n||"string"!==typeof n&&"number"!==typeof n||(t+=n)}),t}function Jn(n,t){return n=Dr({children:void 0},t),(t=Zn(t.children))&&(n.children=t),n}function nt(n,t,e,r){if(n=n.options,t){t={};for(var o=0;o<e.length;o++)t["$"+e[o]]=!0;for(e=0;e<n.length;e++)o=t.hasOwnProperty("$"+n[e].value),n[e].selected!==o&&(n[e].selected=o),o&&r&&(n[e].defaultSelected=!0)}else{for(e=""+e,t=null,o=0;o<n.length;o++){if(n[o].value===e)return n[o].selected=!0,void(r&&(n[o].defaultSelected=!0));null!==t||n[o].disabled||(t=n[o])}null!==t&&(t.selected=!0)}}function tt(n,t){var e=t.value;n._wrapperState={initialValue:null!=e?e:t.defaultValue,wasMultiple:!!t.multiple}}function et(n,t){return null!=t.dangerouslySetInnerHTML&&r("91"),Dr({},t,{value:void 0,defaultValue:void 0,children:""+n._wrapperState.initialValue})}function rt(n,t){var e=t.value;null==e&&(e=t.defaultValue,t=t.children,null!=t&&(null!=e&&r("92"),Array.isArray(t)&&(1>=t.length||r("93"),t=t[0]),e=""+t),null==e&&(e="")),n._wrapperState={initialValue:""+e}}function ot(n,t){var e=t.value;null!=e&&(e=""+e,e!==n.value&&(n.value=e),null==t.defaultValue&&(n.defaultValue=e)),null!=t.defaultValue&&(n.defaultValue=t.defaultValue)}function at(n){var t=n.textContent;t===n._wrapperState.initialValue&&(n.value=t)}function ut(n){switch(n){case"svg":return"http://www.w3.org/2000/svg";case"math":return"http://www.w3.org/1998/Math/MathML";default:return"http://www.w3.org/1999/xhtml"}}function it(n,t){return null==n||"http://www.w3.org/1999/xhtml"===n?ut(t):"http://www.w3.org/2000/svg"===n&&"foreignObject"===t?"http://www.w3.org/1999/xhtml":n}function ct(n,t){if(t){var e=n.firstChild;if(e&&e===n.lastChild&&3===e.nodeType)return void(e.nodeValue=t)}n.textContent=t}function ft(n,t){n=n.style;for(var e in t)if(t.hasOwnProperty(e)){var r=0===e.indexOf("--"),o=e,a=t[e];o=null==a||"boolean"===typeof a||""===a?"":r||"number"!==typeof a||0===a||pu.hasOwnProperty(o)&&pu[o]?(""+a).trim():a+"px","float"===e&&(e="cssFloat"),r?n.setProperty(e,o):n[e]=o}}function dt(n,t,e){t&&(vu[n]&&(null!=t.children||null!=t.dangerouslySetInnerHTML)&&r("137",n,e()),null!=t.dangerouslySetInnerHTML&&(null!=t.children&&r("60"),"object"===typeof t.dangerouslySetInnerHTML&&"__html"in t.dangerouslySetInnerHTML||r("61")),null!=t.style&&"object"!==typeof t.style&&r("62",e()))}function mt(n,t){if(-1===n.indexOf("-"))return"string"===typeof t.is;switch(n){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}function lt(n,t){n=9===n.nodeType||11===n.nodeType?n:n.ownerDocument;var e=qn(n);t=Gr[t];for(var r=0;r<t.length;r++){var o=t[r];if(!e.hasOwnProperty(o)||!e[o]){switch(o){case"scroll":Wn("scroll",n);break;case"focus":case"blur":Wn("focus",n),Wn("blur",n),e.blur=!0,e.focus=!0;break;case"cancel":case"close":nn(o,!0)&&Wn(o,n);break;case"invalid":case"submit":case"reset":break;default:-1===Mo.indexOf(o)&&Vn(o,n)}e[o]=!0}}}function ht(n,t,e,r){return e=9===e.nodeType?e:e.ownerDocument,r===lu.html&&(r=ut(n)),r===lu.html?"script"===n?(n=e.createElement("div"),n.innerHTML="<script><\/script>",n=n.removeChild(n.firstChild)):n="string"===typeof t.is?e.createElement(n,{is:t.is}):e.createElement(n):n=e.createElementNS(r,n),n}function st(n,t){return(9===t.nodeType?t:t.ownerDocument).createTextNode(n)}function pt(n,t,e,r){var o=mt(t,e);switch(t){case"iframe":case"object":Vn("load",n);var a=e;break;case"video":case"audio":for(a=0;a<Mo.length;a++)Vn(Mo[a],n);a=e;break;case"source":Vn("error",n),a=e;break;case"img":case"image":case"link":Vn("error",n),Vn("load",n),a=e;break;case"form":Vn("reset",n),Vn("submit",n),a=e;break;case"details":Vn("toggle",n),a=e;break;case"input":Mn(n,e),a=pn(n,e),Vn("invalid",n),lt(r,"onChange");break;case"option":a=Jn(n,e);break;case"select":tt(n,e),a=Dr({},e,{value:void 0}),Vn("invalid",n),lt(r,"onChange");break;case"textarea":rt(n,e),a=et(n,e),Vn("invalid",n),lt(r,"onChange");break;default:a=e}dt(t,a,Nu);var u,i=a;for(u in i)if(i.hasOwnProperty(u)){var c=i[u];"style"===u?ft(n,c,Nu):"dangerouslySetInnerHTML"===u?null!=(c=c?c.__html:void 0)&&su(n,c):"children"===u?"string"===typeof c?("textarea"!==t||""!==c)&&ct(n,c):"number"===typeof c&&ct(n,""+c):"suppressContentEditableWarning"!==u&&"suppressHydrationWarning"!==u&&"autoFocus"!==u&&(Kr.hasOwnProperty(u)?null!=c&&lt(r,u):null!=c&&sn(n,u,c,o))}switch(t){case"input":rn(n),yn(n,e,!1);break;case"textarea":rn(n),at(n,e);break;case"option":null!=e.value&&n.setAttribute("value",e.value);break;case"select":n.multiple=!!e.multiple,t=e.value,null!=t?nt(n,!!e.multiple,t,!1):null!=e.defaultValue&&nt(n,!!e.multiple,e.defaultValue,!0);break;default:"function"===typeof a.onClick&&(n.onclick=Ar)}}function Mt(n,t,e,r,o){var a=null;switch(t){case"input":e=pn(n,e),r=pn(n,r),a=[];break;case"option":e=Jn(n,e),r=Jn(n,r),a=[];break;case"select":e=Dr({},e,{value:void 0}),r=Dr({},r,{value:void 0}),a=[];break;case"textarea":e=et(n,e),r=et(n,r),a=[];break;default:"function"!==typeof e.onClick&&"function"===typeof r.onClick&&(n.onclick=Ar)}dt(t,r,Nu),t=n=void 0;var u=null;for(n in e)if(!r.hasOwnProperty(n)&&e.hasOwnProperty(n)&&null!=e[n])if("style"===n){var i=e[n];for(t in i)i.hasOwnProperty(t)&&(u||(u={}),u[t]="")}else"dangerouslySetInnerHTML"!==n&&"children"!==n&&"suppressContentEditableWarning"!==n&&"suppressHydrationWarning"!==n&&"autoFocus"!==n&&(Kr.hasOwnProperty(n)?a||(a=[]):(a=a||[]).push(n,null));for(n in r){var c=r[n];if(i=null!=e?e[n]:void 0,r.hasOwnProperty(n)&&c!==i&&(null!=c||null!=i))if("style"===n)if(i){for(t in i)!i.hasOwnProperty(t)||c&&c.hasOwnProperty(t)||(u||(u={}),u[t]="");for(t in c)c.hasOwnProperty(t)&&i[t]!==c[t]&&(u||(u={}),u[t]=c[t])}else u||(a||(a=[]),a.push(n,u)),u=c;else"dangerouslySetInnerHTML"===n?(c=c?c.__html:void 0,i=i?i.__html:void 0,null!=c&&i!==c&&(a=a||[]).push(n,""+c)):"children"===n?i===c||"string"!==typeof c&&"number"!==typeof c||(a=a||[]).push(n,""+c):"suppressContentEditableWarning"!==n&&"suppressHydrationWarning"!==n&&(Kr.hasOwnProperty(n)?(null!=c&&lt(o,n),a||i===c||(a=[])):(a=a||[]).push(n,c))}return u&&(a=a||[]).push("style",u),a}function vt(n,t,e,r,o){"input"===e&&"radio"===o.type&&null!=o.name&&vn(n,o),mt(e,r),r=mt(e,o);for(var a=0;a<t.length;a+=2){var u=t[a],i=t[a+1];"style"===u?ft(n,i,Nu):"dangerouslySetInnerHTML"===u?su(n,i):"children"===u?ct(n,i):sn(n,u,i,r)}switch(e){case"input":Nn(n,o);break;case"textarea":ot(n,o);break;case"select":n._wrapperState.initialValue=void 0,t=n._wrapperState.wasMultiple,n._wrapperState.wasMultiple=!!o.multiple,e=o.value,null!=e?nt(n,!!o.multiple,e,!1):t!==!!o.multiple&&(null!=o.defaultValue?nt(n,!!o.multiple,o.defaultValue,!0):nt(n,!!o.multiple,o.multiple?[]:"",!1))}}function Nt(n,t,e,r,o){switch(t){case"iframe":case"object":Vn("load",n);break;case"video":case"audio":for(r=0;r<Mo.length;r++)Vn(Mo[r],n);break;case"source":Vn("error",n);break;case"img":case"image":case"link":Vn("error",n),Vn("load",n);break;case"form":Vn("reset",n),Vn("submit",n);break;case"details":Vn("toggle",n);break;case"input":Mn(n,e),Vn("invalid",n),lt(o,"onChange");break;case"select":tt(n,e),Vn("invalid",n),lt(o,"onChange");break;case"textarea":rt(n,e),Vn("invalid",n),lt(o,"onChange")}dt(t,e,Nu),r=null;for(var a in e)if(e.hasOwnProperty(a)){var u=e[a];"children"===a?"string"===typeof u?n.textContent!==u&&(r=["children",u]):"number"===typeof u&&n.textContent!==""+u&&(r=["children",""+u]):Kr.hasOwnProperty(a)&&null!=u&&lt(o,a)}switch(t){case"input":rn(n),yn(n,e,!0);break;case"textarea":rn(n),at(n,e);break;case"select":case"option":break;default:"function"===typeof e.onClick&&(n.onclick=Ar)}return r}function yt(n,t){return n.nodeValue!==t}function xt(n,t){switch(n){case"button":case"input":case"select":case"textarea":return!!t.autoFocus}return!1}function Ct(n,t){return"textarea"===n||"string"===typeof t.children||"number"===typeof t.children||"object"===typeof t.dangerouslySetInnerHTML&&null!==t.dangerouslySetInnerHTML&&"string"===typeof t.dangerouslySetInnerHTML.__html}function gt(n){for(n=n.nextSibling;n&&1!==n.nodeType&&3!==n.nodeType;)n=n.nextSibling;return n}function bt(n){for(n=n.firstChild;n&&1!==n.nodeType&&3!==n.nodeType;)n=n.nextSibling;return n}function Ut(n){return{current:n}}function Rt(n){0>Iu||(n.current=Ru[Iu],Ru[Iu]=null,Iu--)}function It(n,t){Iu++,Ru[Iu]=n.current,n.current=t}function Qt(n){return _t(n)?_u:Qu.current}function wt(n,t){var e=n.type.contextTypes;if(!e)return Br;var r=n.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===t)return r.__reactInternalMemoizedMaskedChildContext;var o,a={};for(o in e)a[o]=t[o];return r&&(n=n.stateNode,n.__reactInternalMemoizedUnmaskedChildContext=t,n.__reactInternalMemoizedMaskedChildContext=a),a}function _t(n){return 2===n.tag&&null!=n.type.childContextTypes}function kt(n){_t(n)&&(Rt(wu,n),Rt(Qu,n))}function Et(n){Rt(wu,n),Rt(Qu,n)}function Tt(n,t,e){Qu.current!==Br&&r("168"),It(Qu,t,n),It(wu,e,n)}function St(n,t){var e=n.stateNode,o=n.type.childContextTypes;if("function"!==typeof e.getChildContext)return t;e=e.getChildContext();for(var a in e)a in o||r("108",un(n)||"Unknown",a);return Dr({},t,e)}function Pt(n){if(!_t(n))return!1;var t=n.stateNode;return t=t&&t.__reactInternalMemoizedMergedChildContext||Br,_u=Qu.current,It(Qu,t,n),It(wu,wu.current,n),!0}function Ot(n,t){var e=n.stateNode;if(e||r("169"),t){var o=St(n,_u);e.__reactInternalMemoizedMergedChildContext=o,Rt(wu,n),Rt(Qu,n),It(Qu,o,n)}else Rt(wu,n);It(wu,t,n)}function Ft(n,t,e,r){this.tag=n,this.key=e,this.sibling=this.child=this.return=this.stateNode=this.type=null,this.index=0,this.ref=null,this.pendingProps=t,this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.effectTag=0,this.lastEffect=this.firstEffect=this.nextEffect=null,this.expirationTime=0,this.alternate=null}function Dt(n,t,e){var r=n.alternate;return null===r?(r=new Ft(n.tag,t,n.key,n.mode),r.type=n.type,r.stateNode=n.stateNode,r.alternate=n,n.alternate=r):(r.pendingProps=t,r.effectTag=0,r.nextEffect=null,r.firstEffect=null,r.lastEffect=null),r.expirationTime=e,r.child=n.child,r.memoizedProps=n.memoizedProps,r.memoizedState=n.memoizedState,r.updateQueue=n.updateQueue,r.sibling=n.sibling,r.index=n.index,r.ref=n.ref,r}function At(n,t,e){var o=n.type,a=n.key;if(n=n.props,"function"===typeof o)var u=o.prototype&&o.prototype.isReactComponent?2:0;else if("string"===typeof o)u=5;else switch(o){case Wo:return jt(n.children,t,e,a);case Go:u=11,t|=3;break;case Ho:u=11,t|=2;break;case $o:return o=new Ft(15,n,a,4|t),o.type=$o,o.expirationTime=e,o;case Yo:u=16,t|=2;break;default:n:{switch("object"===typeof o&&null!==o?o.$$typeof:null){case qo:u=13;break n;case Ko:u=12;break n;case Xo:u=14;break n;default:r("130",null==o?o:typeof o,"")}u=void 0}}return t=new Ft(u,n,a,t),t.type=o,t.expirationTime=e,t}function jt(n,t,e,r){return n=new Ft(10,n,r,t),n.expirationTime=e,n}function Lt(n,t,e){return n=new Ft(6,n,null,t),n.expirationTime=e,n}function zt(n,t,e){return t=new Ft(4,null!==n.children?n.children:[],n.key,t),t.expirationTime=e,t.stateNode={containerInfo:n.containerInfo,pendingChildren:null,implementation:n.implementation},t}function Bt(n,t,e){return t=new Ft(3,null,null,t?3:0),n={current:t,containerInfo:n,pendingChildren:null,earliestPendingTime:0,latestPendingTime:0,earliestSuspendedTime:0,latestSuspendedTime:0,latestPingedTime:0,pendingCommitExpirationTime:0,finishedWork:null,context:null,pendingContext:null,hydrate:e,remainingExpirationTime:0,firstBatch:null,nextScheduledRoot:null},t.stateNode=n}function Vt(n){return function(t){try{return n(t)}catch(n){}}}function Wt(n){if("undefined"===typeof __REACT_DEVTOOLS_GLOBAL_HOOK__)return!1;var t=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(t.isDisabled||!t.supportsFiber)return!0;try{var e=t.inject(n);ku=Vt(function(n){return t.onCommitFiberRoot(e,n)}),Eu=Vt(function(n){return t.onCommitFiberUnmount(e,n)})}catch(n){}return!0}function Ht(n){"function"===typeof ku&&ku(n)}function $t(n){"function"===typeof Eu&&Eu(n)}function qt(n){return{expirationTime:0,baseState:n,firstUpdate:null,lastUpdate:null,firstCapturedUpdate:null,lastCapturedUpdate:null,firstEffect:null,lastEffect:null,firstCapturedEffect:null,lastCapturedEffect:null}}function Kt(n){return{expirationTime:n.expirationTime,baseState:n.baseState,firstUpdate:n.firstUpdate,lastUpdate:n.lastUpdate,firstCapturedUpdate:null,lastCapturedUpdate:null,firstEffect:null,lastEffect:null,firstCapturedEffect:null,lastCapturedEffect:null}}function Gt(n){return{expirationTime:n,tag:0,payload:null,callback:null,next:null,nextEffect:null}}function Xt(n,t,e){null===n.lastUpdate?n.firstUpdate=n.lastUpdate=t:(n.lastUpdate.next=t,n.lastUpdate=t),(0===n.expirationTime||n.expirationTime>e)&&(n.expirationTime=e)}function Yt(n,t,e){var r=n.alternate;if(null===r){var o=n.updateQueue,a=null;null===o&&(o=n.updateQueue=qt(n.memoizedState))}else o=n.updateQueue,a=r.updateQueue,null===o?null===a?(o=n.updateQueue=qt(n.memoizedState),a=r.updateQueue=qt(r.memoizedState)):o=n.updateQueue=Kt(a):null===a&&(a=r.updateQueue=Kt(o));null===a||o===a?Xt(o,t,e):null===o.lastUpdate||null===a.lastUpdate?(Xt(o,t,e),Xt(a,t,e)):(Xt(o,t,e),a.lastUpdate=t)}function Zt(n,t,e){var r=n.updateQueue;r=null===r?n.updateQueue=qt(n.memoizedState):Jt(n,r),null===r.lastCapturedUpdate?r.firstCapturedUpdate=r.lastCapturedUpdate=t:(r.lastCapturedUpdate.next=t,r.lastCapturedUpdate=t),(0===r.expirationTime||r.expirationTime>e)&&(r.expirationTime=e)}function Jt(n,t){var e=n.alternate;return null!==e&&t===e.updateQueue&&(t=n.updateQueue=Kt(t)),t}function ne(n,t,e,r,o,a){switch(e.tag){case 1:return n=e.payload,"function"===typeof n?n.call(a,r,o):n;case 3:n.effectTag=-1025&n.effectTag|64;case 0:if(n=e.payload,null===(o="function"===typeof n?n.call(a,r,o):n)||void 0===o)break;return Dr({},r,o);case 2:Tu=!0}return r}function te(n,t,e,r,o){if(Tu=!1,!(0===t.expirationTime||t.expirationTime>o)){t=Jt(n,t);for(var a=t.baseState,u=null,i=0,c=t.firstUpdate,f=a;null!==c;){var d=c.expirationTime;d>o?(null===u&&(u=c,a=f),(0===i||i>d)&&(i=d)):(f=ne(n,t,c,f,e,r),null!==c.callback&&(n.effectTag|=32,c.nextEffect=null,null===t.lastEffect?t.firstEffect=t.lastEffect=c:(t.lastEffect.nextEffect=c,t.lastEffect=c))),c=c.next}for(d=null,c=t.firstCapturedUpdate;null!==c;){var m=c.expirationTime;m>o?(null===d&&(d=c,null===u&&(a=f)),(0===i||i>m)&&(i=m)):(f=ne(n,t,c,f,e,r),null!==c.callback&&(n.effectTag|=32,c.nextEffect=null,null===t.lastCapturedEffect?t.firstCapturedEffect=t.lastCapturedEffect=c:(t.lastCapturedEffect.nextEffect=c,t.lastCapturedEffect=c))),c=c.next}null===u&&(t.lastUpdate=null),null===d?t.lastCapturedUpdate=null:n.effectTag|=32,null===u&&null===d&&(a=f),t.baseState=a,t.firstUpdate=u,t.firstCapturedUpdate=d,t.expirationTime=i,n.memoizedState=f}}function ee(n,t){"function"!==typeof n&&r("191",n),n.call(t)}function re(n,t,e){for(null!==t.firstCapturedUpdate&&(null!==t.lastUpdate&&(t.lastUpdate.next=t.firstCapturedUpdate,t.lastUpdate=t.lastCapturedUpdate),t.firstCapturedUpdate=t.lastCapturedUpdate=null),n=t.firstEffect,t.firstEffect=t.lastEffect=null;null!==n;){var r=n.callback;null!==r&&(n.callback=null,ee(r,e)),n=n.nextEffect}for(n=t.firstCapturedEffect,t.firstCapturedEffect=t.lastCapturedEffect=null;null!==n;)t=n.callback,null!==t&&(n.callback=null,ee(t,e)),n=n.nextEffect}function oe(n,t){return{value:n,source:t,stack:cn(t)}}function ae(n){var t=n.type._context;It(Ou,t._changedBits,n),It(Pu,t._currentValue,n),It(Su,n,n),t._currentValue=n.pendingProps.value,t._changedBits=n.stateNode}function ue(n){var t=Ou.current,e=Pu.current;Rt(Su,n),Rt(Pu,n),Rt(Ou,n),n=n.type._context,n._currentValue=e,n._changedBits=t}function ie(n){return n===Fu&&r("174"),n}function ce(n,t){It(ju,t,n),It(Au,n,n),It(Du,Fu,n);var e=t.nodeType;switch(e){case 9:case 11:t=(t=t.documentElement)?t.namespaceURI:it(null,"");break;default:e=8===e?t.parentNode:t,t=e.namespaceURI||null,e=e.tagName,t=it(t,e)}Rt(Du,n),It(Du,t,n)}function fe(n){Rt(Du,n),Rt(Au,n),Rt(ju,n)}function de(n){Au.current===n&&(Rt(Du,n),Rt(Au,n))}function me(n,t,e){var r=n.memoizedState;t=t(e,r),r=null===t||void 0===t?r:Dr({},r,t),n.memoizedState=r,null!==(n=n.updateQueue)&&0===n.expirationTime&&(n.baseState=r)}function le(n,t,e,r,o,a){var u=n.stateNode;return n=n.type,"function"===typeof u.shouldComponentUpdate?u.shouldComponentUpdate(e,o,a):!n.prototype||!n.prototype.isPureReactComponent||(!Lr(t,e)||!Lr(r,o))}function he(n,t,e,r){n=t.state,"function"===typeof t.componentWillReceiveProps&&t.componentWillReceiveProps(e,r),"function"===typeof t.UNSAFE_componentWillReceiveProps&&t.UNSAFE_componentWillReceiveProps(e,r),t.state!==n&&Lu.enqueueReplaceState(t,t.state,null)}function se(n,t){var e=n.type,r=n.stateNode,o=n.pendingProps,a=Qt(n);r.props=o,r.state=n.memoizedState,r.refs=Br,r.context=wt(n,a),a=n.updateQueue,null!==a&&(te(n,a,o,r,t),r.state=n.memoizedState),a=n.type.getDerivedStateFromProps,"function"===typeof a&&(me(n,a,o),r.state=n.memoizedState),"function"===typeof e.getDerivedStateFromProps||"function"===typeof r.getSnapshotBeforeUpdate||"function"!==typeof r.UNSAFE_componentWillMount&&"function"!==typeof r.componentWillMount||(e=r.state,"function"===typeof r.componentWillMount&&r.componentWillMount(),"function"===typeof r.UNSAFE_componentWillMount&&r.UNSAFE_componentWillMount(),e!==r.state&&Lu.enqueueReplaceState(r,r.state,null),null!==(a=n.updateQueue)&&(te(n,a,o,r,t),r.state=n.memoizedState)),"function"===typeof r.componentDidMount&&(n.effectTag|=4)}function pe(n,t,e){if(null!==(n=e.ref)&&"function"!==typeof n&&"object"!==typeof n){if(e._owner){e=e._owner;var o=void 0;e&&(2!==e.tag&&r("110"),o=e.stateNode),o||r("147",n);var a=""+n;return null!==t&&null!==t.ref&&"function"===typeof t.ref&&t.ref._stringRef===a?t.ref:(t=function(n){var t=o.refs===Br?o.refs={}:o.refs;null===n?delete t[a]:t[a]=n},t._stringRef=a,t)}"string"!==typeof n&&r("148"),e._owner||r("254",n)}return n}function Me(n,t){"textarea"!==n.type&&r("31","[object Object]"===Object.prototype.toString.call(t)?"object with keys {"+Object.keys(t).join(", ")+"}":t,"")}function ve(n){function t(t,e){if(n){var r=t.lastEffect;null!==r?(r.nextEffect=e,t.lastEffect=e):t.firstEffect=t.lastEffect=e,e.nextEffect=null,e.effectTag=8}}function e(e,r){if(!n)return null;for(;null!==r;)t(e,r),r=r.sibling;return null}function o(n,t){for(n=new Map;null!==t;)null!==t.key?n.set(t.key,t):n.set(t.index,t),t=t.sibling;return n}function a(n,t,e){return n=Dt(n,t,e),n.index=0,n.sibling=null,n}function u(t,e,r){return t.index=r,n?null!==(r=t.alternate)?(r=r.index,r<e?(t.effectTag=2,e):r):(t.effectTag=2,e):e}function i(t){return n&&null===t.alternate&&(t.effectTag=2),t}function c(n,t,e,r){return null===t||6!==t.tag?(t=Lt(e,n.mode,r),t.return=n,t):(t=a(t,e,r),t.return=n,t)}function f(n,t,e,r){return null!==t&&t.type===e.type?(r=a(t,e.props,r),r.ref=pe(n,t,e),r.return=n,r):(r=At(e,n.mode,r),r.ref=pe(n,t,e),r.return=n,r)}function d(n,t,e,r){return null===t||4!==t.tag||t.stateNode.containerInfo!==e.containerInfo||t.stateNode.implementation!==e.implementation?(t=zt(e,n.mode,r),t.return=n,t):(t=a(t,e.children||[],r),t.return=n,t)}function m(n,t,e,r,o){return null===t||10!==t.tag?(t=jt(e,n.mode,r,o),t.return=n,t):(t=a(t,e,r),t.return=n,t)}function l(n,t,e){if("string"===typeof t||"number"===typeof t)return t=Lt(""+t,n.mode,e),t.return=n,t;if("object"===typeof t&&null!==t){switch(t.$$typeof){case Bo:return e=At(t,n.mode,e),e.ref=pe(n,null,t),e.return=n,e;case Vo:return t=zt(t,n.mode,e),t.return=n,t}if(zu(t)||an(t))return t=jt(t,n.mode,e,null),t.return=n,t;Me(n,t)}return null}function h(n,t,e,r){var o=null!==t?t.key:null;if("string"===typeof e||"number"===typeof e)return null!==o?null:c(n,t,""+e,r);if("object"===typeof e&&null!==e){switch(e.$$typeof){case Bo:return e.key===o?e.type===Wo?m(n,t,e.props.children,r,o):f(n,t,e,r):null;case Vo:return e.key===o?d(n,t,e,r):null}if(zu(e)||an(e))return null!==o?null:m(n,t,e,r,null);Me(n,e)}return null}function s(n,t,e,r,o){if("string"===typeof r||"number"===typeof r)return n=n.get(e)||null,c(t,n,""+r,o);if("object"===typeof r&&null!==r){switch(r.$$typeof){case Bo:return n=n.get(null===r.key?e:r.key)||null,r.type===Wo?m(t,n,r.props.children,o,r.key):f(t,n,r,o);case Vo:return n=n.get(null===r.key?e:r.key)||null,d(t,n,r,o)}if(zu(r)||an(r))return n=n.get(e)||null,m(t,n,r,o,null);Me(t,r)}return null}function p(r,a,i,c){for(var f=null,d=null,m=a,p=a=0,M=null;null!==m&&p<i.length;p++){m.index>p?(M=m,m=null):M=m.sibling;var v=h(r,m,i[p],c);if(null===v){null===m&&(m=M);break}n&&m&&null===v.alternate&&t(r,m),a=u(v,a,p),null===d?f=v:d.sibling=v,d=v,m=M}if(p===i.length)return e(r,m),f;if(null===m){for(;p<i.length;p++)(m=l(r,i[p],c))&&(a=u(m,a,p),null===d?f=m:d.sibling=m,d=m);return f}for(m=o(r,m);p<i.length;p++)(M=s(m,r,p,i[p],c))&&(n&&null!==M.alternate&&m.delete(null===M.key?p:M.key),a=u(M,a,p),null===d?f=M:d.sibling=M,d=M);return n&&m.forEach(function(n){return t(r,n)}),f}function M(a,i,c,f){var d=an(c);"function"!==typeof d&&r("150"),null==(c=d.call(c))&&r("151");for(var m=d=null,p=i,M=i=0,v=null,N=c.next();null!==p&&!N.done;M++,N=c.next()){p.index>M?(v=p,p=null):v=p.sibling;var y=h(a,p,N.value,f);if(null===y){p||(p=v);break}n&&p&&null===y.alternate&&t(a,p),i=u(y,i,M),null===m?d=y:m.sibling=y,m=y,p=v}if(N.done)return e(a,p),d;if(null===p){for(;!N.done;M++,N=c.next())null!==(N=l(a,N.value,f))&&(i=u(N,i,M),null===m?d=N:m.sibling=N,m=N);return d}for(p=o(a,p);!N.done;M++,N=c.next())null!==(N=s(p,a,M,N.value,f))&&(n&&null!==N.alternate&&p.delete(null===N.key?M:N.key),i=u(N,i,M),null===m?d=N:m.sibling=N,m=N);return n&&p.forEach(function(n){return t(a,n)}),d}return function(n,o,u,c){var f="object"===typeof u&&null!==u&&u.type===Wo&&null===u.key;f&&(u=u.props.children);var d="object"===typeof u&&null!==u;if(d)switch(u.$$typeof){case Bo:n:{for(d=u.key,f=o;null!==f;){if(f.key===d){if(10===f.tag?u.type===Wo:f.type===u.type){e(n,f.sibling),o=a(f,u.type===Wo?u.props.children:u.props,c),o.ref=pe(n,f,u),o.return=n,n=o;break n}e(n,f);break}t(n,f),f=f.sibling}u.type===Wo?(o=jt(u.props.children,n.mode,c,u.key),o.return=n,n=o):(c=At(u,n.mode,c),c.ref=pe(n,o,u),c.return=n,n=c)}return i(n);case Vo:n:{for(f=u.key;null!==o;){if(o.key===f){if(4===o.tag&&o.stateNode.containerInfo===u.containerInfo&&o.stateNode.implementation===u.implementation){e(n,o.sibling),o=a(o,u.children||[],c),o.return=n,n=o;break n}e(n,o);break}t(n,o),o=o.sibling}o=zt(u,n.mode,c),o.return=n,n=o}return i(n)}if("string"===typeof u||"number"===typeof u)return u=""+u,null!==o&&6===o.tag?(e(n,o.sibling),o=a(o,u,c),o.return=n,n=o):(e(n,o),o=Lt(u,n.mode,c),o.return=n,n=o),i(n);if(zu(u))return p(n,o,u,c);if(an(u))return M(n,o,u,c);if(d&&Me(n,u),"undefined"===typeof u&&!f)switch(n.tag){case 2:case 1:c=n.type,r("152",c.displayName||c.name||"Component")}return e(n,o)}}function Ne(n,t){var e=new Ft(5,null,null,0);e.type="DELETED",e.stateNode=t,e.return=n,e.effectTag=8,null!==n.lastEffect?(n.lastEffect.nextEffect=e,n.lastEffect=e):n.firstEffect=n.lastEffect=e}function ye(n,t){switch(n.tag){case 5:var e=n.type;return null!==(t=1!==t.nodeType||e.toLowerCase()!==t.nodeName.toLowerCase()?null:t)&&(n.stateNode=t,!0);case 6:return null!==(t=""===n.pendingProps||3!==t.nodeType?null:t)&&(n.stateNode=t,!0);default:return!1}}function xe(n){if($u){var t=Hu;if(t){var e=t;if(!ye(n,t)){if(!(t=gt(e))||!ye(n,t))return n.effectTag|=2,$u=!1,void(Wu=n);Ne(Wu,e)}Wu=n,Hu=bt(t)}else n.effectTag|=2,$u=!1,Wu=n}}function Ce(n){for(n=n.return;null!==n&&5!==n.tag&&3!==n.tag;)n=n.return;Wu=n}function ge(n){if(n!==Wu)return!1;if(!$u)return Ce(n),$u=!0,!1;var t=n.type;if(5!==n.tag||"head"!==t&&"body"!==t&&!Ct(t,n.memoizedProps))for(t=Hu;t;)Ne(n,t),t=gt(t);return Ce(n),Hu=Wu?gt(n.stateNode):null,!0}function be(){Hu=Wu=null,$u=!1}function Ue(n,t,e){Re(n,t,e,t.expirationTime)}function Re(n,t,e,r){t.child=null===n?Vu(t,null,e,r):Bu(t,n.child,e,r)}function Ie(n,t){var e=t.ref;(null===n&&null!==e||null!==n&&n.ref!==e)&&(t.effectTag|=128)}function Qe(n,t,e,r,o){Ie(n,t);var a=0!==(64&t.effectTag);if(!e&&!a)return r&&Ot(t,!1),Ee(n,t);e=t.stateNode,Lo.current=t;var u=a?null:e.render();return t.effectTag|=1,a&&(Re(n,t,null,o),t.child=null),Re(n,t,u,o),t.memoizedState=e.state,t.memoizedProps=e.props,r&&Ot(t,!0),t.child}function we(n){var t=n.stateNode;t.pendingContext?Tt(n,t.pendingContext,t.pendingContext!==t.context):t.context&&Tt(n,t.context,!1),ce(n,t.containerInfo)}function _e(n,t,e,r){var o=n.child;for(null!==o&&(o.return=n);null!==o;){switch(o.tag){case 12:var a=0|o.stateNode;if(o.type===t&&0!==(a&e)){for(a=o;null!==a;){var u=a.alternate;if(0===a.expirationTime||a.expirationTime>r)a.expirationTime=r,null!==u&&(0===u.expirationTime||u.expirationTime>r)&&(u.expirationTime=r);else{if(null===u||!(0===u.expirationTime||u.expirationTime>r))break;u.expirationTime=r}a=a.return}a=null}else a=o.child;break;case 13:a=o.type===n.type?null:o.child;break;default:a=o.child}if(null!==a)a.return=o;else for(a=o;null!==a;){if(a===n){a=null;break}if(null!==(o=a.sibling)){o.return=a.return,a=o;break}a=a.return}o=a}}function ke(n,t,e){var r=t.type._context,o=t.pendingProps,a=t.memoizedProps,u=!0;if(wu.current)u=!1;else if(a===o)return t.stateNode=0,ae(t),Ee(n,t);var i=o.value;if(t.memoizedProps=o,null===a)i=1073741823;else if(a.value===o.value){if(a.children===o.children&&u)return t.stateNode=0,ae(t),Ee(n,t);i=0}else{var c=a.value;if(c===i&&(0!==c||1/c===1/i)||c!==c&&i!==i){if(a.children===o.children&&u)return t.stateNode=0,ae(t),Ee(n,t);i=0}else if(i="function"===typeof r._calculateChangedBits?r._calculateChangedBits(c,i):1073741823,0===(i|=0)){if(a.children===o.children&&u)return t.stateNode=0,ae(t),Ee(n,t)}else _e(t,r,i,e)}return t.stateNode=i,ae(t),Ue(n,t,o.children),t.child}function Ee(n,t){if(null!==n&&t.child!==n.child&&r("153"),null!==t.child){n=t.child;var e=Dt(n,n.pendingProps,n.expirationTime);for(t.child=e,e.return=t;null!==n.sibling;)n=n.sibling,e=e.sibling=Dt(n,n.pendingProps,n.expirationTime),e.return=t;e.sibling=null}return t.child}function Te(n,t,e){if(0===t.expirationTime||t.expirationTime>e){switch(t.tag){case 3:we(t);break;case 2:Pt(t);break;case 4:ce(t,t.stateNode.containerInfo);break;case 13:ae(t)}return null}switch(t.tag){case 0:null!==n&&r("155");var o=t.type,a=t.pendingProps,u=Qt(t);return u=wt(t,u),o=o(a,u),t.effectTag|=1,"object"===typeof o&&null!==o&&"function"===typeof o.render&&void 0===o.$$typeof?(u=t.type,t.tag=2,t.memoizedState=null!==o.state&&void 0!==o.state?o.state:null,u=u.getDerivedStateFromProps,"function"===typeof u&&me(t,u,a),a=Pt(t),o.updater=Lu,t.stateNode=o,o._reactInternalFiber=t,se(t,e),n=Qe(n,t,!0,a,e)):(t.tag=1,Ue(n,t,o),t.memoizedProps=a,n=t.child),n;case 1:return a=t.type,e=t.pendingProps,wu.current||t.memoizedProps!==e?(o=Qt(t),o=wt(t,o),a=a(e,o),t.effectTag|=1,Ue(n,t,a),t.memoizedProps=e,n=t.child):n=Ee(n,t),n;case 2:if(a=Pt(t),null===n)if(null===t.stateNode){var i=t.pendingProps,c=t.type;o=Qt(t);var f=2===t.tag&&null!=t.type.contextTypes;u=f?wt(t,o):Br,i=new c(i,u),t.memoizedState=null!==i.state&&void 0!==i.state?i.state:null,i.updater=Lu,t.stateNode=i,i._reactInternalFiber=t,f&&(f=t.stateNode,f.__reactInternalMemoizedUnmaskedChildContext=o,f.__reactInternalMemoizedMaskedChildContext=u),se(t,e),o=!0}else{c=t.type,o=t.stateNode,f=t.memoizedProps,u=t.pendingProps,o.props=f;var d=o.context;i=Qt(t),i=wt(t,i);var m=c.getDerivedStateFromProps;(c="function"===typeof m||"function"===typeof o.getSnapshotBeforeUpdate)||"function"!==typeof o.UNSAFE_componentWillReceiveProps&&"function"!==typeof o.componentWillReceiveProps||(f!==u||d!==i)&&he(t,o,u,i),Tu=!1;var l=t.memoizedState;d=o.state=l;var h=t.updateQueue;null!==h&&(te(t,h,u,o,e),d=t.memoizedState),f!==u||l!==d||wu.current||Tu?("function"===typeof m&&(me(t,m,u),d=t.memoizedState),(f=Tu||le(t,f,u,l,d,i))?(c||"function"!==typeof o.UNSAFE_componentWillMount&&"function"!==typeof o.componentWillMount||("function"===typeof o.componentWillMount&&o.componentWillMount(),"function"===typeof o.UNSAFE_componentWillMount&&o.UNSAFE_componentWillMount()),"function"===typeof o.componentDidMount&&(t.effectTag|=4)):("function"===typeof o.componentDidMount&&(t.effectTag|=4),t.memoizedProps=u,t.memoizedState=d),o.props=u,o.state=d,o.context=i,o=f):("function"===typeof o.componentDidMount&&(t.effectTag|=4),o=!1)}else c=t.type,o=t.stateNode,u=t.memoizedProps,f=t.pendingProps,o.props=u,d=o.context,i=Qt(t),i=wt(t,i),m=c.getDerivedStateFromProps,(c="function"===typeof m||"function"===typeof o.getSnapshotBeforeUpdate)||"function"!==typeof o.UNSAFE_componentWillReceiveProps&&"function"!==typeof o.componentWillReceiveProps||(u!==f||d!==i)&&he(t,o,f,i),Tu=!1,d=t.memoizedState,l=o.state=d,h=t.updateQueue,null!==h&&(te(t,h,f,o,e),l=t.memoizedState),u!==f||d!==l||wu.current||Tu?("function"===typeof m&&(me(t,m,f),l=t.memoizedState),(m=Tu||le(t,u,f,d,l,i))?(c||"function"!==typeof o.UNSAFE_componentWillUpdate&&"function"!==typeof o.componentWillUpdate||("function"===typeof o.componentWillUpdate&&o.componentWillUpdate(f,l,i),"function"===typeof o.UNSAFE_componentWillUpdate&&o.UNSAFE_componentWillUpdate(f,l,i)),"function"===typeof o.componentDidUpdate&&(t.effectTag|=4),"function"===typeof o.getSnapshotBeforeUpdate&&(t.effectTag|=256)):("function"!==typeof o.componentDidUpdate||u===n.memoizedProps&&d===n.memoizedState||(t.effectTag|=4),"function"!==typeof o.getSnapshotBeforeUpdate||u===n.memoizedProps&&d===n.memoizedState||(t.effectTag|=256),t.memoizedProps=f,t.memoizedState=l),o.props=f,o.state=l,o.context=i,o=m):("function"!==typeof o.componentDidUpdate||u===n.memoizedProps&&d===n.memoizedState||(t.effectTag|=4),"function"!==typeof o.getSnapshotBeforeUpdate||u===n.memoizedProps&&d===n.memoizedState||(t.effectTag|=256),o=!1);return Qe(n,t,o,a,e);case 3:return we(t),a=t.updateQueue,null!==a?(o=t.memoizedState,o=null!==o?o.element:null,te(t,a,t.pendingProps,null,e),(a=t.memoizedState.element)===o?(be(),n=Ee(n,t)):(o=t.stateNode,(o=(null===n||null===n.child)&&o.hydrate)&&(Hu=bt(t.stateNode.containerInfo),Wu=t,o=$u=!0),o?(t.effectTag|=2,t.child=Vu(t,null,a,e)):(be(),Ue(n,t,a)),n=t.child)):(be(),n=Ee(n,t)),n;case 5:return ie(ju.current),a=ie(Du.current),o=it(a,t.type),a!==o&&(It(Au,t,t),It(Du,o,t)),null===n&&xe(t),a=t.type,f=t.memoizedProps,o=t.pendingProps,u=null!==n?n.memoizedProps:null,wu.current||f!==o||((f=1&t.mode&&!!o.hidden)&&(t.expirationTime=1073741823),f&&1073741823===e)?(f=o.children,Ct(a,o)?f=null:u&&Ct(a,u)&&(t.effectTag|=16),Ie(n,t),1073741823!==e&&1&t.mode&&o.hidden?(t.expirationTime=1073741823,t.memoizedProps=o,n=null):(Ue(n,t,f),t.memoizedProps=o,n=t.child)):n=Ee(n,t),n;case 6:return null===n&&xe(t),t.memoizedProps=t.pendingProps,null;case 16:return null;case 4:return ce(t,t.stateNode.containerInfo),a=t.pendingProps,wu.current||t.memoizedProps!==a?(null===n?t.child=Bu(t,null,a,e):Ue(n,t,a),t.memoizedProps=a,n=t.child):n=Ee(n,t),n;case 14:return a=t.type.render,e=t.pendingProps,o=t.ref,wu.current||t.memoizedProps!==e||o!==(null!==n?n.ref:null)?(a=a(e,o),Ue(n,t,a),t.memoizedProps=e,n=t.child):n=Ee(n,t),n;case 10:return e=t.pendingProps,wu.current||t.memoizedProps!==e?(Ue(n,t,e),t.memoizedProps=e,n=t.child):n=Ee(n,t),n;case 11:return e=t.pendingProps.children,wu.current||null!==e&&t.memoizedProps!==e?(Ue(n,t,e),t.memoizedProps=e,n=t.child):n=Ee(n,t),n;case 15:return e=t.pendingProps,t.memoizedProps===e?n=Ee(n,t):(Ue(n,t,e.children),t.memoizedProps=e,n=t.child),n;case 13:return ke(n,t,e);case 12:n:if(o=t.type,u=t.pendingProps,f=t.memoizedProps,a=o._currentValue,i=o._changedBits,wu.current||0!==i||f!==u){if(t.memoizedProps=u,c=u.unstable_observedBits,void 0!==c&&null!==c||(c=1073741823),t.stateNode=c,0!==(i&c))_e(t,o,i,e);else if(f===u){n=Ee(n,t);break n}e=u.children,e=e(a),t.effectTag|=1,Ue(n,t,e),n=t.child}else n=Ee(n,t);return n;default:r("156")}}function Se(n){n.effectTag|=4}function Pe(n,t){var e=t.pendingProps;switch(t.tag){case 1:return null;case 2:return kt(t),null;case 3:fe(t),Et(t);var o=t.stateNode;return o.pendingContext&&(o.context=o.pendingContext,o.pendingContext=null),null!==n&&null!==n.child||(ge(t),t.effectTag&=-3),qu(t),null;case 5:de(t),o=ie(ju.current);var a=t.type;if(null!==n&&null!=t.stateNode){var u=n.memoizedProps,i=t.stateNode,c=ie(Du.current);i=Mt(i,a,u,e,o),Ku(n,t,i,a,u,e,o,c),n.ref!==t.ref&&(t.effectTag|=128)}else{if(!e)return null===t.stateNode&&r("166"),null;if(n=ie(Du.current),ge(t))e=t.stateNode,a=t.type,u=t.memoizedProps,e[oo]=t,e[ao]=u,o=Nt(e,a,u,n,o),t.updateQueue=o,null!==o&&Se(t);else{n=ht(a,e,o,n),n[oo]=t,n[ao]=e;n:for(u=t.child;null!==u;){if(5===u.tag||6===u.tag)n.appendChild(u.stateNode);else if(4!==u.tag&&null!==u.child){u.child.return=u,u=u.child;continue}if(u===t)break;for(;null===u.sibling;){if(null===u.return||u.return===t)break n;u=u.return}u.sibling.return=u.return,u=u.sibling}pt(n,a,e,o),xt(a,e)&&Se(t),t.stateNode=n}null!==t.ref&&(t.effectTag|=128)}return null;case 6:if(n&&null!=t.stateNode)Gu(n,t,n.memoizedProps,e);else{if("string"!==typeof e)return null===t.stateNode&&r("166"),null;o=ie(ju.current),ie(Du.current),ge(t)?(o=t.stateNode,e=t.memoizedProps,o[oo]=t,yt(o,e)&&Se(t)):(o=st(e,o),o[oo]=t,t.stateNode=o)}return null;case 14:case 16:case 10:case 11:case 15:return null;case 4:return fe(t),qu(t),null;case 13:return ue(t),null;case 12:return null;case 0:r("167");default:r("156")}}function Oe(n,t){var e=t.source;null===t.stack&&null!==e&&cn(e),null!==e&&un(e),t=t.value,null!==n&&2===n.tag&&un(n);try{t&&t.suppressReactErrorLogging||console.error(t)}catch(n){n&&n.suppressReactErrorLogging||console.error(n)}}function Fe(n){var t=n.ref;if(null!==t)if("function"===typeof t)try{t(null)}catch(t){Xe(n,t)}else t.current=null}function De(n){switch("function"===typeof $t&&$t(n),n.tag){case 2:Fe(n);var t=n.stateNode;if("function"===typeof t.componentWillUnmount)try{t.props=n.memoizedProps,t.state=n.memoizedState,t.componentWillUnmount()}catch(t){Xe(n,t)}break;case 5:Fe(n);break;case 4:Le(n)}}function Ae(n){return 5===n.tag||3===n.tag||4===n.tag}function je(n){n:{for(var t=n.return;null!==t;){if(Ae(t)){var e=t;break n}t=t.return}r("160"),e=void 0}var o=t=void 0;switch(e.tag){case 5:t=e.stateNode,o=!1;break;case 3:case 4:t=e.stateNode.containerInfo,o=!0;break;default:r("161")}16&e.effectTag&&(ct(t,""),e.effectTag&=-17);n:t:for(e=n;;){for(;null===e.sibling;){if(null===e.return||Ae(e.return)){e=null;break n}e=e.return}for(e.sibling.return=e.return,e=e.sibling;5!==e.tag&&6!==e.tag;){if(2&e.effectTag)continue t;if(null===e.child||4===e.tag)continue t;e.child.return=e,e=e.child}if(!(2&e.effectTag)){e=e.stateNode;break n}}for(var a=n;;){if(5===a.tag||6===a.tag)if(e)if(o){var u=t,i=a.stateNode,c=e;8===u.nodeType?u.parentNode.insertBefore(i,c):u.insertBefore(i,c)}else t.insertBefore(a.stateNode,e);else o?(u=t,i=a.stateNode,8===u.nodeType?u.parentNode.insertBefore(i,u):u.appendChild(i)):t.appendChild(a.stateNode);else if(4!==a.tag&&null!==a.child){a.child.return=a,a=a.child;continue}if(a===n)break;for(;null===a.sibling;){if(null===a.return||a.return===n)return;a=a.return}a.sibling.return=a.return,a=a.sibling}}function Le(n){for(var t=n,e=!1,o=void 0,a=void 0;;){if(!e){e=t.return;n:for(;;){switch(null===e&&r("160"),e.tag){case 5:o=e.stateNode,a=!1;break n;case 3:case 4:o=e.stateNode.containerInfo,a=!0;break n}e=e.return}e=!0}if(5===t.tag||6===t.tag){n:for(var u=t,i=u;;)if(De(i),null!==i.child&&4!==i.tag)i.child.return=i,i=i.child;else{if(i===u)break;for(;null===i.sibling;){if(null===i.return||i.return===u)break n;i=i.return}i.sibling.return=i.return,i=i.sibling}a?(u=o,i=t.stateNode,8===u.nodeType?u.parentNode.removeChild(i):u.removeChild(i)):o.removeChild(t.stateNode)}else if(4===t.tag?o=t.stateNode.containerInfo:De(t),null!==t.child){t.child.return=t,t=t.child;continue}if(t===n)break;for(;null===t.sibling;){if(null===t.return||t.return===n)return;t=t.return,4===t.tag&&(e=!1)}t.sibling.return=t.return,t=t.sibling}}function ze(n,t){switch(t.tag){case 2:break;case 5:var e=t.stateNode;if(null!=e){var o=t.memoizedProps;n=null!==n?n.memoizedProps:o;var a=t.type,u=t.updateQueue;t.updateQueue=null,null!==u&&(e[ao]=o,vt(e,u,a,n,o))}break;case 6:null===t.stateNode&&r("162"),t.stateNode.nodeValue=t.memoizedProps;break;case 3:case 15:case 16:break;default:r("163")}}function Be(n,t,e){e=Gt(e),e.tag=3,e.payload={element:null};var r=t.value;return e.callback=function(){sr(r),Oe(n,t)},e}function Ve(n,t,e){e=Gt(e),e.tag=3;var r=n.stateNode;return null!==r&&"function"===typeof r.componentDidCatch&&(e.callback=function(){null===di?di=new Set([this]):di.add(this);var e=t.value,r=t.stack;Oe(n,t),this.componentDidCatch(e,{componentStack:null!==r?r:""})}),e}function We(n,t,e,r,o,a){e.effectTag|=512,e.firstEffect=e.lastEffect=null,r=oe(r,e),n=t;do{switch(n.tag){case 3:return n.effectTag|=1024,r=Be(n,r,a),void Zt(n,r,a);case 2:if(t=r,e=n.stateNode,0===(64&n.effectTag)&&null!==e&&"function"===typeof e.componentDidCatch&&(null===di||!di.has(e)))return n.effectTag|=1024,r=Ve(n,t,a),void Zt(n,r,a)}n=n.return}while(null!==n)}function He(n){switch(n.tag){case 2:kt(n);var t=n.effectTag;return 1024&t?(n.effectTag=-1025&t|64,n):null;case 3:return fe(n),Et(n),t=n.effectTag,1024&t?(n.effectTag=-1025&t|64,n):null;case 5:return de(n),null;case 16:return t=n.effectTag,1024&t?(n.effectTag=-1025&t|64,n):null;case 4:return fe(n),null;case 13:return ue(n),null;default:return null}}function $e(){if(null!==ei)for(var n=ei.return;null!==n;){var t=n;switch(t.tag){case 2:kt(t);break;case 3:fe(t),Et(t);break;case 5:de(t);break;case 4:fe(t);break;case 13:ue(t)}n=n.return}ri=null,oi=0,ai=-1,ui=!1,ei=null,fi=!1}function qe(n){for(;;){var t=n.alternate,e=n.return,r=n.sibling;if(0===(512&n.effectTag)){t=Pe(t,n,oi);var o=n;if(1073741823===oi||1073741823!==o.expirationTime){var a=0;switch(o.tag){case 3:case 2:var u=o.updateQueue;null!==u&&(a=u.expirationTime)}for(u=o.child;null!==u;)0!==u.expirationTime&&(0===a||a>u.expirationTime)&&(a=u.expirationTime),u=u.sibling;o.expirationTime=a}if(null!==t)return t;if(null!==e&&0===(512&e.effectTag)&&(null===e.firstEffect&&(e.firstEffect=n.firstEffect),null!==n.lastEffect&&(null!==e.lastEffect&&(e.lastEffect.nextEffect=n.firstEffect),e.lastEffect=n.lastEffect),1<n.effectTag&&(null!==e.lastEffect?e.lastEffect.nextEffect=n:e.firstEffect=n,e.lastEffect=n)),null!==r)return r;if(null===e){fi=!0;break}n=e}else{if(null!==(n=He(n,ui,oi)))return n.effectTag&=511,n;if(null!==e&&(e.firstEffect=e.lastEffect=null,e.effectTag|=512),null!==r)return r;if(null===e)break;n=e}}return null}function Ke(n){var t=Te(n.alternate,n,oi);return null===t&&(t=qe(n)),Lo.current=null,t}function Ge(n,t,e){ti&&r("243"),ti=!0,t===oi&&n===ri&&null!==ei||($e(),ri=n,oi=t,ai=-1,ei=Dt(ri.current,null,oi),n.pendingCommitExpirationTime=0);var o=!1;for(ui=!e||oi<=Yu;;){try{if(e)for(;null!==ei&&!hr();)ei=Ke(ei);else for(;null!==ei;)ei=Ke(ei)}catch(t){if(null===ei)o=!0,sr(t);else{null===ei&&r("271"),e=ei;var a=e.return;if(null===a){o=!0,sr(t);break}We(n,a,e,t,ui,oi,Zu),ei=qe(e)}}break}if(ti=!1,o)return null;if(null===ei){if(fi)return n.pendingCommitExpirationTime=t,n.current.alternate;ui&&r("262"),0<=ai&&setTimeout(function(){var t=n.current.expirationTime;0!==t&&(0===n.remainingExpirationTime||n.remainingExpirationTime<t)&&or(n,t)},ai),pr(n.current.expirationTime)}return null}function Xe(n,t){var e;n:{for(ti&&!ci&&r("263"),e=n.return;null!==e;){switch(e.tag){case 2:var o=e.stateNode;if("function"===typeof e.type.getDerivedStateFromCatch||"function"===typeof o.componentDidCatch&&(null===di||!di.has(o))){n=oe(t,n),n=Ve(e,n,1),Yt(e,n,1),Je(e,1),e=void 0;break n}break;case 3:n=oe(t,n),n=Be(e,n,1),Yt(e,n,1),Je(e,1),e=void 0;break n}e=e.return}3===n.tag&&(e=oe(t,n),e=Be(n,e,1),Yt(n,e,1),Je(n,1)),e=void 0}return e}function Ye(){var n=2+25*(1+((nr()-2+500)/25|0));return n<=Ju&&(n=Ju+1),Ju=n}function Ze(n,t){return n=0!==ni?ni:ti?ci?1:oi:1&t.mode?Ri?2+10*(1+((n-2+15)/10|0)):2+25*(1+((n-2+500)/25|0)):1,Ri&&(0===Ni||n>Ni)&&(Ni=n),n}function Je(n,t){for(;null!==n;){if((0===n.expirationTime||n.expirationTime>t)&&(n.expirationTime=t),null!==n.alternate&&(0===n.alternate.expirationTime||n.alternate.expirationTime>t)&&(n.alternate.expirationTime=t),null===n.return){if(3!==n.tag)break;var e=n.stateNode;!ti&&0!==oi&&t<oi&&$e();var o=e.current.expirationTime;ti&&!ci&&ri===e||or(e,o),wi>Qi&&r("185")}n=n.return}}function nr(){return Zu=gu()-Xu,Yu=2+(Zu/10|0)}function tr(n){var t=ni;ni=2+25*(1+((nr()-2+500)/25|0));try{return n()}finally{ni=t}}function er(n,t,e,r,o){var a=ni;ni=1;try{return n(t,e,r,o)}finally{ni=a}}function rr(n){if(0!==hi){if(n>hi)return;null!==si&&Uu(si)}var t=gu()-Xu;hi=n,si=bu(ur,{timeout:10*(n-2)-t})}function or(n,t){if(null===n.nextScheduledRoot)n.remainingExpirationTime=t,null===li?(mi=li=n,n.nextScheduledRoot=n):(li=li.nextScheduledRoot=n,li.nextScheduledRoot=mi);else{var e=n.remainingExpirationTime;(0===e||t<e)&&(n.remainingExpirationTime=t)}pi||(bi?Ui&&(Mi=n,vi=1,mr(n,1,!1)):1===t?ir():rr(t))}function ar(){var n=0,t=null;if(null!==li)for(var e=li,o=mi;null!==o;){var a=o.remainingExpirationTime;if(0===a){if((null===e||null===li)&&r("244"),o===o.nextScheduledRoot){mi=li=o.nextScheduledRoot=null;break}if(o===mi)mi=a=o.nextScheduledRoot,li.nextScheduledRoot=a,o.nextScheduledRoot=null;else{if(o===li){li=e,li.nextScheduledRoot=mi,o.nextScheduledRoot=null;break}e.nextScheduledRoot=o.nextScheduledRoot,o.nextScheduledRoot=null}o=e.nextScheduledRoot}else{if((0===n||a<n)&&(n=a,t=o),o===li)break;e=o,o=o.nextScheduledRoot}}e=Mi,null!==e&&e===t&&1===n?wi++:wi=0,Mi=t,vi=n}function ur(n){cr(0,!0,n)}function ir(){cr(1,!1,null)}function cr(n,t,e){if(gi=e,ar(),t)for(;null!==Mi&&0!==vi&&(0===n||n>=vi)&&(!yi||nr()>=vi);)nr(),mr(Mi,vi,!yi),ar();else for(;null!==Mi&&0!==vi&&(0===n||n>=vi);)mr(Mi,vi,!1),ar();null!==gi&&(hi=0,si=null),0!==vi&&rr(vi),gi=null,yi=!1,dr()}function fr(n,t){pi&&r("253"),Mi=n,vi=t,mr(n,t,!1),ir(),dr()}function dr(){if(wi=0,null!==Ii){var n=Ii;Ii=null;for(var t=0;t<n.length;t++){var e=n[t];try{e._onComplete()}catch(n){xi||(xi=!0,Ci=n)}}}if(xi)throw n=Ci,Ci=null,xi=!1,n}function mr(n,t,e){pi&&r("245"),pi=!0,e?(e=n.finishedWork,null!==e?lr(n,e,t):null!==(e=Ge(n,t,!0))&&(hr()?n.finishedWork=e:lr(n,e,t))):(e=n.finishedWork,null!==e?lr(n,e,t):null!==(e=Ge(n,t,!1))&&lr(n,e,t)),pi=!1}function lr(n,t,e){var o=n.firstBatch;if(null!==o&&o._expirationTime<=e&&(null===Ii?Ii=[o]:Ii.push(o),o._defer))return n.finishedWork=t,void(n.remainingExpirationTime=0);if(n.finishedWork=null,ci=ti=!0,e=t.stateNode,e.current===t&&r("177"),o=e.pendingCommitExpirationTime,0===o&&r("261"),e.pendingCommitExpirationTime=0,nr(),Lo.current=null,1<t.effectTag)if(null!==t.lastEffect){t.lastEffect.nextEffect=t;var a=t.firstEffect}else a=t;else a=t.firstEffect;xu=Ta;var u=jr();if(Xn(u)){if("selectionStart"in u)var i={start:u.selectionStart,end:u.selectionEnd};else n:{var c=window.getSelection&&window.getSelection();if(c&&0!==c.rangeCount){i=c.anchorNode;var f=c.anchorOffset,d=c.focusNode;c=c.focusOffset;try{i.nodeType,d.nodeType}catch(n){i=null;break n}var m=0,l=-1,h=-1,s=0,p=0,M=u,v=null;t:for(;;){for(var N;M!==i||0!==f&&3!==M.nodeType||(l=m+f),M!==d||0!==c&&3!==M.nodeType||(h=m+c),3===M.nodeType&&(m+=M.nodeValue.length),null!==(N=M.firstChild);)v=M,M=N;for(;;){if(M===u)break t;if(v===i&&++s===f&&(l=m),v===d&&++p===c&&(h=m),null!==(N=M.nextSibling))break;M=v,v=M.parentNode}M=N}i=-1===l||-1===h?null:{start:l,end:h}}else i=null}i=i||{start:0,end:0}}else i=null;for(Cu={focusedElem:u,selectionRange:i},Bn(!1),ii=a;null!==ii;){u=!1,i=void 0;try{for(;null!==ii;){if(256&ii.effectTag){var y=ii.alternate;switch(f=ii,f.tag){case 2:if(256&f.effectTag&&null!==y){var x=y.memoizedProps,C=y.memoizedState,g=f.stateNode;g.props=f.memoizedProps,g.state=f.memoizedState;var b=g.getSnapshotBeforeUpdate(x,C);g.__reactInternalSnapshotBeforeUpdate=b}break;case 3:case 5:case 6:case 4:break;default:r("163")}}ii=ii.nextEffect}}catch(n){u=!0,i=n}u&&(null===ii&&r("178"),Xe(ii,i),null!==ii&&(ii=ii.nextEffect))}for(ii=a;null!==ii;){y=!1,x=void 0;try{for(;null!==ii;){var U=ii.effectTag;if(16&U&&ct(ii.stateNode,""),128&U){var R=ii.alternate;if(null!==R){var I=R.ref;null!==I&&("function"===typeof I?I(null):I.current=null)}}switch(14&U){case 2:je(ii),ii.effectTag&=-3;break;case 6:je(ii),ii.effectTag&=-3,ze(ii.alternate,ii);break;case 4:ze(ii.alternate,ii);break;case 8:C=ii,Le(C),C.return=null,C.child=null,C.alternate&&(C.alternate.child=null,C.alternate.return=null)}ii=ii.nextEffect}}catch(n){y=!0,x=n}y&&(null===ii&&r("178"),Xe(ii,x),null!==ii&&(ii=ii.nextEffect))}if(I=Cu,R=jr(),U=I.focusedElem,y=I.selectionRange,R!==U&&zr(document.documentElement,U)){null!==y&&Xn(U)&&(R=y.start,I=y.end,void 0===I&&(I=R),"selectionStart"in U?(U.selectionStart=R,U.selectionEnd=Math.min(I,U.value.length)):window.getSelection&&(R=window.getSelection(),x=U[S()].length,I=Math.min(y.start,x),y=void 0===y.end?I:Math.min(y.end,x),!R.extend&&I>y&&(x=y,y=I,I=x),x=Gn(U,I),C=Gn(U,y),x&&C&&(1!==R.rangeCount||R.anchorNode!==x.node||R.anchorOffset!==x.offset||R.focusNode!==C.node||R.focusOffset!==C.offset)&&(g=document.createRange(),g.setStart(x.node,x.offset),R.removeAllRanges(),I>y?(R.addRange(g),R.extend(C.node,C.offset)):(g.setEnd(C.node,C.offset),R.addRange(g))))),R=[];for(I=U;I=I.parentNode;)1===I.nodeType&&R.push({element:I,left:I.scrollLeft,top:I.scrollTop});for("function"===typeof U.focus&&U.focus(),U=0;U<R.length;U++)I=R[U],I.element.scrollLeft=I.left,I.element.scrollTop=I.top}for(Cu=null,Bn(xu),xu=null,e.current=t,ii=a;null!==ii;){a=!1,U=void 0;try{for(R=o;null!==ii;){var Q=ii.effectTag;if(36&Q){var w=ii.alternate;switch(I=ii,y=R,I.tag){case 2:var _=I.stateNode;if(4&I.effectTag)if(null===w)_.props=I.memoizedProps,_.state=I.memoizedState,_.componentDidMount();else{var k=w.memoizedProps,E=w.memoizedState;_.props=I.memoizedProps,_.state=I.memoizedState,_.componentDidUpdate(k,E,_.__reactInternalSnapshotBeforeUpdate)}var T=I.updateQueue;null!==T&&(_.props=I.memoizedProps,_.state=I.memoizedState,re(I,T,_,y));break;case 3:var P=I.updateQueue;if(null!==P){if(x=null,null!==I.child)switch(I.child.tag){case 5:x=I.child.stateNode;break;case 2:x=I.child.stateNode}re(I,P,x,y)}break;case 5:var O=I.stateNode;null===w&&4&I.effectTag&&xt(I.type,I.memoizedProps)&&O.focus();break;case 6:case 4:case 15:case 16:break;default:r("163")}}if(128&Q){I=void 0;var F=ii.ref;if(null!==F){var D=ii.stateNode;switch(ii.tag){case 5:I=D;break;default:I=D}"function"===typeof F?F(I):F.current=I}}var A=ii.nextEffect;ii.nextEffect=null,ii=A}}catch(n){a=!0,U=n}a&&(null===ii&&r("178"),Xe(ii,U),null!==ii&&(ii=ii.nextEffect))}ti=ci=!1,"function"===typeof Ht&&Ht(t.stateNode),t=e.current.expirationTime,0===t&&(di=null),n.remainingExpirationTime=t}function hr(){return!(null===gi||gi.timeRemaining()>_i)&&(yi=!0)}function sr(n){null===Mi&&r("246"),Mi.remainingExpirationTime=0,xi||(xi=!0,Ci=n)}function pr(n){null===Mi&&r("246"),Mi.remainingExpirationTime=n}function Mr(n,t){var e=bi;bi=!0;try{return n(t)}finally{(bi=e)||pi||ir()}}function vr(n,t){if(bi&&!Ui){Ui=!0;try{return n(t)}finally{Ui=!1}}return n(t)}function Nr(n,t){pi&&r("187");var e=bi;bi=!0;try{return er(n,t)}finally{bi=e,ir()}}function yr(n,t,e){if(Ri)return n(t,e);bi||pi||0===Ni||(cr(Ni,!1,null),Ni=0);var r=Ri,o=bi;bi=Ri=!0;try{return n(t,e)}finally{Ri=r,(bi=o)||pi||ir()}}function xr(n){var t=bi;bi=!0;try{er(n)}finally{(bi=t)||pi||cr(1,!1,null)}}function Cr(n,t,e,o,a){var u=t.current;if(e){e=e._reactInternalFiber;var i;n:{for(2===Pn(e)&&2===e.tag||r("170"),i=e;3!==i.tag;){if(_t(i)){i=i.stateNode.__reactInternalMemoizedMergedChildContext;break n}(i=i.return)||r("171")}i=i.stateNode.context}e=_t(e)?St(e,i):i}else e=Br;return null===t.context?t.context=e:t.pendingContext=e,t=a,a=Gt(o),a.payload={element:n},t=void 0===t?null:t,null!==t&&(a.callback=t),Yt(u,a,o),Je(u,o),o}function gr(n){var t=n._reactInternalFiber;return void 0===t&&("function"===typeof n.render?r("188"):r("268",Object.keys(n))),n=Dn(t),null===n?null:n.stateNode}function br(n,t,e,r){var o=t.current;return o=Ze(nr(),o),Cr(n,t,e,o,r)}function Ur(n){if(n=n.current,!n.child)return null;switch(n.child.tag){case 5:default:return n.child.stateNode}}function Rr(n){var t=n.findFiberByHostInstance;return Wt(Dr({},n,{findHostInstanceByFiber:function(n){return n=Dn(n),null===n?null:n.stateNode},findFiberByHostInstance:function(n){return t?t(n):null}}))}function Ir(n,t,e){var r=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null;return{$$typeof:Vo,key:null==r?null:""+r,children:n,containerInfo:t,implementation:e}}function Qr(n){this._expirationTime=Ye(),this._root=n,this._callbacks=this._next=null,this._hasChildren=this._didComplete=!1,this._children=null,this._defer=!0}function wr(){this._callbacks=null,this._didCommit=!1,this._onCommit=this._onCommit.bind(this)}function _r(n,t,e){this._internalRoot=Bt(n,t,e)}function kr(n){return!(!n||1!==n.nodeType&&9!==n.nodeType&&11!==n.nodeType&&(8!==n.nodeType||" react-mount-point-unstable "!==n.nodeValue))}function Er(n,t){if(t||(t=n?9===n.nodeType?n.documentElement:n.firstChild:null,t=!(!t||1!==t.nodeType||!t.hasAttribute("data-reactroot"))),!t)for(var e;e=n.lastChild;)n.removeChild(e);return new _r(n,!1,t)}function Tr(n,t,e,o,a){kr(e)||r("200");var u=e._reactRootContainer;if(u){if("function"===typeof a){var i=a;a=function(){var n=Ur(u._internalRoot);i.call(n)}}null!=n?u.legacy_renderSubtreeIntoContainer(n,t,a):u.render(t,a)}else{if(u=e._reactRootContainer=Er(e,o),"function"===typeof a){var c=a;a=function(){var n=Ur(u._internalRoot);c.call(n)}}vr(function(){null!=n?u.legacy_renderSubtreeIntoContainer(n,t,a):u.render(t,a)})}return Ur(u._internalRoot)}function Sr(n,t){var e=2<arguments.length&&void 0!==arguments[2]?arguments[2]:null;return kr(t)||r("200"),Ir(n,t,null,e)}var Pr=e(3),Or=e(1),Fr=e(17),Dr=e(0),Ar=e(5),jr=e(18),Lr=e(19),zr=e(20),Br=e(4);Or||r("227");var Vr={_caughtError:null,_hasCaughtError:!1,_rethrowError:null,_hasRethrowError:!1,invokeGuardedCallback:function(n,t,e,r,a,u,i,c,f){o.apply(Vr,arguments)},invokeGuardedCallbackAndCatchFirstError:function(n,t,e,r,o,a,u,i,c){if(Vr.invokeGuardedCallback.apply(this,arguments),Vr.hasCaughtError()){var f=Vr.clearCaughtError();Vr._hasRethrowError||(Vr._hasRethrowError=!0,Vr._rethrowError=f)}},rethrowCaughtError:function(){return a.apply(Vr,arguments)},hasCaughtError:function(){return Vr._hasCaughtError},clearCaughtError:function(){if(Vr._hasCaughtError){var n=Vr._caughtError;return Vr._caughtError=null,Vr._hasCaughtError=!1,n}r("198")}},Wr=null,Hr={},$r=[],qr={},Kr={},Gr={},Xr={plugins:$r,eventNameDispatchConfigs:qr,registrationNameModules:Kr,registrationNameDependencies:Gr,possibleRegistrationNames:null,injectEventPluginOrder:c,injectEventPluginsByName:f},Yr=null,Zr=null,Jr=null,no=null,to={injectEventPluginOrder:c,injectEventPluginsByName:f},eo={injection:to,getListener:M,runEventsInBatch:v,runExtractedEventsInBatch:N},ro=Math.random().toString(36).slice(2),oo="__reactInternalInstance$"+ro,ao="__reactEventHandlers$"+ro,uo={precacheFiberNode:function(n,t){t[oo]=n},getClosestInstanceFromNode:y,getInstanceFromNode:function(n){return n=n[oo],!n||5!==n.tag&&6!==n.tag?null:n},getNodeFromInstance:x,getFiberCurrentPropsFromNode:C,updateFiberProps:function(n,t){n[ao]=t}},io={accumulateTwoPhaseDispatches:_,accumulateTwoPhaseDispatchesSkipTarget:function(n){l(n,I)},accumulateEnterLeaveDispatches:k,accumulateDirectDispatches:function(n){l(n,w)}},co={animationend:E("Animation","AnimationEnd"),animationiteration:E("Animation","AnimationIteration"),animationstart:E("Animation","AnimationStart"),transitionend:E("Transition","TransitionEnd")},fo={},mo={};Fr.canUseDOM&&(mo=document.createElement("div").style,"AnimationEvent"in window||(delete co.animationend.animation,delete co.animationiteration.animation,delete co.animationstart.animation),"TransitionEvent"in window||delete co.transitionend.transition);var lo=T("animationend"),ho=T("animationiteration"),so=T("animationstart"),po=T("transitionend"),Mo="abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange seeked seeking stalled suspend timeupdate volumechange waiting".split(" "),vo=null,No={_root:null,_startText:null,_fallbackText:null},yo="dispatchConfig _targetInst nativeEvent isDefaultPrevented isPropagationStopped _dispatchListeners _dispatchInstances".split(" "),xo={type:null,target:null,currentTarget:Ar.thatReturnsNull,eventPhase:null,bubbles:null,cancelable:null,timeStamp:function(n){return n.timeStamp||Date.now()},defaultPrevented:null,isTrusted:null};Dr(F.prototype,{preventDefault:function(){this.defaultPrevented=!0;var n=this.nativeEvent;n&&(n.preventDefault?n.preventDefault():"unknown"!==typeof n.returnValue&&(n.returnValue=!1),this.isDefaultPrevented=Ar.thatReturnsTrue)},stopPropagation:function(){var n=this.nativeEvent;n&&(n.stopPropagation?n.stopPropagation():"unknown"!==typeof n.cancelBubble&&(n.cancelBubble=!0),this.isPropagationStopped=Ar.thatReturnsTrue)},persist:function(){this.isPersistent=Ar.thatReturnsTrue},isPersistent:Ar.thatReturnsFalse,destructor:function(){var n,t=this.constructor.Interface;for(n in t)this[n]=null;for(t=0;t<yo.length;t++)this[yo[t]]=null}}),F.Interface=xo,F.extend=function(n){function t(){}function e(){return r.apply(this,arguments)}var r=this;t.prototype=r.prototype;var o=new t;return Dr(o,e.prototype),e.prototype=o,e.prototype.constructor=e,e.Interface=Dr({},r.Interface,n),e.extend=r.extend,j(e),e},j(F);var Co=F.extend({data:null}),go=F.extend({data:null}),bo=[9,13,27,32],Uo=Fr.canUseDOM&&"CompositionEvent"in window,Ro=null;Fr.canUseDOM&&"documentMode"in document&&(Ro=document.documentMode);var Io=Fr.canUseDOM&&"TextEvent"in window&&!Ro,Qo=Fr.canUseDOM&&(!Uo||Ro&&8<Ro&&11>=Ro),wo=String.fromCharCode(32),_o={beforeInput:{phasedRegistrationNames:{bubbled:"onBeforeInput",captured:"onBeforeInputCapture"},dependencies:["compositionend","keypress","textInput","paste"]},compositionEnd:{phasedRegistrationNames:{bubbled:"onCompositionEnd",captured:"onCompositionEndCapture"},dependencies:"blur compositionend keydown keypress keyup mousedown".split(" ")},compositionStart:{phasedRegistrationNames:{bubbled:"onCompositionStart",captured:"onCompositionStartCapture"},dependencies:"blur compositionstart keydown keypress keyup mousedown".split(" ")},compositionUpdate:{phasedRegistrationNames:{bubbled:"onCompositionUpdate",captured:"onCompositionUpdateCapture"},dependencies:"blur compositionupdate keydown keypress keyup mousedown".split(" ")}},ko=!1,Eo=!1,To={eventTypes:_o,extractEvents:function(n,t,e,r){var o=void 0,a=void 0;if(Uo)n:{switch(n){case"compositionstart":o=_o.compositionStart;break n;case"compositionend":o=_o.compositionEnd;break n;case"compositionupdate":o=_o.compositionUpdate;break n}o=void 0}else Eo?L(n,e)&&(o=_o.compositionEnd):"keydown"===n&&229===e.keyCode&&(o=_o.compositionStart);return o?(Qo&&(Eo||o!==_o.compositionStart?o===_o.compositionEnd&&Eo&&(a=P()):(No._root=r,No._startText=O(),Eo=!0)),o=Co.getPooled(o,t,e,r),a?o.data=a:null!==(a=z(e))&&(o.data=a),_(o),a=o):a=null,(n=Io?B(n,e):V(n,e))?(t=go.getPooled(_o.beforeInput,t,e,r),t.data=n,_(t)):t=null,null===a?t:null===t?a:[a,t]}},So=null,Po={injectFiberControlledHostComponent:function(n){So=n}},Oo=null,Fo=null,Do={injection:Po,enqueueStateRestore:H,needsStateRestore:$,restoreStateIfNeeded:q},Ao=!1,jo={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0},Lo=Or.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,zo="function"===typeof Symbol&&Symbol.for,Bo=zo?Symbol.for("react.element"):60103,Vo=zo?Symbol.for("react.portal"):60106,Wo=zo?Symbol.for("react.fragment"):60107,Ho=zo?Symbol.for("react.strict_mode"):60108,$o=zo?Symbol.for("react.profiler"):60114,qo=zo?Symbol.for("react.provider"):60109,Ko=zo?Symbol.for("react.context"):60110,Go=zo?Symbol.for("react.async_mode"):60111,Xo=zo?Symbol.for("react.forward_ref"):60112,Yo=zo?Symbol.for("react.timeout"):60113,Zo="function"===typeof Symbol&&Symbol.iterator,Jo=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,na=Object.prototype.hasOwnProperty,ta={},ea={},ra={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(n){ra[n]=new ln(n,0,!1,n,null)}),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(n){var t=n[0];ra[t]=new ln(t,1,!1,n[1],null)}),["contentEditable","draggable","spellCheck","value"].forEach(function(n){ra[n]=new ln(n,2,!1,n.toLowerCase(),null)}),["autoReverse","externalResourcesRequired","preserveAlpha"].forEach(function(n){ra[n]=new ln(n,2,!1,n,null)}),"allowFullScreen async autoFocus autoPlay controls default defer disabled formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(n){ra[n]=new ln(n,3,!1,n.toLowerCase(),null)}),["checked","multiple","muted","selected"].forEach(function(n){ra[n]=new ln(n,3,!0,n.toLowerCase(),null)}),["capture","download"].forEach(function(n){ra[n]=new ln(n,4,!1,n.toLowerCase(),null)}),["cols","rows","size","span"].forEach(function(n){ra[n]=new ln(n,6,!1,n.toLowerCase(),null)}),["rowSpan","start"].forEach(function(n){ra[n]=new ln(n,5,!1,n.toLowerCase(),null)});var oa=/[\-:]([a-z])/g;"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(n){var t=n.replace(oa,hn);ra[t]=new ln(t,1,!1,n,null)}),"xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(n){var t=n.replace(oa,hn);ra[t]=new ln(t,1,!1,n,"http://www.w3.org/1999/xlink")}),["xml:base","xml:lang","xml:space"].forEach(function(n){var t=n.replace(oa,hn);ra[t]=new ln(t,1,!1,n,"http://www.w3.org/XML/1998/namespace")}),ra.tabIndex=new ln("tabIndex",1,!1,"tabindex",null);var aa={change:{phasedRegistrationNames:{bubbled:"onChange",captured:"onChangeCapture"},dependencies:"blur change click focus input keydown keyup selectionchange".split(" ")}},ua=null,ia=null,ca=!1;Fr.canUseDOM&&(ca=nn("input")&&(!document.documentMode||9<document.documentMode));var fa={eventTypes:aa,_isInputEventSupported:ca,extractEvents:function(n,t,e,r){var o=t?x(t):window,a=void 0,u=void 0,i=o.nodeName&&o.nodeName.toLowerCase();if("select"===i||"input"===i&&"file"===o.type?a=Rn:Z(o)?ca?a=En:(a=_n,u=wn):(i=o.nodeName)&&"input"===i.toLowerCase()&&("checkbox"===o.type||"radio"===o.type)&&(a=kn),a&&(a=a(n,t)))return gn(a,e,r);u&&u(n,o,t),"blur"===n&&(n=o._wrapperState)&&n.controlled&&"number"===o.type&&xn(o,"number",o.value)}},da=F.extend({view:null,detail:null}),ma={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"},la=da.extend({screenX:null,screenY:null,clientX:null,clientY:null,pageX:null,pageY:null,ctrlKey:null,shiftKey:null,altKey:null,metaKey:null,getModifierState:Sn,button:null,buttons:null,relatedTarget:function(n){return n.relatedTarget||(n.fromElement===n.srcElement?n.toElement:n.fromElement)}}),ha=la.extend({pointerId:null,width:null,height:null,pressure:null,tiltX:null,tiltY:null,pointerType:null,isPrimary:null}),sa={mouseEnter:{registrationName:"onMouseEnter",dependencies:["mouseout","mouseover"]},mouseLeave:{registrationName:"onMouseLeave",dependencies:["mouseout","mouseover"]},pointerEnter:{registrationName:"onPointerEnter",dependencies:["pointerout","pointerover"]},pointerLeave:{registrationName:"onPointerLeave",dependencies:["pointerout","pointerover"]}},pa={eventTypes:sa,extractEvents:function(n,t,e,r){var o="mouseover"===n||"pointerover"===n,a="mouseout"===n||"pointerout"===n;if(o&&(e.relatedTarget||e.fromElement)||!a&&!o)return null;if(o=r.window===r?r:(o=r.ownerDocument)?o.defaultView||o.parentWindow:window,a?(a=t,t=(t=e.relatedTarget||e.toElement)?y(t):null):a=null,a===t)return null;var u=void 0,i=void 0,c=void 0,f=void 0;return"mouseout"===n||"mouseover"===n?(u=la,i=sa.mouseLeave,c=sa.mouseEnter,f="mouse"):"pointerout"!==n&&"pointerover"!==n||(u=ha,i=sa.pointerLeave,c=sa.pointerEnter,f="pointer"),n=null==a?o:x(a),o=null==t?o:x(t),i=u.getPooled(i,a,e,r),i.type=f+"leave",i.target=n,i.relatedTarget=o,e=u.getPooled(c,t,e,r),e.type=f+"enter",e.target=o,e.relatedTarget=n,k(i,e,a,t),[i,e]}},Ma=F.extend({animationName:null,elapsedTime:null,pseudoElement:null}),va=F.extend({clipboardData:function(n){return"clipboardData"in n?n.clipboardData:window.clipboardData}}),Na=da.extend({relatedTarget:null}),ya={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},xa={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"},Ca=da.extend({key:function(n){if(n.key){var t=ya[n.key]||n.key;if("Unidentified"!==t)return t}return"keypress"===n.type?(n=jn(n),13===n?"Enter":String.fromCharCode(n)):"keydown"===n.type||"keyup"===n.type?xa[n.keyCode]||"Unidentified":""},location:null,ctrlKey:null,shiftKey:null,altKey:null,metaKey:null,repeat:null,locale:null,getModifierState:Sn,charCode:function(n){return"keypress"===n.type?jn(n):0},keyCode:function(n){return"keydown"===n.type||"keyup"===n.type?n.keyCode:0},which:function(n){return"keypress"===n.type?jn(n):"keydown"===n.type||"keyup"===n.type?n.keyCode:0}}),ga=la.extend({dataTransfer:null}),ba=da.extend({touches:null,targetTouches:null,changedTouches:null,altKey:null,metaKey:null,ctrlKey:null,shiftKey:null,getModifierState:Sn}),Ua=F.extend({propertyName:null,elapsedTime:null,pseudoElement:null}),Ra=la.extend({deltaX:function(n){return"deltaX"in n?n.deltaX:"wheelDeltaX"in n?-n.wheelDeltaX:0},deltaY:function(n){return"deltaY"in n?n.deltaY:"wheelDeltaY"in n?-n.wheelDeltaY:"wheelDelta"in n?-n.wheelDelta:0},deltaZ:null,deltaMode:null}),Ia=[["abort","abort"],[lo,"animationEnd"],[ho,"animationIteration"],[so,"animationStart"],["canplay","canPlay"],["canplaythrough","canPlayThrough"],["drag","drag"],["dragenter","dragEnter"],["dragexit","dragExit"],["dragleave","dragLeave"],["dragover","dragOver"],["durationchange","durationChange"],["emptied","emptied"],["encrypted","encrypted"],["ended","ended"],["error","error"],["gotpointercapture","gotPointerCapture"],["load","load"],["loadeddata","loadedData"],["loadedmetadata","loadedMetadata"],["loadstart","loadStart"],["lostpointercapture","lostPointerCapture"],["mousemove","mouseMove"],["mouseout","mouseOut"],["mouseover","mouseOver"],["playing","playing"],["pointermove","pointerMove"],["pointerout","pointerOut"],["pointerover","pointerOver"],["progress","progress"],["scroll","scroll"],["seeking","seeking"],["stalled","stalled"],["suspend","suspend"],["timeupdate","timeUpdate"],["toggle","toggle"],["touchmove","touchMove"],[po,"transitionEnd"],["waiting","waiting"],["wheel","wheel"]],Qa={},wa={};[["blur","blur"],["cancel","cancel"],["click","click"],["close","close"],["contextmenu","contextMenu"],["copy","copy"],["cut","cut"],["dblclick","doubleClick"],["dragend","dragEnd"],["dragstart","dragStart"],["drop","drop"],["focus","focus"],["input","input"],["invalid","invalid"],["keydown","keyDown"],["keypress","keyPress"],["keyup","keyUp"],["mousedown","mouseDown"],["mouseup","mouseUp"],["paste","paste"],["pause","pause"],["play","play"],["pointercancel","pointerCancel"],["pointerdown","pointerDown"],["pointerup","pointerUp"],["ratechange","rateChange"],["reset","reset"],["seeked","seeked"],["submit","submit"],["touchcancel","touchCancel"],["touchend","touchEnd"],["touchstart","touchStart"],["volumechange","volumeChange"]].forEach(function(n){Ln(n,!0)}),Ia.forEach(function(n){Ln(n,!1)});var _a={eventTypes:Qa,isInteractiveTopLevelEventType:function(n){return void 0!==(n=wa[n])&&!0===n.isInteractive},extractEvents:function(n,t,e,r){var o=wa[n];if(!o)return null;switch(n){case"keypress":if(0===jn(e))return null;case"keydown":case"keyup":n=Ca;break;case"blur":case"focus":n=Na;break;case"click":if(2===e.button)return null;case"dblclick":case"mousedown":case"mousemove":case"mouseup":case"mouseout":case"mouseover":case"contextmenu":n=la;break;case"drag":case"dragend":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"dragstart":case"drop":n=ga;break;case"touchcancel":case"touchend":case"touchmove":case"touchstart":n=ba;break;case lo:case ho:case so:n=Ma;break;case po:n=Ua;break;case"scroll":n=da;break;case"wheel":n=Ra;break;case"copy":case"cut":case"paste":n=va;break;case"gotpointercapture":case"lostpointercapture":case"pointercancel":case"pointerdown":case"pointermove":case"pointerout":case"pointerover":case"pointerup":n=ha;break;default:n=F}return t=n.getPooled(o,t,e,r),_(t),t}},ka=_a.isInteractiveTopLevelEventType,Ea=[],Ta=!0,Sa={get _enabled(){return Ta},setEnabled:Bn,isEnabled:function(){return Ta},trapBubbledEvent:Vn,trapCapturedEvent:Wn,dispatchEvent:$n},Pa={},Oa=0,Fa="_reactListenersID"+(""+Math.random()).slice(2),Da=Fr.canUseDOM&&"documentMode"in document&&11>=document.documentMode,Aa={select:{phasedRegistrationNames:{bubbled:"onSelect",captured:"onSelectCapture"},dependencies:"blur contextmenu focus keydown keyup mousedown mouseup selectionchange".split(" ")}},ja=null,La=null,za=null,Ba=!1,Va={eventTypes:Aa,extractEvents:function(n,t,e,r){var o,a=r.window===r?r.document:9===r.nodeType?r:r.ownerDocument;if(!(o=!a)){n:{a=qn(a),o=Gr.onSelect;for(var u=0;u<o.length;u++){var i=o[u];if(!a.hasOwnProperty(i)||!a[i]){a=!1;break n}}a=!0}o=!a}if(o)return null;switch(a=t?x(t):window,n){case"focus":(Z(a)||"true"===a.contentEditable)&&(ja=a,La=t,za=null);break;case"blur":za=La=ja=null;break;case"mousedown":Ba=!0;break;case"contextmenu":case"mouseup":return Ba=!1,Yn(e,r);case"selectionchange":if(Da)break;case"keydown":case"keyup":return Yn(e,r)}return null}};to.injectEventPluginOrder("ResponderEventPlugin SimpleEventPlugin TapEventPlugin EnterLeaveEventPlugin ChangeEventPlugin SelectEventPlugin BeforeInputEventPlugin".split(" ")),Yr=uo.getFiberCurrentPropsFromNode,Zr=uo.getInstanceFromNode,Jr=uo.getNodeFromInstance,to.injectEventPluginsByName({SimpleEventPlugin:_a,EnterLeaveEventPlugin:pa,ChangeEventPlugin:fa,SelectEventPlugin:Va,BeforeInputEventPlugin:To});var Wa="function"===typeof requestAnimationFrame?requestAnimationFrame:void 0,Ha=Date,$a=setTimeout,qa=clearTimeout,Ka=void 0;if("object"===typeof performance&&"function"===typeof performance.now){var Ga=performance;Ka=function(){return Ga.now()}}else Ka=function(){return Ha.now()};var Xa=void 0,Ya=void 0;if(Fr.canUseDOM){var Za="function"===typeof Wa?Wa:function(){r("276")},Ja=null,nu=null,tu=-1,eu=!1,ru=!1,ou=0,au=33,uu=33,iu={didTimeout:!1,timeRemaining:function(){var n=ou-Ka();return 0<n?n:0}},cu=function(n,t){var e=n.scheduledCallback,r=!1;try{e(t),r=!0}finally{Ya(n),r||(eu=!0,window.postMessage(fu,"*"))}},fu="__reactIdleCallback$"+Math.random().toString(36).slice(2);window.addEventListener("message",function(n){if(n.source===window&&n.data===fu&&(eu=!1,null!==Ja)){if(null!==Ja){var t=Ka();if(!(-1===tu||tu>t)){n=-1;for(var e=[],r=Ja;null!==r;){var o=r.timeoutTime;-1!==o&&o<=t?e.push(r):-1!==o&&(-1===n||o<n)&&(n=o),r=r.next}if(0<e.length)for(iu.didTimeout=!0,t=0,r=e.length;t<r;t++)cu(e[t],iu);tu=n}}for(n=Ka();0<ou-n&&null!==Ja;)n=Ja,iu.didTimeout=!1,cu(n,iu),n=Ka();null===Ja||ru||(ru=!0,Za(du))}},!1);var du=function(n){ru=!1;var t=n-ou+uu;t<uu&&au<uu?(8>t&&(t=8),uu=t<au?au:t):au=t,ou=n+uu,eu||(eu=!0,window.postMessage(fu,"*"))};Xa=function(n,t){var e=-1;return null!=t&&"number"===typeof t.timeout&&(e=Ka()+t.timeout),(-1===tu||-1!==e&&e<tu)&&(tu=e),n={scheduledCallback:n,timeoutTime:e,prev:null,next:null},null===Ja?Ja=n:null!==(t=n.prev=nu)&&(t.next=n),nu=n,ru||(ru=!0,Za(du)),n},Ya=function(n){if(null!==n.prev||Ja===n){var t=n.next,e=n.prev;n.next=null,n.prev=null,null!==t?null!==e?(e.next=t,t.prev=e):(t.prev=null,Ja=t):null!==e?(e.next=null,nu=e):nu=Ja=null}}}else{var mu=new Map;Xa=function(n){var t={scheduledCallback:n,timeoutTime:0,next:null,prev:null},e=$a(function(){n({timeRemaining:function(){return 1/0},didTimeout:!1})});return mu.set(n,e),t},Ya=function(n){var t=mu.get(n.scheduledCallback);mu.delete(n),qa(t)}}var lu={html:"http://www.w3.org/1999/xhtml",mathml:"http://www.w3.org/1998/Math/MathML",svg:"http://www.w3.org/2000/svg"},hu=void 0,su=function(n){return"undefined"!==typeof MSApp&&MSApp.execUnsafeLocalFunction?function(t,e,r,o){MSApp.execUnsafeLocalFunction(function(){return n(t,e)})}:n}(function(n,t){if(n.namespaceURI!==lu.svg||"innerHTML"in n)n.innerHTML=t;else{for(hu=hu||document.createElement("div"),hu.innerHTML="<svg>"+t+"</svg>",t=hu.firstChild;n.firstChild;)n.removeChild(n.firstChild);for(;t.firstChild;)n.appendChild(t.firstChild)}}),pu={animationIterationCount:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},Mu=["Webkit","ms","Moz","O"];Object.keys(pu).forEach(function(n){Mu.forEach(function(t){t=t+n.charAt(0).toUpperCase()+n.substring(1),pu[t]=pu[n]})});var vu=Dr({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0}),Nu=Ar.thatReturns(""),yu={createElement:ht,createTextNode:st,setInitialProperties:pt,diffProperties:Mt,updateProperties:vt,diffHydratedProperties:Nt,diffHydratedText:yt,warnForUnmatchedText:function(){},warnForDeletedHydratableElement:function(){},warnForDeletedHydratableText:function(){},warnForInsertedHydratedElement:function(){},warnForInsertedHydratedText:function(){},restoreControlledState:function(n,t,e){switch(t){case"input":if(Nn(n,e),t=e.name,"radio"===e.type&&null!=t){for(e=n;e.parentNode;)e=e.parentNode;for(e=e.querySelectorAll("input[name="+JSON.stringify(""+t)+'][type="radio"]'),t=0;t<e.length;t++){var o=e[t];if(o!==n&&o.form===n.form){var a=C(o);a||r("90"),on(o),Nn(o,a)}}}break;case"textarea":ot(n,e);break;case"select":null!=(t=e.value)&&nt(n,!!e.multiple,t,!1)}}},xu=null,Cu=null,gu=Ka,bu=Xa,Uu=Ya;new Set;var Ru=[],Iu=-1,Qu=Ut(Br),wu=Ut(!1),_u=Br,ku=null,Eu=null,Tu=!1,Su=Ut(null),Pu=Ut(null),Ou=Ut(0),Fu={},Du=Ut(Fu),Au=Ut(Fu),ju=Ut(Fu),Lu={isMounted:function(n){return!!(n=n._reactInternalFiber)&&2===Pn(n)},enqueueSetState:function(n,t,e){n=n._reactInternalFiber;var r=nr();r=Ze(r,n);var o=Gt(r);o.payload=t,void 0!==e&&null!==e&&(o.callback=e),Yt(n,o,r),Je(n,r)},enqueueReplaceState:function(n,t,e){n=n._reactInternalFiber;var r=nr();r=Ze(r,n);var o=Gt(r);o.tag=1,o.payload=t,void 0!==e&&null!==e&&(o.callback=e),Yt(n,o,r),Je(n,r)},enqueueForceUpdate:function(n,t){n=n._reactInternalFiber;var e=nr();e=Ze(e,n);var r=Gt(e);r.tag=2,void 0!==t&&null!==t&&(r.callback=t),Yt(n,r,e),Je(n,e)}},zu=Array.isArray,Bu=ve(!0),Vu=ve(!1),Wu=null,Hu=null,$u=!1,qu=void 0,Ku=void 0,Gu=void 0;qu=function(){},Ku=function(n,t,e){(t.updateQueue=e)&&Se(t)},Gu=function(n,t,e,r){e!==r&&Se(t)};var Xu=gu(),Yu=2,Zu=Xu,Ju=0,ni=0,ti=!1,ei=null,ri=null,oi=0,ai=-1,ui=!1,ii=null,ci=!1,fi=!1,di=null,mi=null,li=null,hi=0,si=void 0,pi=!1,Mi=null,vi=0,Ni=0,yi=!1,xi=!1,Ci=null,gi=null,bi=!1,Ui=!1,Ri=!1,Ii=null,Qi=1e3,wi=0,_i=1,ki={updateContainerAtExpirationTime:Cr,createContainer:function(n,t,e){return Bt(n,t,e)},updateContainer:br,flushRoot:fr,requestWork:or,computeUniqueAsyncExpiration:Ye,batchedUpdates:Mr,unbatchedUpdates:vr,deferredUpdates:tr,syncUpdates:er,interactiveUpdates:yr,flushInteractiveUpdates:function(){pi||0===Ni||(cr(Ni,!1,null),Ni=0)},flushControlled:xr,flushSync:Nr,getPublicRootInstance:Ur,findHostInstance:gr,findHostInstanceWithNoPortals:function(n){return n=An(n),null===n?null:n.stateNode},injectIntoDevTools:Rr};Po.injectFiberControlledHostComponent(yu),Qr.prototype.render=function(n){this._defer||r("250"),this._hasChildren=!0,this._children=n;var t=this._root._internalRoot,e=this._expirationTime,o=new wr;return Cr(n,t,null,e,o._onCommit),o},Qr.prototype.then=function(n){if(this._didComplete)n();else{var t=this._callbacks;null===t&&(t=this._callbacks=[]),t.push(n)}},Qr.prototype.commit=function(){var n=this._root._internalRoot,t=n.firstBatch;if(this._defer&&null!==t||r("251"),this._hasChildren){var e=this._expirationTime;if(t!==this){this._hasChildren&&(e=this._expirationTime=t._expirationTime,this.render(this._children));for(var o=null,a=t;a!==this;)o=a,a=a._next;null===o&&r("251"),o._next=a._next,this._next=t,n.firstBatch=this}this._defer=!1,fr(n,e),t=this._next,this._next=null,t=n.firstBatch=t,null!==t&&t._hasChildren&&t.render(t._children)}else this._next=null,this._defer=!1},Qr.prototype._onComplete=function(){if(!this._didComplete){this._didComplete=!0;var n=this._callbacks;if(null!==n)for(var t=0;t<n.length;t++)(0,n[t])()}},wr.prototype.then=function(n){if(this._didCommit)n();else{var t=this._callbacks;null===t&&(t=this._callbacks=[]),t.push(n)}},wr.prototype._onCommit=function(){if(!this._didCommit){this._didCommit=!0;var n=this._callbacks;if(null!==n)for(var t=0;t<n.length;t++){var e=n[t];"function"!==typeof e&&r("191",e),e()}}},_r.prototype.render=function(n,t){var e=this._internalRoot,r=new wr;return t=void 0===t?null:t,null!==t&&r.then(t),br(n,e,null,r._onCommit),r},_r.prototype.unmount=function(n){var t=this._internalRoot,e=new wr;return n=void 0===n?null:n,null!==n&&e.then(n),br(null,t,null,e._onCommit),e},_r.prototype.legacy_renderSubtreeIntoContainer=function(n,t,e){var r=this._internalRoot,o=new wr;return e=void 0===e?null:e,null!==e&&o.then(e),br(t,r,n,o._onCommit),o},_r.prototype.createBatch=function(){var n=new Qr(this),t=n._expirationTime,e=this._internalRoot,r=e.firstBatch;if(null===r)e.firstBatch=n,n._next=null;else{for(e=null;null!==r&&r._expirationTime<=t;)e=r,r=r._next;n._next=r,null!==e&&(e._next=n)}return n},K=ki.batchedUpdates,G=ki.interactiveUpdates,X=ki.flushInteractiveUpdates;var Ei={createPortal:Sr,findDOMNode:function(n){return null==n?null:1===n.nodeType?n:gr(n)},hydrate:function(n,t,e){return Tr(null,n,t,!0,e)},render:function(n,t,e){return Tr(null,n,t,!1,e)},unstable_renderSubtreeIntoContainer:function(n,t,e,o){return(null==n||void 0===n._reactInternalFiber)&&r("38"),Tr(n,t,e,!1,o)},unmountComponentAtNode:function(n){return kr(n)||r("40"),!!n._reactRootContainer&&(vr(function(){Tr(null,null,n,!1,function(){n._reactRootContainer=null})}),!0)},unstable_createPortal:function(){return Sr.apply(void 0,arguments)},unstable_batchedUpdates:Mr,unstable_deferredUpdates:tr,unstable_interactiveUpdates:yr,flushSync:Nr,unstable_flushControlled:xr,__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED:{EventPluginHub:eo,EventPluginRegistry:Xr,EventPropagators:io,ReactControlledComponent:Do,ReactDOMComponentTree:uo,ReactDOMEventListener:Sa},unstable_createRoot:function(n,t){return new _r(n,!0,null!=t&&!0===t.hydrate)}};Rr({findFiberByHostInstance:y,bundleType:0,version:"16.4.2",rendererPackageName:"react-dom"});var Ti={default:Ei},Si=Ti&&Ei||Ti;n.exports=Si.default?Si.default:Si},function(n,t,e){"use strict";var r=!("undefined"===typeof window||!window.document||!window.document.createElement),o={canUseDOM:r,canUseWorkers:"undefined"!==typeof Worker,canUseEventListeners:r&&!(!window.addEventListener&&!window.attachEvent),canUseViewport:r&&!!window.screen,isInWorker:!r};n.exports=o},function(n,t,e){"use strict";function r(n){if("undefined"===typeof(n=n||("undefined"!==typeof document?document:void 0)))return null;try{return n.activeElement||n.body}catch(t){return n.body}}n.exports=r},function(n,t,e){"use strict";function r(n,t){return n===t?0!==n||0!==t||1/n===1/t:n!==n&&t!==t}function o(n,t){if(r(n,t))return!0;if("object"!==typeof n||null===n||"object"!==typeof t||null===t)return!1;var e=Object.keys(n),o=Object.keys(t);if(e.length!==o.length)return!1;for(var u=0;u<e.length;u++)if(!a.call(t,e[u])||!r(n[e[u]],t[e[u]]))return!1;return!0}var a=Object.prototype.hasOwnProperty;n.exports=o},function(n,t,e){"use strict";function r(n,t){return!(!n||!t)&&(n===t||!o(n)&&(o(t)?r(n,t.parentNode):"contains"in n?n.contains(t):!!n.compareDocumentPosition&&!!(16&n.compareDocumentPosition(t))))}var o=e(21);n.exports=r},function(n,t,e){"use strict";function r(n){return o(n)&&3==n.nodeType}var o=e(22);n.exports=r},function(n,t,e){"use strict";function r(n){var t=n?n.ownerDocument||n:document,e=t.defaultView||window;return!(!n||!("function"===typeof e.Node?n instanceof e.Node:"object"===typeof n&&"number"===typeof n.nodeType&&"string"===typeof n.nodeName))}n.exports=r},function(n,t,e){"use strict";function r(n,t){if(!(n instanceof t))throw new TypeError("Cannot call a class as a function")}function o(n,t){if(!n)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!==typeof t&&"function"!==typeof t?n:t}function a(n,t){if("function"!==typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);n.prototype=Object.create(t&&t.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(n,t):n.__proto__=t)}var u=e(1),i=e.n(u),c=e(24),f=e(25),d=e(26),m=function(){function n(n,t){for(var e=0;e<t.length;e++){var r=t[e];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(n,r.key,r)}}return function(t,e,r){return e&&n(t.prototype,e),r&&n(t,r),t}}(),l=function(n){function t(){return r(this,t),o(this,(t.__proto__||Object.getPrototypeOf(t)).apply(this,arguments))}return a(t,n),m(t,[{key:"render",value:function(){return i.a.createElement("div",{className:"App"},i.a.createElement("header",{className:"App-header"},i.a.createElement("h1",{className:"App-title"},"Welcome to React")),i.a.createElement("p",{className:"App-intro"},"To get started, edit ",i.a.createElement("code",null,"src/App.js")," and save to reload."))}}]),t}(u.Component);window.hitBreakpoint=function(){Object(c.b)(),Object(f.a)(),Object(d.a)(),console.log("hitting a breakpoint")},window.hitDebugStatement=function(){Object(c.a)(),console.log("hitting a debug statement")},t.a=l},function(n,t,e){"use strict";function r(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function o(){return Math.max(Math.random(),Math.random())}function a(){return Math.random()}function u(){return Math.random()}function i(){return isNaN(void 0)}function c(){return Math.max(Math.random(),Math.random())}function f(){return Math.max(Math.random(),Math.random())}function d(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function m(){return Math.max(Math.random(),Math.random())}function l(){return Math.max(Math.random(),Math.random())}function h(){return Math.max(Math.random(),Math.random())}function s(){return Math.max(Math.random(),Math.random())}function p(){r(),o(),a(),u(),i(),c(),f(),d(),m(),l(),h(),s()}function M(){return Math.max(Math.random(),Math.random())}function v(){return Math.random()}function N(){return Math.random()}function y(){return Math.max(Math.random(),Math.random())}function x(){return Math.random()}function C(){return isNaN(void 0)}function g(){return Math.max(Math.random(),Math.random())}function b(){return isNaN(void 0)}function U(){return Math.max(Math.random(),Math.random())}function R(){return Math.max(Math.random(),Math.random())}function I(){return Math.random()}function Q(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function w(){M(),v(),N(),y(),x(),C(),g(),b(),U(),R(),I(),Q()}function _(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function k(){return isNaN(void 0)}function E(){return isNaN(void 0)}function T(){return Math.max(Math.random(),Math.random())}function S(){return Math.random()}function P(){return Math.max(Math.random(),Math.random())}function O(){return Math.max(Math.random(),Math.random())}function F(){return Math.max(Math.random(),Math.random())}function D(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function A(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function j(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function L(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function z(){_(),k(),E(),T(),S(),P(),O(),F(),D(),A(),j(),L()}function B(){return Math.max(Math.random(),Math.random())}function V(){return Math.max(Math.random(),Math.random())}function W(){return Math.max(Math.random(),Math.random())}function H(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function $(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function q(){return isNaN(void 0)}function K(){return isNaN(void 0)}function G(){return isNaN(void 0)}function X(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Y(){return Math.random()}function Z(){return isNaN(void 0)}function J(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function nn(){B(),V(),W(),H(),$(),q(),K(),G(),X(),Y(),Z(),J()}function tn(){return isNaN(void 0)}function en(){return Math.max(Math.random(),Math.random())}function rn(){return Math.random()}function on(){return isNaN(void 0)}function an(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function un(){return isNaN(void 0)}function cn(){return isNaN(void 0)}function fn(){return isNaN(void 0)}function dn(){return isNaN(void 0)}function mn(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function ln(){return Math.random()}function hn(){return isNaN(void 0)}function sn(){tn(),en(),rn(),on(),an(),un(),cn(),fn(),dn(),mn(),ln(),hn()}function pn(){return Math.random()}function Mn(){return Math.random()}function vn(){return Math.max(Math.random(),Math.random())}function Nn(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function yn(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function xn(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Cn(){return Math.random()}function gn(){return isNaN(void 0)}function bn(){return Math.max(Math.random(),Math.random())}function Un(){return Math.max(Math.random(),Math.random())}function Rn(){return isNaN(void 0)}function In(){return Math.random()}function Qn(){pn(),Mn(),vn(),Nn(),yn(),xn(),Cn(),gn(),bn(),Un(),Rn(),In()}function wn(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function _n(){return Math.random()}function kn(){return isNaN(void 0)}function En(){return isNaN(void 0)}function Tn(){return isNaN(void 0)}function Sn(){return Math.random()}function Pn(){return Math.max(Math.random(),Math.random())}function On(){return Math.max(Math.random(),Math.random())}function Fn(){return Math.random()}function Dn(){return Math.max(Math.random(),Math.random())}function An(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function jn(){return Math.max(Math.random(),Math.random())}function Ln(){wn(),_n(),kn(),En(),Tn(),Sn(),Pn(),On(),Fn(),Dn(),An(),jn()}function zn(){return isNaN(void 0)}function Bn(){return Math.random()}function Vn(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Wn(){return Math.random()}function Hn(){return Math.random()}function $n(){return Math.max(Math.random(),Math.random())}function qn(){return Math.random()}function Kn(){return Math.random()}function Gn(){return Math.max(Math.random(),Math.random())}function Xn(){return isNaN(void 0)}function Yn(){return Math.max(Math.random(),Math.random())}function Zn(){return Math.max(Math.random(),Math.random())}function Jn(){zn(),Bn(),Vn(),Wn(),Hn(),$n(),qn(),Kn(),Gn(),Xn(),Yn(),Zn()}function nt(){return Math.random()}function tt(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function et(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function rt(){return Math.random()}function ot(){return isNaN(void 0)}function at(){return Math.random()}function ut(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function it(){return Math.random()}function ct(){return Math.max(Math.random(),Math.random())}function ft(){return Math.max(Math.random(),Math.random())}function dt(){return Math.max(Math.random(),Math.random())}function mt(){return Math.random()}function lt(){nt(),tt(),et(),rt(),ot(),at(),ut(),it(),ct(),ft(),dt(),mt()}function ht(){return Math.max(Math.random(),Math.random())}function st(){return Math.random()}function pt(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Mt(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function vt(){return Math.max(Math.random(),Math.random())}function Nt(){return isNaN(void 0)}function yt(){return Math.random()}function xt(){return Math.random()}function Ct(){return Math.random()}function gt(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function bt(){return Math.random()}function Ut(){return Math.random()}function Rt(){ht(),st(),pt(),Mt(),vt(),Nt(),yt(),xt(),Ct(),gt(),bt(),Ut()}function It(){return Math.random()}function Qt(){return isNaN(void 0)}function wt(){return Math.max(Math.random(),Math.random())}function _t(){return Math.random()}function kt(){return Math.max(Math.random(),Math.random())}function Et(){return isNaN(void 0)}function Tt(){return Math.random()}function St(){return Math.max(Math.random(),Math.random())}function Pt(){return Math.max(Math.random(),Math.random())}function Ot(){return Math.max(Math.random(),Math.random())}function Ft(){return Math.max(Math.random(),Math.random())}function Dt(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function At(){It(),Qt(),wt(),_t(),kt(),Et(),Tt(),St(),Pt(),Ot(),Ft(),Dt()}function jt(){return Math.random()}function Lt(){return Math.max(Math.random(),Math.random())}function zt(){return Math.max(Math.random(),Math.random())}function Bt(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Vt(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Wt(){return isNaN(void 0)}function Ht(){return isNaN(void 0)}function $t(){return Math.max(Math.random(),Math.random())}function qt(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Kt(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Gt(){return Math.random()}function Xt(){return Math.random()}function Yt(){jt(),Lt(),zt(),Bt(),Vt(),Wt(),Ht(),$t(),qt(),Kt(),Gt(),Xt()}function Zt(){p(),w(),z(),nn(),sn(),Qn(),Ln(),Jn(),lt(),Rt(),At(),Yt()}function Jt(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function ne(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function te(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function ee(){return Math.max(Math.random(),Math.random())}function re(){return Math.max(Math.random(),Math.random())}function oe(){return Math.random()}function ae(){return isNaN(void 0)}function ue(){return Math.random()}function ie(){return isNaN(void 0)}function ce(){return Math.max(Math.random(),Math.random())}function fe(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function de(){return Math.random()}function me(){Jt(),ne(),te(),ee(),re(),oe(),ae(),ue(),ie(),ce(),fe(),de()}function le(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function he(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function se(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function pe(){return isNaN(void 0)}function Me(){return Math.random()}function ve(){return isNaN(void 0)}function Ne(){return isNaN(void 0)}function ye(){return Math.max(Math.random(),Math.random())}function xe(){return Math.random()}function Ce(){return Math.random()}function ge(){return Math.random()}function be(){return Math.random()}function Ue(){le(),he(),se(),pe(),Me(),ve(),Ne(),ye(),xe(),Ce(),ge(),be()}function Re(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Ie(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Qe(){return Math.max(Math.random(),Math.random())}function we(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function _e(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function ke(){return Math.random()}function Ee(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Te(){return Math.max(Math.random(),Math.random())}function Se(){return isNaN(void 0)}function Pe(){return Math.random()}function Oe(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Fe(){return Math.random()}function De(){Re(),Ie(),Qe(),we(),_e(),ke(),Ee(),Te(),Se(),Pe(),Oe(),Fe()}function Ae(){return isNaN(void 0)}function je(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Le(){return isNaN(void 0)}function ze(){return Math.max(Math.random(),Math.random())}function Be(){return isNaN(void 0)}function Ve(){return Math.random()}function We(){return Math.random()}function He(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function $e(){return Math.max(Math.random(),Math.random())}function qe(){return Math.max(Math.random(),Math.random())}function Ke(){return Math.random()}function Ge(){return Math.max(Math.random(),Math.random())}function Xe(){Ae(),je(),Le(),ze(),Be(),Ve(),We(),He(),$e(),qe(),Ke(),Ge()}function Ye(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Ze(){return isNaN(void 0)}function Je(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function nr(){return isNaN(void 0)}function tr(){return isNaN(void 0)}function er(){return isNaN(void 0)}function rr(){return isNaN(void 0)}function or(){return Math.random()}function ar(){return Math.max(Math.random(),Math.random())}function ur(){return isNaN(void 0)}function ir(){return Math.max(Math.random(),Math.random())}function cr(){return Math.random()}function fr(){Ye(),Ze(),Je(),nr(),tr(),er(),rr(),or(),ar(),ur(),ir(),cr()}function dr(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function mr(){return isNaN(void 0)}function lr(){return Math.max(Math.random(),Math.random())}function hr(){return Math.max(Math.random(),Math.random())}function sr(){return Math.max(Math.random(),Math.random())}function pr(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Mr(){return Math.max(Math.random(),Math.random())}function vr(){return isNaN(void 0)}function Nr(){return isNaN(void 0)}function yr(){return Math.random()}function xr(){return Math.max(Math.random(),Math.random())}function Cr(){return isNaN(void 0)}function gr(){dr(),mr(),lr(),hr(),sr(),pr(),Mr(),vr(),Nr(),yr(),xr(),Cr()}function br(){return Math.max(Math.random(),Math.random())}function Ur(){return isNaN(void 0)}function Rr(){return isNaN(void 0)}function Ir(){return isNaN(void 0)}function Qr(){return isNaN(void 0)}function wr(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function _r(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function kr(){return Math.max(Math.random(),Math.random())}function Er(){return isNaN(void 0)}function Tr(){return Math.max(Math.random(),Math.random())}function Sr(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Pr(){return Math.max(Math.random(),Math.random())}function Or(){br(),Ur(),Rr(),Ir(),Qr(),wr(),_r(),kr(),Er(),Tr(),Sr(),Pr()}function Fr(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Dr(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Ar(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function jr(){return Math.random()}function Lr(){return Math.max(Math.random(),Math.random())}function zr(){return isNaN(void 0)}function Br(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Vr(){return Math.max(Math.random(),Math.random())}function Wr(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Hr(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function $r(){return Math.max(Math.random(),Math.random())}function qr(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Kr(){Fr(),Dr(),Ar(),jr(),Lr(),zr(),Br(),Vr(),Wr(),Hr(),$r(),qr()}function Gr(){return Math.max(Math.random(),Math.random())}function Xr(){return isNaN(void 0)}function Yr(){return Math.random()}function Zr(){return isNaN(void 0)}function Jr(){return isNaN(void 0)}function no(){return isNaN(void 0)}function to(){return isNaN(void 0)}function eo(){return Math.random()}function ro(){return Math.max(Math.random(),Math.random())}function oo(){return isNaN(void 0)}function ao(){return isNaN(void 0)}function uo(){return Math.max(Math.random(),Math.random())}function io(){Gr(),Xr(),Yr(),Zr(),Jr(),no(),to(),eo(),ro(),oo(),ao(),uo()}function co(){return isNaN(void 0)}function fo(){return isNaN(void 0)}function mo(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function lo(){return isNaN(void 0)}function ho(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function so(){return isNaN(void 0)}function po(){return Math.max(Math.random(),Math.random())}function Mo(){return Math.random()}function vo(){return isNaN(void 0)}function No(){return Math.random()}function yo(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function xo(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Co(){co(),fo(),mo(),lo(),ho(),so(),po(),Mo(),vo(),No(),yo(),xo()}function go(){return isNaN(void 0)}function bo(){return isNaN(void 0)}function Uo(){return Math.max(Math.random(),Math.random())}function Ro(){return Math.random()}function Io(){return Math.max(Math.random(),Math.random())}function Qo(){return Math.random()}function wo(){return Math.max(Math.random(),Math.random())}function _o(){return Math.max(Math.random(),Math.random())}function ko(){return isNaN(void 0)}function Eo(){return isNaN(void 0)}function To(){return isNaN(void 0)}function So(){return isNaN(void 0)}function Po(){go(),bo(),Uo(),Ro(),Io(),Qo(),wo(),_o(),ko(),Eo(),To(),So()}function Oo(){return Math.random()}function Fo(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Do(){return Math.random()}function Ao(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function jo(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Lo(){return Math.max(Math.random(),Math.random())}function zo(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Bo(){return Math.max(Math.random(),Math.random())}function Vo(){return Math.random()}function Wo(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Ho(){return Math.max(Math.random(),Math.random())}function $o(){return Math.max(Math.random(),Math.random())}function qo(){Oo(),Fo(),Do(),Ao(),jo(),Lo(),zo(),Bo(),Vo(),Wo(),Ho(),$o()}function Ko(){me(),Ue(),De(),Xe(),fr(),gr(),Or(),Kr(),io(),Co(),Po(),qo()}function Go(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Xo(){return Math.random()}function Yo(){return Math.max(Math.random(),Math.random())}function Zo(){return isNaN(void 0)}function Jo(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function na(){return Math.random()}function ta(){return Math.max(Math.random(),Math.random())}function ea(){return Math.random()}function ra(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function oa(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function aa(){return isNaN(void 0)}function ua(){return isNaN(void 0)}function ia(){Go(),Xo(),Yo(),Zo(),Jo(),na(),ta(),ea(),ra(),oa(),aa(),ua()}function ca(){return Math.max(Math.random(),Math.random())}function fa(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function da(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function ma(){return isNaN(void 0)}function la(){return Math.max(Math.random(),Math.random())}function ha(){return Math.max(Math.random(),Math.random())}function sa(){return isNaN(void 0)}function pa(){return Math.max(Math.random(),Math.random())}function Ma(){return isNaN(void 0)}function va(){return Math.max(Math.random(),Math.random())}function Na(){return isNaN(void 0)}function ya(){return isNaN(void 0)}function xa(){ca(),fa(),da(),ma(),la(),ha(),sa(),pa(),Ma(),va(),Na(),ya()}function Ca(){return Math.random()}function ga(){return Math.random()}function ba(){return Math.max(Math.random(),Math.random())}function Ua(){return Math.max(Math.random(),Math.random())}function Ra(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Ia(){return Math.random()}function Qa(){return Math.max(Math.random(),Math.random())}function wa(){return Math.max(Math.random(),Math.random())}function _a(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function ka(){return Math.random()}function Ea(){return Math.random()}function Ta(){return isNaN(void 0)}function Sa(){Ca(),ga(),ba(),Ua(),Ra(),Ia(),Qa(),wa(),_a(),ka(),Ea(),Ta()}function Pa(){return Math.random()}function Oa(){return Math.random()}function Fa(){return Math.random()}function Da(){return Math.max(Math.random(),Math.random())}function Aa(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function ja(){return Math.max(Math.random(),Math.random())}function La(){return isNaN(void 0)}function za(){return isNaN(void 0)}function Ba(){return Math.max(Math.random(),Math.random())}function Va(){return Math.random()}function Wa(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Ha(){return isNaN(void 0)}function $a(){Pa(),Oa(),Fa(),Da(),Aa(),ja(),La(),za(),Ba(),Va(),Wa(),Ha()}function qa(){return Math.max(Math.random(),Math.random())}function Ka(){return Math.random()}function Ga(){return Math.random()}function Xa(){return isNaN(void 0)}function Ya(){return isNaN(void 0)}function Za(){return Math.max(Math.random(),Math.random())}function Ja(){return Math.random()}function nu(){return Math.max(Math.random(),Math.random())}function tu(){return Math.random()}function eu(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function ru(){return isNaN(void 0)}function ou(){return isNaN(void 0)}function au(){qa(),Ka(),Ga(),Xa(),Ya(),Za(),Ja(),nu(),tu(),eu(),ru(),ou()}function uu(){return Math.max(Math.random(),Math.random())}function iu(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function cu(){return Math.random()}function fu(){return Math.random()}function du(){return isNaN(void 0)}function mu(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function lu(){return Math.max(Math.random(),Math.random())}function hu(){return isNaN(void 0)}function su(){return Math.max(Math.random(),Math.random())}function pu(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Mu(){return Math.random()}function vu(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Nu(){uu(),iu(),cu(),fu(),du(),mu(),lu(),hu(),su(),pu(),Mu(),vu()}function yu(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function xu(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Cu(){return Math.random()}function gu(){return Math.random()}function bu(){return Math.random()}function Uu(){return Math.max(Math.random(),Math.random())}function Ru(){return Math.random()}function Iu(){return Math.max(Math.random(),Math.random())}function Qu(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function wu(){return Math.random()}function _u(){return isNaN(void 0)}function ku(){return Math.max(Math.random(),Math.random())}function Eu(){yu(),xu(),Cu(),gu(),bu(),Uu(),Ru(),Iu(),Qu(),wu(),_u(),ku()}function Tu(){return Math.max(Math.random(),Math.random())}function Su(){return Math.max(Math.random(),Math.random())}function Pu(){return isNaN(void 0)}function Ou(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Fu(){return Math.max(Math.random(),Math.random())}function Du(){return isNaN(void 0)}function Au(){return Math.max(Math.random(),Math.random())}function ju(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Lu(){return isNaN(void 0)}function zu(){return Math.random()}function Bu(){return Math.max(Math.random(),Math.random())}function Vu(){return Math.max(Math.random(),Math.random())}function Wu(){Tu(),Su(),Pu(),Ou(),Fu(),Du(),Au(),ju(),Lu(),zu(),Bu(),Vu()}function Hu(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function $u(){return Math.random()}function qu(){return isNaN(void 0)}function Ku(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Gu(){return Math.max(Math.random(),Math.random())}function Xu(){return isNaN(void 0)}function Yu(){return Math.random()}function Zu(){return isNaN(void 0)}function Ju(){return Math.random()}function ni(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function ti(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function ei(){return Math.max(Math.random(),Math.random())}function ri(){Hu(),$u(),qu(),Ku(),Gu(),Xu(),Yu(),Zu(),Ju(),ni(),ti(),ei()}function oi(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function ai(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function ui(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function ii(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function ci(){return isNaN(void 0)}function fi(){return Math.max(Math.random(),Math.random())}function di(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function mi(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function li(){return Math.random()}function hi(){return Math.random()}function si(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function pi(){return isNaN(void 0)}function Mi(){oi(),ai(),ui(),ii(),ci(),fi(),di(),mi(),li(),hi(),si(),pi()}function vi(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Ni(){return Math.random()}function yi(){return isNaN(void 0)}function xi(){return isNaN(void 0)}function Ci(){return isNaN(void 0)}function gi(){return isNaN(void 0)}function bi(){return isNaN(void 0)}function Ui(){return Math.random()}function Ri(){return Math.max(Math.random(),Math.random())}function Ii(){return Math.max(Math.random(),Math.random())}function Qi(){return Math.max(Math.random(),Math.random())}function wi(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function _i(){vi(),Ni(),yi(),xi(),Ci(),gi(),bi(),Ui(),Ri(),Ii(),Qi(),wi()}function ki(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Ei(){return Math.random()}function Ti(){return Math.random()}function Si(){return Math.max(Math.random(),Math.random())}function Pi(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Oi(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Fi(){return isNaN(void 0)}function Di(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Ai(){return Math.max(Math.random(),Math.random())}function ji(){return isNaN(void 0)}function Li(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function zi(){return isNaN(void 0)}function Bi(){ki(),Ei(),Ti(),Si(),Pi(),Oi(),Fi(),Di(),Ai(),ji(),Li(),zi()}function Vi(){ia(),xa(),Sa(),$a(),au(),Nu(),Eu(),Wu(),ri(),Mi(),_i(),Bi()}function Wi(){return Math.random()}function Hi(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function $i(){return Math.max(Math.random(),Math.random())}function qi(){return isNaN(void 0)}function Ki(){return Math.random()}function Gi(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Xi(){return Math.max(Math.random(),Math.random())}function Yi(){return Math.max(Math.random(),Math.random())}function Zi(){return Math.max(Math.random(),Math.random())}function Ji(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function nc(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function tc(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function ec(){Wi(),Hi(),$i(),qi(),Ki(),Gi(),Xi(),Yi(),Zi(),Ji(),nc(),tc()}function rc(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function oc(){return isNaN(void 0)}function ac(){return Math.random()}function uc(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function ic(){return isNaN(void 0)}function cc(){return Math.random()}function fc(){return Math.max(Math.random(),Math.random())}function dc(){return isNaN(void 0)}function mc(){return Math.random()}function lc(){return Math.random()}function hc(){return Math.random()}function sc(){return Math.random()}function pc(){rc(),oc(),ac(),uc(),ic(),cc(),fc(),dc(),mc(),lc(),hc(),sc()}function Mc(){return Math.random()}function vc(){return Math.max(Math.random(),Math.random())}function Nc(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function yc(){return isNaN(void 0)}function xc(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Cc(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function gc(){return Math.max(Math.random(),Math.random())}function bc(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Uc(){return Math.max(Math.random(),Math.random())}function Rc(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Ic(){return isNaN(void 0)}function Qc(){return Math.random()}function wc(){Mc(),vc(),Nc(),yc(),xc(),Cc(),gc(),bc(),Uc(),Rc(),Ic(),Qc()}function _c(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function kc(){return Math.max(Math.random(),Math.random())}function Ec(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Tc(){return Math.max(Math.random(),Math.random())}function Sc(){return isNaN(void 0)}function Pc(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Oc(){return Math.random()}function Fc(){return isNaN(void 0)}function Dc(){return isNaN(void 0)}function Ac(){return isNaN(void 0)}function jc(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Lc(){return Math.random()}function zc(){_c(),kc(),Ec(),Tc(),Sc(),Pc(),Oc(),Fc(),Dc(),Ac(),jc(),Lc()}function Bc(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Vc(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Wc(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Hc(){return Math.random()}function $c(){return Math.max(Math.random(),Math.random())}function qc(){return Math.random()}function Kc(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Gc(){return Math.random()}function Xc(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Yc(){return Math.random()}function Zc(){return Math.random()}function Jc(){return Math.random()}function nf(){Bc(),Vc(),Wc(),Hc(),$c(),qc(),Kc(),Gc(),Xc(),Yc(),Zc(),Jc()}function tf(){return Math.random()}function ef(){return Math.max(Math.random(),Math.random())}function rf(){return isNaN(void 0)}function of(){return isNaN(void 0)}function af(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function uf(){return Math.random()}function cf(){return Math.max(Math.random(),Math.random())}function ff(){return Math.random()}function df(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function mf(){return isNaN(void 0)}function lf(){return Math.random()}function hf(){return Math.max(Math.random(),Math.random())}function sf(){tf(),ef(),rf(),of(),af(),uf(),cf(),ff(),df(),mf(),lf(),hf()}function pf(){return Math.max(Math.random(),Math.random())}function Mf(){return isNaN(void 0)}function vf(){return Math.random()}function Nf(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function yf(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function xf(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Cf(){return isNaN(void 0)}function gf(){return Math.max(Math.random(),Math.random())}function bf(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Uf(){return isNaN(void 0)}function Rf(){return Math.random()}function If(){return Math.max(Math.random(),Math.random())}function Qf(){pf(),Mf(),vf(),Nf(),yf(),xf(),Cf(),gf(),bf(),Uf(),Rf(),If()}function wf(){return isNaN(void 0)}function _f(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function kf(){return Math.random()}function Ef(){return isNaN(void 0)}function Tf(){return isNaN(void 0)}function Sf(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Pf(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Of(){return isNaN(void 0)}function Ff(){return Math.random()}function Df(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Af(){return isNaN(void 0)}function jf(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Lf(){wf(),_f(),kf(),Ef(),Tf(),Sf(),Pf(),Of(),Ff(),Df(),Af(),jf()}function zf(){return Math.random()}function Bf(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Vf(){return isNaN(void 0)}function Wf(){return Math.random()}function Hf(){return Math.random()}function $f(){return Math.max(Math.random(),Math.random())}function qf(){return Math.max(Math.random(),Math.random())}function Kf(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Gf(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Xf(){return Math.random()}function Yf(){return Math.max(Math.random(),Math.random())}function Zf(){return Math.random()}function Jf(){zf(),Bf(),Vf(),Wf(),Hf(),$f(),qf(),Kf(),Gf(),Xf(),Yf(),Zf()}function nd(){return isNaN(void 0)}function td(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function ed(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function rd(){return Math.max(Math.random(),Math.random())}function od(){return isNaN(void 0)}function ad(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function ud(){return Math.max(Math.random(),Math.random())}function id(){return Math.random()}function cd(){return Math.max(Math.random(),Math.random())}function fd(){return Math.random()}function dd(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function md(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function ld(){nd(),td(),ed(),rd(),od(),ad(),ud(),id(),cd(),fd(),dd(),md()}function hd(){return Math.max(Math.random(),Math.random())}function sd(){return Math.max(Math.random(),Math.random())}function pd(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Md(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function vd(){return isNaN(void 0)}function Nd(){return Math.random()}function yd(){return isNaN(void 0)}function xd(){return isNaN(void 0)}function Cd(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function gd(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function bd(){return isNaN(void 0)}function Ud(){return Math.max(Math.random(),Math.random())}function Rd(){hd(),sd(),pd(),Md(),vd(),Nd(),yd(),xd(),Cd(),gd(),bd(),Ud()}function Id(){return isNaN(void 0)}function Qd(){return Math.max(Math.random(),Math.random())}function wd(){return Math.max(Math.random(),Math.random())}function _d(){return isNaN(void 0)}function kd(){return isNaN(void 0)}function Ed(){return Math.max(Math.random(),Math.random())}function Td(){return Math.max(Math.random(),Math.random())}function Sd(){return Math.random()}function Pd(){return Math.random()}function Od(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Fd(){return Math.max(Math.random(),Math.random())}function Dd(){return Math.random()}function Ad(){Id(),Qd(),wd(),_d(),kd(),Ed(),Td(),Sd(),Pd(),Od(),Fd(),Dd()}function jd(){ec(),pc(),wc(),zc(),nf(),sf(),Qf(),Lf(),Jf(),ld(),Rd(),Ad()}function Ld(){return Math.max(Math.random(),Math.random())}function zd(){return Math.max(Math.random(),Math.random())}function Bd(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Vd(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Wd(){return Math.random()}function Hd(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function $d(){return isNaN(void 0)}function qd(){return isNaN(void 0)}function Kd(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Gd(){return Math.random()}function Xd(){return Math.max(Math.random(),Math.random())}function Yd(){return Math.max(Math.random(),Math.random())}function Zd(){Ld(),zd(),Bd(),Vd(),Wd(),Hd(),$d(),qd(),Kd(),Gd(),Xd(),Yd()}function Jd(){return Math.max(Math.random(),Math.random())}function nm(){return Math.random()}function tm(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function em(){return Math.max(Math.random(),Math.random())}function rm(){return isNaN(void 0)}function om(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function am(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function um(){return Math.max(Math.random(),Math.random())}function im(){return isNaN(void 0)}function cm(){return Math.max(Math.random(),Math.random())}function fm(){return isNaN(void 0)}function dm(){return Math.max(Math.random(),Math.random())}function mm(){Jd(),nm(),tm(),em(),rm(),om(),am(),um(),im(),cm(),fm(),dm()}function lm(){return Math.random()}function hm(){return Math.random()}function sm(){return isNaN(void 0)}function pm(){return isNaN(void 0)}function Mm(){return isNaN(void 0)}function vm(){return Math.max(Math.random(),Math.random())}function Nm(){return Math.max(Math.random(),Math.random())}function ym(){return Math.random()}function xm(){return Math.random()}function Cm(){return isNaN(void 0)}function gm(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function bm(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Um(){lm(),hm(),sm(),pm(),Mm(),vm(),Nm(),ym(),xm(),Cm(),gm(),bm()}function Rm(){return isNaN(void 0)}function Im(){return Math.max(Math.random(),Math.random())}function Qm(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function wm(){return isNaN(void 0)}function _m(){return Math.max(Math.random(),Math.random())}function km(){return isNaN(void 0)}function Em(){return Math.random()}function Tm(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Sm(){return Math.max(Math.random(),Math.random())}function Pm(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Om(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Fm(){return Math.max(Math.random(),Math.random())}function Dm(){Rm(),Im(),Qm(),wm(),_m(),km(),Em(),Tm(),Sm(),Pm(),Om(),Fm()}function Am(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function jm(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Lm(){return isNaN(void 0)}function zm(){return Math.max(Math.random(),Math.random())}function Bm(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Vm(){return isNaN(void 0)}function Wm(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Hm(){return Math.random()}function $m(){return isNaN(void 0)}function qm(){return Math.max(Math.random(),Math.random())}function Km(){return isNaN(void 0)}function Gm(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Xm(){Am(),jm(),Lm(),zm(),Bm(),Vm(),Wm(),Hm(),$m(),qm(),Km(),Gm()}function Ym(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Zm(){return Math.max(Math.random(),Math.random())}function Jm(){return Math.max(Math.random(),Math.random())}function nl(){return isNaN(void 0)}function tl(){return Math.random()}function el(){return Math.max(Math.random(),Math.random())}function rl(){return isNaN(void 0)}function ol(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function al(){return Math.random()}function ul(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function il(){return Math.max(Math.random(),Math.random())}function cl(){return Math.max(Math.random(),Math.random())}function fl(){Ym(),Zm(),Jm(),nl(),tl(),el(),rl(),ol(),al(),ul(),il(),cl()}function dl(){return Math.random()}function ml(){return Math.max(Math.random(),Math.random())}function ll(){return Math.max(Math.random(),Math.random())}function hl(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function sl(){return Math.max(Math.random(),Math.random())}function pl(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Ml(){return Math.max(Math.random(),Math.random())}function vl(){return Math.random()}function Nl(){return isNaN(void 0)}function yl(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function xl(){return Math.max(Math.random(),Math.random())}function Cl(){return Math.random()}function gl(){dl(),ml(),ll(),hl(),sl(),pl(),Ml(),vl(),Nl(),yl(),xl(),Cl()}function bl(){return Math.max(Math.random(),Math.random())}function Ul(){return Math.random()}function Rl(){return Math.max(Math.random(),Math.random())}function Il(){return isNaN(void 0)}function Ql(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function wl(){return Math.max(Math.random(),Math.random())}function _l(){return Math.max(Math.random(),Math.random())}function kl(){return isNaN(void 0)}function El(){return Math.max(Math.random(),Math.random())}function Tl(){return Math.random()}function Sl(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Pl(){return isNaN(void 0)}function Ol(){bl(),Ul(),Rl(),Il(),Ql(),wl(),_l(),kl(),El(),Tl(),Sl(),Pl()}function Fl(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Dl(){return Math.max(Math.random(),Math.random())}function Al(){return Math.random()}function jl(){return Math.max(Math.random(),Math.random())}function Ll(){return Math.random()}function zl(){return isNaN(void 0)}function Bl(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Vl(){return Math.random()}function Wl(){return Math.max(Math.random(),Math.random())}function Hl(){return isNaN(void 0)}function $l(){return Math.random()}function ql(){return isNaN(void 0)}function Kl(){Fl(),Dl(),Al(),jl(),Ll(),zl(),Bl(),Vl(),Wl(),Hl(),$l(),ql()}function Gl(){return Math.max(Math.random(),Math.random())}function Xl(){return Math.random()}function Yl(){return Math.random()}function Zl(){return Math.max(Math.random(),Math.random())}function Jl(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function nh(){return isNaN(void 0)}function th(){return isNaN(void 0)}function eh(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function rh(){return Math.random()}function oh(){return Math.random()}function ah(){return Math.max(Math.random(),Math.random())}function uh(){return Math.random()}function ih(){Gl(),Xl(),Yl(),Zl(),Jl(),nh(),th(),eh(),rh(),oh(),ah(),uh()}function ch(){return isNaN(void 0)}function fh(){return isNaN(void 0)}function dh(){return Math.max(Math.random(),Math.random())}function mh(){return Math.random()}function lh(){return Math.random()}function hh(){return Math.random()}function sh(){return isNaN(void 0)}function ph(){return isNaN(void 0)}function Mh(){return Math.random()}function vh(){return Math.random()}function Nh(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function yh(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function xh(){ch(),fh(),dh(),mh(),lh(),hh(),sh(),ph(),Mh(),vh(),Nh(),yh()}function Ch(){return isNaN(void 0)}function gh(){return Math.max(Math.random(),Math.random())}function bh(){return Math.max(Math.random(),Math.random())}function Uh(){return isNaN(void 0)}function Rh(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Ih(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Qh(){return isNaN(void 0)}function wh(){return isNaN(void 0)}function _h(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function kh(){return Math.max(Math.random(),Math.random())}function Eh(){return isNaN(void 0)}function Th(){return isNaN(void 0)}function Sh(){Ch(),gh(),bh(),Uh(),Rh(),Ih(),Qh(),wh(),_h(),kh(),Eh(),Th()}function Ph(){Zd(),mm(),Um(),Dm(),Xm(),fl(),gl(),Ol(),Kl(),ih(),xh(),Sh()}function Oh(){return Math.max(Math.random(),Math.random())}function Fh(){return Math.random()}function Dh(){return isNaN(void 0)}function Ah(){return Math.random()}function jh(){return Math.max(Math.random(),Math.random())}function Lh(){return isNaN(void 0)}function zh(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Bh(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Vh(){return Math.max(Math.random(),Math.random())}function Wh(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Hh(){return Math.random()}function $h(){return isNaN(void 0)}function qh(){Oh(),Fh(),Dh(),Ah(),jh(),Lh(),zh(),Bh(),Vh(),Wh(),Hh(),$h()}function Kh(){return Math.max(Math.random(),Math.random())}function Gh(){return isNaN(void 0)}function Xh(){return Math.random()}function Yh(){return isNaN(void 0)}function Zh(){return Math.random()}function Jh(){return Math.max(Math.random(),Math.random())}function ns(){return isNaN(void 0)}function ts(){return isNaN(void 0)}function es(){return Math.random()}function rs(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function os(){return Math.max(Math.random(),Math.random())}function as(){return Math.max(Math.random(),Math.random())}function us(){Kh(),Gh(),Xh(),Yh(),Zh(),Jh(),ns(),ts(),es(),rs(),os(),as()}function is(){return isNaN(void 0)}function cs(){return isNaN(void 0)}function fs(){return Math.random()}function ds(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function ms(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function ls(){return Math.max(Math.random(),Math.random())}function hs(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function ss(){return Math.random()}function ps(){return Math.max(Math.random(),Math.random())}function Ms(){return isNaN(void 0)}function vs(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Ns(){return isNaN(void 0)}function ys(){is(),cs(),fs(),ds(),ms(),ls(),hs(),ss(),ps(),Ms(),vs(),Ns()}function xs(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Cs(){return isNaN(void 0)}function gs(){return Math.random()}function bs(){return isNaN(void 0)}function Us(){return Math.max(Math.random(),Math.random())}function Rs(){return Math.max(Math.random(),Math.random())}function Is(){return isNaN(void 0)}function Qs(){return Math.max(Math.random(),Math.random())}function ws(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function _s(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function ks(){return Math.max(Math.random(),Math.random())}function Es(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Ts(){xs(),Cs(),gs(),bs(),Us(),Rs(),Is(),Qs(),ws(),_s(),ks(),Es()}function Ss(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Ps(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Os(){return Math.random()}function Fs(){return Math.random()}function Ds(){return Math.random()}function As(){return Math.random()}function js(){return Math.random()}function Ls(){return Math.random()}function zs(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Bs(){return Math.random()}function Vs(){return isNaN(void 0)}function Ws(){return Math.max(Math.random(),Math.random())}function Hs(){Ss(),Ps(),Os(),Fs(),Ds(),As(),js(),Ls(),zs(),Bs(),Vs(),Ws()}function $s(){return isNaN(void 0)}function qs(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Ks(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Gs(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Xs(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Ys(){return isNaN(void 0)}function Zs(){return Math.random()}function Js(){return Math.random()}function np(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function tp(){return Math.random()}function ep(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function rp(){return Math.random()}function op(){$s(),qs(),Ks(),Gs(),Xs(),Ys(),Zs(),Js(),np(),tp(),ep(),rp()}function ap(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function up(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function ip(){return Math.random()}function cp(){return isNaN(void 0)}function fp(){return Math.random()}function dp(){return Math.max(Math.random(),Math.random())}function mp(){return Math.random()}function lp(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function hp(){return isNaN(void 0)}function sp(){return isNaN(void 0)}function pp(){return Math.random()}function Mp(){return Math.random()}function vp(){ap(),up(),ip(),cp(),fp(),dp(),mp(),lp(),hp(),sp(),pp(),Mp()}function Np(){return Math.max(Math.random(),Math.random())}function yp(){return Math.max(Math.random(),Math.random())}function xp(){return Math.random()}function Cp(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function gp(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function bp(){return Math.random()}function Up(){return isNaN(void 0)}function Rp(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Ip(){return Math.random()}function Qp(){return Math.max(Math.random(),Math.random())}function wp(){return Math.random()}function _p(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function kp(){Np(),yp(),xp(),Cp(),gp(),bp(),Up(),Rp(),Ip(),Qp(),wp(),_p()}function Ep(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Tp(){return Math.max(Math.random(),Math.random())}function Sp(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Pp(){return Math.random()}function Op(){return Math.max(Math.random(),Math.random())}function Fp(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Dp(){return Math.random()}function Ap(){return Math.random()}function jp(){return isNaN(void 0)}function Lp(){return Math.random()}function zp(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Bp(){return isNaN(void 0)}function Vp(){Ep(),Tp(),Sp(),Pp(),Op(),Fp(),Dp(),Ap(),jp(),Lp(),zp(),Bp()}function Wp(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Hp(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function $p(){return Math.max(Math.random(),Math.random())}function qp(){return Math.max(Math.random(),Math.random())}function Kp(){return Math.max(Math.random(),Math.random())}function Gp(){return Math.max(Math.random(),Math.random())}function Xp(){return Math.max(Math.random(),Math.random())}function Yp(){return Math.random()}function Zp(){return Math.max(Math.random(),Math.random())}function Jp(){return Math.random()}function nM(){return Math.random()}function tM(){return isNaN(void 0)}function eM(){Wp(),Hp(),$p(),qp(),Kp(),Gp(),Xp(),Yp(),Zp(),Jp(),nM(),tM()}function rM(){return isNaN(void 0)}function oM(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function aM(){return isNaN(void 0)}function uM(){return Math.max(Math.random(),Math.random())}function iM(){return Math.random()}function cM(){return Math.random()}function fM(){return Math.random()}function dM(){return Math.max(Math.random(),Math.random())}function mM(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function lM(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function hM(){return Math.max(Math.random(),Math.random())}function sM(){return Math.random()}function pM(){rM(),oM(),aM(),uM(),iM(),cM(),fM(),dM(),mM(),lM(),hM(),sM()}function MM(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function vM(){return Math.max(Math.random(),Math.random())}function NM(){return Math.random()}function yM(){return Math.random()}function xM(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function CM(){return Math.random()}function gM(){return Math.random()}function bM(){return isNaN(void 0)}function UM(){return isNaN(void 0)}function RM(){return Math.max(Math.random(),Math.random())}function IM(){return Math.max(Math.random(),Math.random())}function QM(){return isNaN(void 0)}function wM(){MM(),vM(),NM(),yM(),xM(),CM(),gM(),bM(),UM(),RM(),IM(),QM()}function _M(){qh(),us(),ys(),Ts(),Hs(),op(),vp(),kp(),Vp(),eM(),pM(),wM()}function kM(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function EM(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function TM(){return Math.max(Math.random(),Math.random())}function SM(){return Math.random()}function PM(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function OM(){return isNaN(void 0)}function FM(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function DM(){return Math.random()}function AM(){return isNaN(void 0)}function jM(){return isNaN(void 0)}function LM(){return Math.max(Math.random(),Math.random())}function zM(){return isNaN(void 0)}function BM(){kM(),EM(),TM(),SM(),PM(),OM(),FM(),DM(),AM(),jM(),LM(),zM()}function VM(){return isNaN(void 0)}function WM(){return Math.max(Math.random(),Math.random())}function HM(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function $M(){return Math.max(Math.random(),Math.random())}function qM(){return Math.random()}function KM(){return isNaN(void 0)}function GM(){return isNaN(void 0)}function XM(){return isNaN(void 0)}function YM(){return Math.random()}function ZM(){return Math.max(Math.random(),Math.random())}function JM(){return Math.random()}function nv(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function tv(){VM(),WM(),HM(),$M(),qM(),KM(),GM(),XM(),YM(),ZM(),JM(),nv()}function ev(){return isNaN(void 0)}function rv(){return Math.random()}function ov(){return isNaN(void 0)}function av(){return Math.max(Math.random(),Math.random())}function uv(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function iv(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function cv(){return Math.max(Math.random(),Math.random())}function fv(){return Math.max(Math.random(),Math.random())}function dv(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function mv(){return Math.random()}function lv(){return Math.max(Math.random(),Math.random())}function hv(){return isNaN(void 0)}function sv(){ev(),rv(),ov(),av(),uv(),iv(),cv(),fv(),dv(),mv(),lv(),hv()}function pv(){return Math.random()}function Mv(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function vv(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Nv(){return isNaN(void 0)}function yv(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function xv(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Cv(){return Math.random()}function gv(){return isNaN(void 0)}function bv(){return Math.max(Math.random(),Math.random())}function Uv(){return Math.max(Math.random(),Math.random())}function Rv(){return Math.max(Math.random(),Math.random())}function Iv(){return Math.random()}function Qv(){pv(),Mv(),vv(),Nv(),yv(),xv(),Cv(),gv(),bv(),Uv(),Rv(),Iv()}function wv(){return Math.max(Math.random(),Math.random())}function _v(){return Math.random()}function kv(){return isNaN(void 0)}function Ev(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Tv(){return Math.max(Math.random(),Math.random())}function Sv(){return Math.max(Math.random(),Math.random())}function Pv(){return Math.max(Math.random(),Math.random())}function Ov(){return Math.random()}function Fv(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Dv(){return isNaN(void 0)}function Av(){return isNaN(void 0)}function jv(){return Math.max(Math.random(),Math.random())}function Lv(){wv(),_v(),kv(),Ev(),Tv(),Sv(),Pv(),Ov(),Fv(),Dv(),Av(),jv()}function zv(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Bv(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Vv(){return isNaN(void 0)}function Wv(){return isNaN(void 0)}function Hv(){return Math.random()}function $v(){return Math.max(Math.random(),Math.random())}function qv(){return Math.max(Math.random(),Math.random())}function Kv(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Gv(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Xv(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Yv(){return isNaN(void 0)}function Zv(){return Math.max(Math.random(),Math.random())}function Jv(){zv(),Bv(),Vv(),Wv(),Hv(),$v(),qv(),Kv(),Gv(),Xv(),Yv(),Zv()}function nN(){return Math.max(Math.random(),Math.random())}function tN(){return Math.max(Math.random(),Math.random())}function eN(){return Math.max(Math.random(),Math.random())}function rN(){return Math.random()}function oN(){return isNaN(void 0)}function aN(){return isNaN(void 0)}function uN(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function iN(){return isNaN(void 0)}function cN(){return Math.max(Math.random(),Math.random())}function fN(){return isNaN(void 0)}function dN(){return Math.max(Math.random(),Math.random())}function mN(){return isNaN(void 0)}function lN(){nN(),tN(),eN(),rN(),oN(),aN(),uN(),iN(),cN(),fN(),dN(),mN()}function hN(){return isNaN(void 0)}function sN(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function pN(){return Math.random()}function MN(){return Math.max(Math.random(),Math.random())}function vN(){return Math.random()}function NN(){return isNaN(void 0)}function yN(){return isNaN(void 0)}function xN(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function CN(){return Math.random()}function gN(){return Math.random()}function bN(){return Math.max(Math.random(),Math.random())}function UN(){return Math.max(Math.random(),Math.random())}function RN(){hN(),sN(),pN(),MN(),vN(),NN(),yN(),xN(),CN(),gN(),bN(),UN()}function IN(){return isNaN(void 0)}function QN(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function wN(){return Math.max(Math.random(),Math.random())}function _N(){return isNaN(void 0)}function kN(){return isNaN(void 0)}function EN(){return Math.max(Math.random(),Math.random())}function TN(){return isNaN(void 0)}function SN(){return Math.random()}function PN(){return Math.random()}function ON(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function FN(){return Math.max(Math.random(),Math.random())}function DN(){return Math.random()}function AN(){IN(),QN(),wN(),_N(),kN(),EN(),TN(),SN(),PN(),ON(),FN(),DN()}function jN(){return isNaN(void 0)}function LN(){return Math.max(Math.random(),Math.random())}function zN(){return isNaN(void 0)}function BN(){return Math.random()}function VN(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function WN(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function HN(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function $N(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function qN(){return Math.max(Math.random(),Math.random())}function KN(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function GN(){return isNaN(void 0)}function XN(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function YN(){jN(),LN(),zN(),BN(),VN(),WN(),HN(),$N(),qN(),KN(),GN(),XN()}function ZN(){return isNaN(void 0)}function JN(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function ny(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function ty(){return isNaN(void 0)}function ey(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function ry(){return Math.random()}function oy(){return Math.random()}function ay(){return Math.max(Math.random(),Math.random())}function uy(){return isNaN(void 0)}function iy(){return Math.random()}function cy(){return isNaN(void 0)}function fy(){return Math.max(Math.random(),Math.random())}function dy(){ZN(),JN(),ny(),ty(),ey(),ry(),oy(),ay(),uy(),iy(),cy(),fy()}function my(){return isNaN(void 0)}function ly(){return Math.max(Math.random(),Math.random())}function hy(){return Math.random()}function sy(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function py(){return Math.random()}function My(){return isNaN(void 0)}function vy(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Ny(){return Math.random()}function yy(){return Math.max(Math.random(),Math.random())}function xy(){return Math.max(Math.random(),Math.random())}function Cy(){return Math.random()}function gy(){return Math.max(Math.random(),Math.random())}function by(){my(),ly(),hy(),sy(),py(),My(),vy(),Ny(),yy(),xy(),Cy(),gy()}function Uy(){BM(),tv(),sv(),Qv(),Lv(),Jv(),lN(),RN(),AN(),YN(),dy(),by()}function Ry(){return Math.max(Math.random(),Math.random())}function Iy(){return Math.random()}function Qy(){return Math.max(Math.random(),Math.random())}function wy(){return isNaN(void 0)}function _y(){return Math.random()}function ky(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Ey(){return isNaN(void 0)}function Ty(){return Math.max(Math.random(),Math.random())}function Sy(){return Math.random()}function Py(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Oy(){return isNaN(void 0)}function Fy(){return isNaN(void 0)}function Dy(){Ry(),Iy(),Qy(),wy(),_y(),ky(),Ey(),Ty(),Sy(),Py(),Oy(),Fy()}function Ay(){return Math.random()}function jy(){return Math.random()}function Ly(){return Math.random()}function zy(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function By(){return Math.random()}function Vy(){return isNaN(void 0)}function Wy(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Hy(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function $y(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function qy(){return Math.random()}function Ky(){return Math.max(Math.random(),Math.random())}function Gy(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Xy(){Ay(),jy(),Ly(),zy(),By(),Vy(),Wy(),Hy(),$y(),qy(),Ky(),Gy()}function Yy(){return isNaN(void 0)}function Zy(){return Math.random()}function Jy(){return isNaN(void 0)}function nx(){return Math.max(Math.random(),Math.random())}function tx(){return isNaN(void 0)}function ex(){return Math.random()}function rx(){return Math.random()}function ox(){return Math.max(Math.random(),Math.random())}function ax(){return isNaN(void 0)}function ux(){return isNaN(void 0)}function ix(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function cx(){return isNaN(void 0)}function fx(){Yy(),Zy(),Jy(),nx(),tx(),ex(),rx(),ox(),ax(),ux(),ix(),cx()}function dx(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function mx(){return isNaN(void 0)}function lx(){return isNaN(void 0)}function hx(){return Math.max(Math.random(),Math.random())}function sx(){return Math.max(Math.random(),Math.random())}function px(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Mx(){return isNaN(void 0)}function vx(){return Math.random()}function Nx(){return Math.max(Math.random(),Math.random())}function yx(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function xx(){return isNaN(void 0)}function Cx(){return isNaN(void 0)}function gx(){dx(),mx(),lx(),hx(),sx(),px(),Mx(),vx(),Nx(),yx(),xx(),Cx()}function bx(){return Math.max(Math.random(),Math.random())}function Ux(){return Math.max(Math.random(),Math.random())}function Rx(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Ix(){return Math.random()}function Qx(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function wx(){return isNaN(void 0)}function _x(){return Math.random()}function kx(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Ex(){return isNaN(void 0)}function Tx(){return Math.max(Math.random(),Math.random())}function Sx(){return isNaN(void 0)}function Px(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Ox(){bx(),Ux(),Rx(),Ix(),Qx(),wx(),_x(),kx(),Ex(),Tx(),Sx(),Px()}function Fx(){return Math.random()}function Dx(){return Math.random()}function Ax(){return isNaN(void 0)}function jx(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Lx(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function zx(){return Math.max(Math.random(),Math.random())}function Bx(){return isNaN(void 0)}function Vx(){return Math.max(Math.random(),Math.random())}function Wx(){return isNaN(void 0)}function Hx(){return isNaN(void 0)}function $x(){return isNaN(void 0)}function qx(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Kx(){Fx(),Dx(),Ax(),jx(),Lx(),zx(),Bx(),Vx(),Wx(),Hx(),$x(),qx()}function Gx(){return Math.max(Math.random(),Math.random())}function Xx(){return Math.max(Math.random(),Math.random())}function Yx(){return Math.random()}function Zx(){return Math.random()}function Jx(){return isNaN(void 0)}function nC(){return isNaN(void 0)}function tC(){return Math.random()}function eC(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function rC(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function oC(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function aC(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function uC(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function iC(){Gx(),Xx(),Yx(),Zx(),Jx(),nC(),tC(),eC(),rC(),oC(),aC(),uC()}function cC(){return Math.max(Math.random(),Math.random())}function fC(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function dC(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function mC(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function lC(){return isNaN(void 0)}function hC(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function sC(){return Math.max(Math.random(),Math.random())}function pC(){return Math.random()}function MC(){return Math.max(Math.random(),Math.random())}function vC(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function NC(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function yC(){return Math.random()}function xC(){cC(),fC(),dC(),mC(),lC(),hC(),sC(),pC(),MC(),vC(),NC(),yC()}function CC(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function gC(){return Math.max(Math.random(),Math.random())}function bC(){return Math.random()}function UC(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function RC(){return isNaN(void 0)}function IC(){return isNaN(void 0)}function QC(){return Math.max(Math.random(),Math.random())}function wC(){return Math.random()}function _C(){return isNaN(void 0)}function kC(){return isNaN(void 0)}function EC(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function TC(){return Math.max(Math.random(),Math.random())}function SC(){CC(),gC(),bC(),UC(),RC(),IC(),QC(),wC(),_C(),kC(),EC(),TC()}function PC(){return Math.random()}function OC(){return Math.random()}function FC(){return Math.random()}function DC(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function AC(){return Math.max(Math.random(),Math.random())}function jC(){return isNaN(void 0)}function LC(){return Math.random()}function zC(){return Math.random()}function BC(){return Math.max(Math.random(),Math.random())}function VC(){return isNaN(void 0)}function WC(){return Math.max(Math.random(),Math.random())}function HC(){return Math.max(Math.random(),Math.random())}function $C(){PC(),OC(),FC(),DC(),AC(),jC(),LC(),zC(),BC(),VC(),WC(),HC()}function qC(){return Math.max(Math.random(),Math.random())}function KC(){return Math.random()}function GC(){return Math.max(Math.random(),Math.random())}function XC(){return Math.max(Math.random(),Math.random())}function YC(){return isNaN(void 0)}function ZC(){return Math.max(Math.random(),Math.random())}function JC(){return isNaN(void 0)}function ng(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function tg(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function eg(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function rg(){return isNaN(void 0)}function og(){return Math.max(Math.random(),Math.random())}function ag(){qC(),KC(),GC(),XC(),YC(),ZC(),JC(),ng(),tg(),eg(),rg(),og()}function ug(){return Math.max(Math.random(),Math.random())}function ig(){return Math.max(Math.random(),Math.random())}function cg(){return isNaN(void 0)}function fg(){return isNaN(void 0)}function dg(){return Math.max(Math.random(),Math.random())}function mg(){return Math.max(Math.random(),Math.random())}function lg(){return Math.random()}function hg(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function sg(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function pg(){return isNaN(void 0)}function Mg(){return Math.random()}function vg(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Ng(){ug(),ig(),cg(),fg(),dg(),mg(),lg(),hg(),sg(),pg(),Mg(),vg()}function yg(){Dy(),Xy(),fx(),gx(),Ox(),Kx(),iC(),xC(),SC(),$C(),ag(),Ng()}function xg(){return Math.max(Math.random(),Math.random())}function Cg(){return Math.max(Math.random(),Math.random())}function gg(){return Math.random()}function bg(){return Math.max(Math.random(),Math.random())}function Ug(){return Math.random()}function Rg(){return Math.max(Math.random(),Math.random())}function Ig(){return Math.random()}function Qg(){return Math.random()}function wg(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function _g(){return Math.random()}function kg(){return Math.max(Math.random(),Math.random())}function Eg(){return isNaN(void 0)}function Tg(){xg(),Cg(),gg(),bg(),Ug(),Rg(),Ig(),Qg(),wg(),_g(),kg(),Eg()}function Sg(){return Math.random()}function Pg(){return Math.random()}function Og(){return Math.random()}function Fg(){return isNaN(void 0)}function Dg(){return Math.random()}function Ag(){return Math.random()}function jg(){return isNaN(void 0)}function Lg(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function zg(){return Math.max(Math.random(),Math.random())}function Bg(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Vg(){return Math.max(Math.random(),Math.random())}function Wg(){return Math.max(Math.random(),Math.random())}function Hg(){Sg(),Pg(),Og(),Fg(),Dg(),Ag(),jg(),Lg(),zg(),Bg(),Vg(),Wg()}function $g(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function qg(){return isNaN(void 0)}function Kg(){return isNaN(void 0)}function Gg(){return Math.max(Math.random(),Math.random())}function Xg(){return Math.max(Math.random(),Math.random())}function Yg(){return isNaN(void 0)}function Zg(){return Math.random()}function Jg(){return isNaN(void 0)}function nb(){return Math.random()}function tb(){return isNaN(void 0)}function eb(){return isNaN(void 0)}function rb(){return isNaN(void 0)}function ob(){$g(),qg(),Kg(),Gg(),Xg(),Yg(),Zg(),Jg(),nb(),tb(),eb(),rb()}function ab(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function ub(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function ib(){return isNaN(void 0)}function cb(){return isNaN(void 0)}function fb(){return Math.max(Math.random(),Math.random())}function db(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function mb(){return Math.random()}function lb(){return isNaN(void 0)}function hb(){return Math.random()}function sb(){return Math.random()}function pb(){return isNaN(void 0)}function Mb(){return Math.random()}function vb(){ab(),ub(),ib(),cb(),fb(),db(),mb(),lb(),hb(),sb(),pb(),Mb()}function Nb(){return Math.max(Math.random(),Math.random())}function yb(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function xb(){return Math.max(Math.random(),Math.random())}function Cb(){return Math.max(Math.random(),Math.random())}function gb(){return Math.random()}function bb(){return Math.max(Math.random(),Math.random())}function Ub(){return isNaN(void 0)}function Rb(){return Math.random()}function Ib(){return Math.max(Math.random(),Math.random())}function Qb(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function wb(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function _b(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function kb(){Nb(),yb(),xb(),Cb(),gb(),bb(),Ub(),Rb(),Ib(),Qb(),wb(),_b()}function Eb(){return isNaN(void 0)}function Tb(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Sb(){return isNaN(void 0)}function Pb(){return isNaN(void 0)}function Ob(){return Math.random()}function Fb(){return Math.max(Math.random(),Math.random())}function Db(){return Math.max(Math.random(),Math.random())}function Ab(){return Math.random()}function jb(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Lb(){return Math.random()}function zb(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Bb(){return Math.max(Math.random(),Math.random())}function Vb(){Eb(),Tb(),Sb(),Pb(),Ob(),Fb(),Db(),Ab(),jb(),Lb(),zb(),Bb()}function Wb(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Hb(){return Math.random()}function $b(){return isNaN(void 0)}function qb(){return Math.max(Math.random(),Math.random())}function Kb(){return Math.random()}function Gb(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Xb(){return Math.random()}function Yb(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Zb(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Jb(){return Math.random()}function nU(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function tU(){return isNaN(void 0)}function eU(){Wb(),Hb(),$b(),qb(),Kb(),Gb(),Xb(),Yb(),Zb(),Jb(),nU(),tU()}function rU(){return Math.max(Math.random(),Math.random())}function oU(){return Math.max(Math.random(),Math.random())}function aU(){return Math.random()}function uU(){return isNaN(void 0)}function iU(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function cU(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function fU(){return Math.max(Math.random(),Math.random())}function dU(){return Math.max(Math.random(),Math.random())}function mU(){return isNaN(void 0)}function lU(){return isNaN(void 0)}function hU(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function sU(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function pU(){rU(),oU(),aU(),uU(),iU(),cU(),fU(),dU(),mU(),lU(),hU(),sU()}function MU(){return isNaN(void 0)}function vU(){return Math.max(Math.random(),Math.random())}function NU(){return isNaN(void 0)}function yU(){return Math.max(Math.random(),Math.random())}function xU(){return Math.random()}function CU(){return isNaN(void 0)}function gU(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function bU(){return Math.max(Math.random(),Math.random())}function UU(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function RU(){return Math.random()}function IU(){return Math.random()}function QU(){return Math.max(Math.random(),Math.random())}function wU(){MU(),vU(),NU(),yU(),xU(),CU(),gU(),bU(),UU(),RU(),IU(),QU()}function _U(){return Math.max(Math.random(),Math.random())}function kU(){return isNaN(void 0)}function EU(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function TU(){return isNaN(void 0)}function SU(){return isNaN(void 0)}function PU(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function OU(){return Math.random()}function FU(){return isNaN(void 0)}function DU(){return isNaN(void 0)}function AU(){return isNaN(void 0)}function jU(){return isNaN(void 0)}function LU(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function zU(){_U(),kU(),EU(),TU(),SU(),PU(),OU(),FU(),DU(),AU(),jU(),LU()}function BU(){return Math.max(Math.random(),Math.random())}function VU(){return isNaN(void 0)}function WU(){return isNaN(void 0)}function HU(){return Math.random()}function $U(){return isNaN(void 0)}function qU(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function KU(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function GU(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function XU(){return Math.max(Math.random(),Math.random())}function YU(){return Math.random()}function ZU(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function JU(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function nR(){BU(),VU(),WU(),HU(),$U(),qU(),KU(),GU(),XU(),YU(),ZU(),JU()}function tR(){return isNaN(void 0)}function eR(){return Math.max(Math.random(),Math.random())}function rR(){return Math.max(Math.random(),Math.random())}function oR(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function aR(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function uR(){return isNaN(void 0)}function iR(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function cR(){return Math.random()}function fR(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function dR(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function mR(){return Math.random()}function lR(){return isNaN(void 0)}function hR(){tR(),eR(),rR(),oR(),aR(),uR(),iR(),cR(),fR(),dR(),mR(),lR()}function sR(){Tg(),Hg(),ob(),vb(),kb(),Vb(),eU(),pU(),wU(),zU(),nR(),hR()}function pR(){return Math.random()}function MR(){return Math.max(Math.random(),Math.random())}function vR(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function NR(){return Math.max(Math.random(),Math.random())}function yR(){return Math.random()}function xR(){return Math.random()}function CR(){return isNaN(void 0)}function gR(){return Math.random()}function bR(){return Math.max(Math.random(),Math.random())}function UR(){return isNaN(void 0)}function RR(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function IR(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function QR(){pR(),MR(),vR(),NR(),yR(),xR(),CR(),gR(),bR(),UR(),RR(),IR()}function wR(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function _R(){return isNaN(void 0)}function kR(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function ER(){return isNaN(void 0)}function TR(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function SR(){return Math.max(Math.random(),Math.random())}function PR(){return Math.random()}function OR(){return Math.max(Math.random(),Math.random())}function FR(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function DR(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function AR(){return Math.max(Math.random(),Math.random())}function jR(){return isNaN(void 0)}function LR(){wR(),_R(),kR(),ER(),TR(),SR(),PR(),OR(),FR(),DR(),AR(),jR()}function zR(){return isNaN(void 0)}function BR(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function VR(){return Math.max(Math.random(),Math.random())}function WR(){return Math.random()}function HR(){return isNaN(void 0)}function $R(){return Math.max(Math.random(),Math.random())}function qR(){return isNaN(void 0)}function KR(){return Math.random()}function GR(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function XR(){return isNaN(void 0)}function YR(){return Math.max(Math.random(),Math.random())}function ZR(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function JR(){zR(),BR(),VR(),WR(),HR(),$R(),qR(),KR(),GR(),XR(),YR(),ZR()}function nI(){return Math.random()}function tI(){return isNaN(void 0)}function eI(){return Math.random()}function rI(){return Math.max(Math.random(),Math.random())}function oI(){return Math.random()}function aI(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function uI(){return Math.random()}function iI(){return Math.max(Math.random(),Math.random())}function cI(){return Math.random()}function fI(){return Math.max(Math.random(),Math.random())}function dI(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function mI(){return Math.max(Math.random(),Math.random())}function lI(){nI(),tI(),eI(),rI(),oI(),aI(),uI(),iI(),cI(),fI(),dI(),mI()}function hI(){return Math.max(Math.random(),Math.random())}function sI(){return Math.random()}function pI(){return Math.random()}function MI(){return Math.random()}function vI(){return Math.max(Math.random(),Math.random())}function NI(){return isNaN(void 0)}function yI(){return isNaN(void 0)}function xI(){return Math.max(Math.random(),Math.random())}function CI(){return Math.max(Math.random(),Math.random())}function gI(){return Math.random()}function bI(){return Math.random()}function UI(){return isNaN(void 0)}function RI(){hI(),sI(),pI(),MI(),vI(),NI(),yI(),xI(),CI(),gI(),bI(),UI()}function II(){return Math.max(Math.random(),Math.random())}function QI(){return Math.max(Math.random(),Math.random())}function wI(){return isNaN(void 0)}function _I(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function kI(){return Math.random()}function EI(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function TI(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function SI(){return isNaN(void 0)}function PI(){return isNaN(void 0)}function OI(){return Math.random()}function FI(){return isNaN(void 0)}function DI(){return Math.max(Math.random(),Math.random())}function AI(){II(),QI(),wI(),_I(),kI(),EI(),TI(),SI(),PI(),OI(),FI(),DI()}function jI(){return Math.random()}function LI(){return isNaN(void 0)}function zI(){return isNaN(void 0)}function BI(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function VI(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function WI(){return Math.random()}function HI(){return Math.random()}function $I(){return Math.max(Math.random(),Math.random())}function qI(){return isNaN(void 0)}function KI(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function GI(){return Math.random()}function XI(){return Math.max(Math.random(),Math.random())}function YI(){jI(),LI(),zI(),BI(),VI(),WI(),HI(),$I(),qI(),KI(),GI(),XI()}function ZI(){return Math.random()}function JI(){return Math.random()}function nQ(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function tQ(){return isNaN(void 0)}function eQ(){return Math.max(Math.random(),Math.random())}function rQ(){return isNaN(void 0)}function oQ(){return Math.random()}function aQ(){return isNaN(void 0)}function uQ(){return Math.max(Math.random(),Math.random())}function iQ(){return Math.max(Math.random(),Math.random())}function cQ(){return Math.random()}function fQ(){return isNaN(void 0)}function dQ(){ZI(),JI(),nQ(),tQ(),eQ(),rQ(),oQ(),aQ(),uQ(),iQ(),cQ(),fQ()}function mQ(){return isNaN(void 0)}function lQ(){return Math.max(Math.random(),Math.random())}function hQ(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function sQ(){return isNaN(void 0)}function pQ(){return isNaN(void 0)}function MQ(){return Math.random()}function vQ(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function NQ(){return Math.max(Math.random(),Math.random())}function yQ(){return Math.random()}function xQ(){return Math.max(Math.random(),Math.random())}function CQ(){return Math.max(Math.random(),Math.random())}function gQ(){return Math.max(Math.random(),Math.random())}function bQ(){mQ(),lQ(),hQ(),sQ(),pQ(),MQ(),vQ(),NQ(),yQ(),xQ(),CQ(),gQ()}function UQ(){return Math.max(Math.random(),Math.random())}function RQ(){return isNaN(void 0)}function IQ(){return Math.random()}function QQ(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function wQ(){return Math.random()}function _Q(){return isNaN(void 0)}function kQ(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function EQ(){return isNaN(void 0)}function TQ(){return Math.max(Math.random(),Math.random())}function SQ(){return isNaN(void 0)}function PQ(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function OQ(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function FQ(){UQ(),RQ(),IQ(),QQ(),wQ(),_Q(),kQ(),EQ(),TQ(),SQ(),PQ(),OQ()}function DQ(){return Math.max(Math.random(),Math.random())}function AQ(){return isNaN(void 0)}function jQ(){return Math.max(Math.random(),Math.random())}function LQ(){return Math.max(Math.random(),Math.random())}function zQ(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function BQ(){return isNaN(void 0)}function VQ(){return Math.max(Math.random(),Math.random())}function WQ(){return isNaN(void 0)}function HQ(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function $Q(){return isNaN(void 0)}function qQ(){return isNaN(void 0)}function KQ(){return isNaN(void 0)}function GQ(){DQ(),AQ(),jQ(),LQ(),zQ(),BQ(),VQ(),WQ(),HQ(),$Q(),qQ(),KQ()}function XQ(){return Math.random()}function YQ(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function ZQ(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function JQ(){return isNaN(void 0)}function nw(){return Math.max(Math.random(),Math.random())}function tw(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function ew(){return isNaN(void 0)}function rw(){return Math.max(Math.random(),Math.random())}function ow(){return Math.random()}function aw(){return Math.random()}function uw(){return isNaN(void 0)}function iw(){return Math.max(Math.random(),Math.random())}function cw(){XQ(),YQ(),ZQ(),JQ(),nw(),tw(),ew(),rw(),ow(),aw(),uw(),iw()}function fw(){QR(),LR(),JR(),lI(),RI(),AI(),YI(),dQ(),bQ(),FQ(),GQ(),cw()}function dw(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function mw(){return isNaN(void 0)}function lw(){return Math.max(Math.random(),Math.random())}function hw(){return Math.max(Math.random(),Math.random())}function sw(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function pw(){return Math.max(Math.random(),Math.random())}function Mw(){return isNaN(void 0)}function vw(){return Math.max(Math.random(),Math.random())}function Nw(){return Math.random()}function yw(){return isNaN(void 0)}function xw(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Cw(){return Math.max(Math.random(),Math.random())}function gw(){dw(),mw(),lw(),hw(),sw(),pw(),Mw(),vw(),Nw(),yw(),xw(),Cw()}function bw(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Uw(){return Math.max(Math.random(),Math.random())}function Rw(){return Math.max(Math.random(),Math.random())}function Iw(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Qw(){return Math.max(Math.random(),Math.random())}function ww(){return Math.random()}function _w(){return Math.max(Math.random(),Math.random())}function kw(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Ew(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Tw(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Sw(){return Math.random()}function Pw(){return isNaN(void 0)}function Ow(){bw(),Uw(),Rw(),Iw(),Qw(),ww(),_w(),kw(),Ew(),Tw(),Sw(),Pw()}function Fw(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Dw(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Aw(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function jw(){return Math.max(Math.random(),Math.random())}function Lw(){return Math.random()}function zw(){return Math.random()}function Bw(){return Math.random()}function Vw(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Ww(){return Math.max(Math.random(),Math.random())}function Hw(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function $w(){return Math.random()}function qw(){return isNaN(void 0)}function Kw(){Fw(),Dw(),Aw(),jw(),Lw(),zw(),Bw(),Vw(),Ww(),Hw(),$w(),qw()}function Gw(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Xw(){return Math.max(Math.random(),Math.random())}function Yw(){return isNaN(void 0)}function Zw(){return isNaN(void 0)}function Jw(){return isNaN(void 0)}function n_(){return Math.max(Math.random(),Math.random())}function t_(){return Math.max(Math.random(),Math.random())}function e_(){return Math.random()}function r_(){return isNaN(void 0)}function o_(){return isNaN(void 0)}function a_(){return Math.random()}function u_(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function i_(){Gw(),Xw(),Yw(),Zw(),Jw(),n_(),t_(),e_(),r_(),o_(),a_(),u_()}function c_(){return Math.random()}function f_(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function d_(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function m_(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function l_(){return isNaN(void 0)}function h_(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function s_(){return Math.max(Math.random(),Math.random())}function p_(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function M_(){return isNaN(void 0)}function v_(){return Math.max(Math.random(),Math.random())}function N_(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function y_(){return Math.random()}function x_(){c_(),f_(),d_(),m_(),l_(),h_(),s_(),p_(),M_(),v_(),N_(),y_()}function C_(){return Math.random()}function g_(){return Math.random()}function b_(){return isNaN(void 0)}function U_(){return Math.max(Math.random(),Math.random())}function R_(){return isNaN(void 0)}function I_(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Q_(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function w_(){return isNaN(void 0)}function __(){return isNaN(void 0)}function k_(){return Math.random()}function E_(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function T_(){return Math.random()}function S_(){C_(),g_(),b_(),U_(),R_(),I_(),Q_(),w_(),__(),k_(),E_(),T_()}function P_(){return Math.random()}function O_(){return Math.random()}function F_(){return Math.random()}function D_(){return isNaN(void 0)}function A_(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function j_(){return isNaN(void 0)}function L_(){return isNaN(void 0)}function z_(){return Math.max(Math.random(),Math.random())}function B_(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function V_(){return isNaN(void 0)}function W_(){return Math.max(Math.random(),Math.random())}function H_(){return Math.random()}function $_(){P_(),O_(),F_(),D_(),A_(),j_(),L_(),z_(),B_(),V_(),W_(),H_()}function q_(){return Math.random()}function K_(){return Math.random()}function G_(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function X_(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Y_(){return isNaN(void 0)}function Z_(){return Math.max(Math.random(),Math.random())}function J_(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function nk(){return Math.max(Math.random(),Math.random())}function tk(){return Math.max(Math.random(),Math.random())}function ek(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function rk(){return isNaN(void 0)}function ok(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function ak(){q_(),K_(),G_(),X_(),Y_(),Z_(),J_(),nk(),tk(),ek(),rk(),ok()}function uk(){return Math.max(Math.random(),Math.random())}function ik(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function ck(){return Math.max(Math.random(),Math.random())}function fk(){return isNaN(void 0)}function dk(){return isNaN(void 0)}function mk(){return Math.random()}function lk(){return isNaN(void 0)}function hk(){return isNaN(void 0)}function sk(){return Math.max(Math.random(),Math.random())}function pk(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Mk(){return isNaN(void 0)}function vk(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Nk(){uk(),ik(),ck(),fk(),dk(),mk(),lk(),hk(),sk(),pk(),Mk(),vk()}function yk(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function xk(){return Math.max(Math.random(),Math.random())}function Ck(){return Math.max(Math.random(),Math.random())}function gk(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function bk(){return Math.max(Math.random(),Math.random())}function Uk(){return Math.random()}function Rk(){return Math.max(Math.random(),Math.random())}function Ik(){return isNaN(void 0)}function Qk(){return Math.random()}function wk(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function _k(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function kk(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Ek(){yk(),xk(),Ck(),gk(),bk(),Uk(),Rk(),Ik(),Qk(),wk(),_k(),kk()}function Tk(){return Math.max(Math.random(),Math.random())}function Sk(){return Math.random()}function Pk(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Ok(){return Math.max(Math.random(),Math.random())}function Fk(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Dk(){return isNaN(void 0)}function Ak(){return Math.random()}function jk(){return Math.random()}function Lk(){return Math.random()}function zk(){return isNaN(void 0)}function Bk(){return Math.random()}function Vk(){return isNaN(void 0)}function Wk(){Tk(),Sk(),Pk(),Ok(),Fk(),Dk(),Ak(),jk(),Lk(),zk(),Bk(),Vk()}function Hk(){return isNaN(void 0)}function $k(){return Math.max(Math.random(),Math.random())}function qk(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Kk(){return isNaN(void 0)}function Gk(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function Xk(){return Math.random()}function Yk(){return isNaN(void 0)}function Zk(){return Math.max(Math.random(),Math.random())}function Jk(){return Math.max(Math.random(),Math.random())}function nE(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function tE(){return isNaN(void 0)}function eE(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function rE(){Hk(),$k(),qk(),Kk(),Gk(),Xk(),Yk(),Zk(),Jk(),nE(),tE(),eE()}function oE(){gw(),Ow(),Kw(),i_(),x_(),S_(),$_(),ak(),Nk(),Ek(),Wk(),rE()}function aE(){return Math.random()}function uE(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function iE(){return isNaN(void 0)}function cE(){return Math.random()}function fE(){return Math.max(Math.random(),Math.random())}function dE(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function mE(){return isNaN(void 0)}function lE(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function hE(){return Math.random()}function sE(){return Math.random()}function pE(){return Math.max(Math.random(),Math.random())}function ME(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function vE(){aE(),uE(),iE(),cE(),fE(),dE(),mE(),lE(),hE(),sE(),pE(),ME()}function NE(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function yE(){return Math.random()}function xE(){return Math.max(Math.random(),Math.random())}function CE(){return Math.random()}function gE(){return isNaN(void 0)}function bE(){return Math.random()}function UE(){return isNaN(void 0)}function RE(){return Math.max(Math.random(),Math.random())}function IE(){return Math.random()}function QE(){return isNaN(void 0)}function wE(){return isNaN(void 0)}function _E(){return Math.max(Math.random(),Math.random())}function kE(){NE(),yE(),xE(),CE(),gE(),bE(),UE(),RE(),IE(),QE(),wE(),_E()}function EE(){return Math.random()}function TE(){return isNaN(void 0)}function SE(){return isNaN(void 0)}function PE(){return Math.max(Math.random(),Math.random())}function OE(){return Math.max(Math.random(),Math.random())}function FE(){return isNaN(void 0)}function DE(){return Math.random()}function AE(){return Math.random()}function jE(){return Math.random()}function LE(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function zE(){return isNaN(void 0)}function BE(){return encodeURIComponent(',45098#"\xa4#"&\xa4/%"Q"')}function VE(){EE(),TE(),SE(),PE(),OE(),FE(),