Merge mozilla-central to autoland. a=merge CLOSED TREE
authorBogdan Tara <btara@mozilla.com>
Fri, 08 Mar 2019 23:55:49 +0200
changeset 521195 f4edc18a1d44
parent 521194 0c1622df5b86 (current diff)
parent 521152 67424fa758d4 (diff)
child 521196 ba5efb7afd8f
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone67.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
gfx/layers/wr/WebRenderBridgeParent.cpp
--- a/.eslintignore
+++ b/.eslintignore
@@ -277,16 +277,26 @@ mobile/android/chrome/content/browser.js
 # Pre-processed/pref files
 modules/libpref/greprefs.js
 modules/libpref/init/all.js
 modules/libpref/test/unit/*data/**
 
 # Only contains non-standard test files.
 python/**
 
+# Remote agent
+remote/pref/remote.js
+remote/Protocol.jsm
+remote/server/HTTPD.jsm
+remote/server/Packet.jsm
+remote/server/Socket.jsm
+remote/server/Stream.jsm
+remote/test/browser/chrome-remote-interface.js
+remote/test/demo.js
+
 # security/ exclusions (pref files).
 security/manager/ssl/security-prefs.js
 
 # NSS / taskcluster only.
 security/nss/**
 
 # services/ exclusions
 
--- a/browser/config/whats_new_page.yml
+++ b/browser/config/whats_new_page.yml
@@ -13,60 +13,46 @@
       blob-types: [wnp]
       release-types: [release, release-rc]
       products: [firefox]
       update-channel: release
       # e.g.: ["<61.0"]. {version.major_number} reflects the current version.
       # This is done by taskgraph.
       versions: ["<{version.major_number}.0"]
       locales:
-          - ar
-          - az
           - be
           - cak
           - cs
           - cy
           - da
           - de
           - dsb
           - en-CA
           - en-GB
           - en-US
           - es-AR
           - es-CL
           - es-ES
-          - es-MX
-          - et
           - fr
           - fy-NL
-          - gl
-          - gn
           - gu-IN
-          - hi-IN
           - hsb
           - hu
           - ia
           - id
           - it
           - ka
-          - ko
-          - lij
-          - lt
-          - ms
-          - nb-NO
           - nl
           - nn-NO
           - pl
           - pt-BR
           - pt-PT
           - rm
           - ro
           - ru
           - sk
           - sl
           - sq
           - sv-SE
-          - th
           - tr
-          - uk
           - vi
           - zh-CN
           - zh-TW
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -178,17 +178,24 @@
 #endif
 @RESPATH@/components/SyncComponents.manifest
 @RESPATH@/components/servicesComponents.manifest
 @RESPATH@/components/servicesSettings.manifest
 @RESPATH@/components/cryptoComponents.manifest
 
 @RESPATH@/components/Push.manifest
 
-; Remote control protocol
+; CDP remote agent
+#ifdef ENABLE_REMOTE_AGENT
+@RESPATH@/components/RemoteAgent.js
+@RESPATH@/components/RemoteAgent.manifest
+@RESPATH@/defaults/pref/remote.js
+#endif
+
+; Marionette remote control protocol
 #ifdef ENABLE_MARIONETTE
 @RESPATH@/chrome/marionette@JAREXT@
 @RESPATH@/chrome/marionette.manifest
 @RESPATH@/components/marionette.manifest
 @RESPATH@/components/marionette.js
 @RESPATH@/defaults/pref/marionette.js
 #endif
 
--- a/dom/quota/ActorsParent.cpp
+++ b/dom/quota/ActorsParent.cpp
@@ -1169,16 +1169,18 @@ class StoragePressureRunnable final : pu
 
   NS_DECL_NSIRUNNABLE
 };
 
 /*******************************************************************************
  * Helper classes
  ******************************************************************************/
 
+#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+
 class PrincipalVerifier final : public Runnable {
   nsTArray<PrincipalInfo> mPrincipalInfos;
 
  public:
   static already_AddRefed<PrincipalVerifier> CreateAndDispatch(
       nsTArray<PrincipalInfo>&& aPrincipalInfos);
 
  private:
@@ -1190,16 +1192,18 @@ class PrincipalVerifier final : public R
 
   virtual ~PrincipalVerifier() = default;
 
   bool IsPrincipalInfoValid(const PrincipalInfo& aPrincipalInfo);
 
   NS_DECL_NSIRUNNABLE
 };
 
+#endif
+
 /*******************************************************************************
  * Helper Functions
  ******************************************************************************/
 
 template <typename T, bool = mozilla::IsUnsigned<T>::value>
 struct IntChecker {
   static void Assert(T aInt) {
     static_assert(mozilla::IsIntegral<T>::value, "Not an integer!");
@@ -7740,16 +7744,18 @@ nsresult PersistOp::DoDirectoryWork(Quot
 }
 
 void PersistOp::GetResponse(RequestResponse& aResponse) {
   AssertIsOnOwningThread();
 
   aResponse = PersistResponse();
 }
 
+#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+
 // static
 already_AddRefed<PrincipalVerifier> PrincipalVerifier::CreateAndDispatch(
     nsTArray<PrincipalInfo>&& aPrincipalInfos) {
   AssertIsOnIOThread();
 
   RefPtr<PrincipalVerifier> verifier =
       new PrincipalVerifier(std::move(aPrincipalInfos));
 
@@ -7824,16 +7830,18 @@ PrincipalVerifier::Run() {
 
   for (auto& principalInfo : mPrincipalInfos) {
     MOZ_DIAGNOSTIC_ASSERT(IsPrincipalInfoValid(principalInfo));
   }
 
   return NS_OK;
 }
 
+#endif
+
 nsresult StorageOperationBase::GetDirectoryMetadata(nsIFile* aDirectory,
                                                     int64_t& aTimestamp,
                                                     nsACString& aGroup,
                                                     nsACString& aOrigin,
                                                     Nullable<bool>& aIsApp) {
   AssertIsOnIOThread();
   MOZ_ASSERT(aDirectory);
 
@@ -7965,17 +7973,19 @@ nsresult StorageOperationBase::RemoveObs
 }
 
 nsresult StorageOperationBase::ProcessOriginDirectories() {
   AssertIsOnIOThread();
   MOZ_ASSERT(!mOriginProps.IsEmpty());
 
   nsresult rv;
 
+#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
   nsTArray<PrincipalInfo> principalInfos;
+#endif
 
   for (auto& originProps : mOriginProps) {
     switch (originProps.mType) {
       case OriginProps::eChrome: {
         QuotaManager::GetInfoForChrome(
             &originProps.mSuffix, &originProps.mGroup, &originProps.mOrigin);
         break;
       }
@@ -8003,35 +8013,39 @@ nsresult StorageOperationBase::ProcessOr
         contentPrincipalInfo.baseDomain() = baseDomain;
 
         PrincipalInfo principalInfo(contentPrincipalInfo);
 
         QuotaManager::GetInfoFromValidatedPrincipalInfo(
             principalInfo, &originProps.mSuffix, &originProps.mGroup,
             &originProps.mOrigin);
 
+#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
         principalInfos.AppendElement(principalInfo);
+#endif
 
         break;
       }
 
       case OriginProps::eObsolete: {
         // There's no way to get info for obsolete origins.
         break;
       }
 
       default:
         MOZ_CRASH("Bad type!");
     }
   }
 
+#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
   if (!principalInfos.IsEmpty()) {
     RefPtr<PrincipalVerifier> principalVerifier =
         PrincipalVerifier::CreateAndDispatch(std::move(principalInfos));
   }
+#endif
 
   // Don't try to upgrade obsolete origins, remove them right after we detect
   // them.
   for (auto& originProps : mOriginProps) {
     if (originProps.mType == OriginProps::eObsolete) {
       MOZ_ASSERT(originProps.mSuffix.IsEmpty());
       MOZ_ASSERT(originProps.mGroup.IsEmpty());
       MOZ_ASSERT(originProps.mOrigin.IsEmpty());
--- a/gfx/wr/wrench/script/headless.py
+++ b/gfx/wr/wrench/script/headless.py
@@ -44,38 +44,87 @@ def is_windows():
 def is_macos():
     return sys.platform == 'darwin'
 
 
 def is_linux():
     return sys.platform.startswith('linux')
 
 
+def debugger():
+    if "DEBUGGER" in os.environ:
+        return os.environ["DEBUGGER"]
+    return None
+
+
+def use_gdb():
+    return debugger() in ['gdb', 'cgdb', 'rust-gdb']
+
+
+def use_rr():
+    return debugger() == 'rr'
+
+
+def optimized_build():
+    if "OPTIMIZED" in os.environ:
+        opt = os.environ["OPTIMIZED"]
+        return opt not in ["0", "false"]
+    return True
+
+
 def set_osmesa_env(bin_path):
     """Set proper LD_LIBRARY_PATH and DRIVE for software rendering on Linux and OSX"""
     if is_linux():
         osmesa_path = path.join(find_dep_path_newest('osmesa-src', bin_path), "out", "lib", "gallium")
         print(osmesa_path)
         os.environ["LD_LIBRARY_PATH"] = osmesa_path
         os.environ["GALLIUM_DRIVER"] = "softpipe"
     elif is_macos():
         osmesa_path = path.join(find_dep_path_newest('osmesa-src', bin_path),
                                 "out", "src", "gallium", "targets", "osmesa", ".libs")
         glapi_path = path.join(find_dep_path_newest('osmesa-src', bin_path),
                                "out", "src", "mapi", "shared-glapi", ".libs")
         os.environ["DYLD_LIBRARY_PATH"] = osmesa_path + ":" + glapi_path
         os.environ["GALLIUM_DRIVER"] = "softpipe"
 
 
-target_folder = os.getenv('WRENCH_HEADLESS_TARGET', None)
-if not target_folder:
-    extra_flags = os.getenv('CARGOFLAGS', None)
-    extra_flags = extra_flags.split(' ') if extra_flags else []
-    subprocess.check_call(['cargo', 'build'] + extra_flags + ['--release', '--verbose', '--features', 'headless'])
+extra_flags = os.getenv('CARGOFLAGS', None)
+extra_flags = extra_flags.split(' ') if extra_flags else []
+
+wrench_headless_target = os.getenv('WRENCH_HEADLESS_TARGET', None)
+
+if wrench_headless_target:
+    target_folder = wrench_headless_target
+else:
     target_folder = '../target/'
 
-set_osmesa_env(target_folder + 'release/')
+if optimized_build():
+    target_folder += 'release/'
+else:
+    target_folder += 'debug/'
+
+# For CI purposes, don't build if WRENCH_HEADLESS_TARGET is set.
+# This environment variable is used to point to the location of a cross-compiled
+# wrench for the CI on some platforms.
+if not wrench_headless_target:
+    build_cmd = ['cargo', 'build'] + extra_flags + ['--verbose', '--features', 'headless']
+    if optimized_build():
+        build_cmd += ['--release']
+    subprocess.check_call(build_cmd)
+
+dbg_cmd = []
+if use_rr():
+    dbg_cmd = ['rr', 'record']
+elif use_gdb():
+    dbg_cmd = [debugger(), '--args']
+elif debugger():
+    print("Unknown debugger: " + debugger())
+    sys.exit(1)
+
+set_osmesa_env(target_folder)
 # TODO(gw): We have an occasional accuracy issue or bug (could be WR or OSMesa)
 #           where the output of a previous test that uses intermediate targets can
 #           cause 1.0 / 255.0 pixel differences in a subsequent test. For now, we
 #           run tests with no-scissor mode, which ensures a complete target clear
 #           between test runs. But we should investigate this further...
-subprocess.check_call([target_folder + 'release/wrench', '--no-scissor', '-h'] + sys.argv[1:])
+cmd = dbg_cmd + [target_folder + 'wrench', '--no-scissor', '-h'] + sys.argv[1:]
+print('Running: `' + ' '.join(cmd) + '`')
+subprocess.check_call(cmd)
new file mode 100644
--- /dev/null
+++ b/remote/.eslintrc.js
@@ -0,0 +1,7 @@
+"use strict";
+
+module.exports = {
+  "rules": {
+    "max-len": "off",
+  }
+};
new file mode 100644
--- /dev/null
+++ b/remote/Connection.jsm
@@ -0,0 +1,70 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+var EXPORTED_SYMBOLS = ["Connection"];
+
+const {Log} = ChromeUtils.import("chrome://remote/content/Log.jsm");
+const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+XPCOMUtils.defineLazyGetter(this, "log", Log.get);
+XPCOMUtils.defineLazyServiceGetter(this, "UUIDGen", "@mozilla.org/uuid-generator;1", "nsIUUIDGenerator");
+
+class Connection {
+  constructor(transport) {
+    this.id = UUIDGen.generateUUID().toString();
+    this.transport = transport;
+
+    this.transport.hooks = this;
+    this.onmessage = () => {};
+
+    this.transport.ready();
+  }
+
+  send(message) {
+    log.trace(`<-(connection ${this.id}) ${JSON.stringify(message)}`);
+    this.transport.send(message);
+  }
+
+  error(id, e) {
+    const error = {
+      message: e.message,
+      data: e.stack,
+    };
+    this.send({id, error});
+  }
+
+  deserialize(data) {
+    const id = data.id;
+    const method = data.method;
+    const params = data.params || {};
+    return {id, method, params};
+  }
+
+  // transport hooks
+
+  onPacket(packet) {
+    log.trace(`(connection ${this.id})-> ${JSON.stringify(packet)}`);
+
+    let message = {id: null};
+    try {
+      message = this.deserialize(packet);
+      this.onmessage.call(null, message);
+    } catch (e) {
+      log.warn(e);
+      this.error(message.id, e);
+    }
+  }
+
+  close() {
+    this.transport.close();
+  }
+
+  onClosed(status) {}
+
+  toString() {
+    return `[object Connection ${this.id}]`;
+  }
+}
new file mode 100644
--- /dev/null
+++ b/remote/ContentProcessSession.jsm
@@ -0,0 +1,96 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+var EXPORTED_SYMBOLS = ["ContentProcessSession"];
+
+const {ContentProcessDomains} = ChromeUtils.import("chrome://remote/content/domains/ContentProcessDomains.jsm");
+const {Domains} = ChromeUtils.import("chrome://remote/content/domains/Domains.jsm");
+
+class ContentProcessSession {
+  constructor(messageManager, browsingContext, content, docShell) {
+    this.messageManager = messageManager;
+    this.browsingContext = browsingContext;
+    this.content = content;
+    this.docShell = docShell;
+
+    this.domains = new Domains(this, ContentProcessDomains);
+    this.messageManager.addMessageListener("remote:request", this);
+    this.messageManager.addMessageListener("remote:destroy", this);
+
+    this.destroy = this.destroy.bind(this);
+    this.content.addEventListener("unload", this.destroy);
+  }
+
+  destroy() {
+    this.content.addEventListener("unload", this.destroy);
+    this.messageManager.removeMessageListener("remote:request", this);
+    this.messageManager.removeMessageListener("remote:destroy", this);
+  }
+
+  // Domain event listener
+
+  onEvent(eventName, params) {
+    this.messageManager.sendAsyncMessage("remote:event", {
+      browsingContextId: this.browsingContext.id,
+      event: {
+        method: eventName,
+        params,
+      },
+    });
+  }
+
+  // nsIMessageListener
+
+  async receiveMessage({name, data}) {
+    const {browsingContextId} = data;
+
+    // We may have more than one tab loaded in the same process,
+    // and debug the two at the same time. We want to ensure not
+    // mixing up the requests made against two such tabs.
+    // Each tab is going to have its own frame script instance
+    // and two communication channels are going to be set up via
+    // the two message managers.
+    if (browsingContextId != this.browsingContext.id) {
+      return;
+    }
+
+    switch (name) {
+    case "remote:request":
+      try {
+        const {id, domain, method, params} = data.request;
+
+        const inst = this.domains.get(domain);
+        const methodFn = inst[method];
+        if (!methodFn || typeof methodFn != "function") {
+          throw new Error(`Method implementation of ${method} missing`);
+        }
+
+        const result = await methodFn.call(inst, params);
+
+        this.messageManager.sendAsyncMessage("remote:result", {
+          browsingContextId,
+          id,
+          result,
+        });
+      } catch (e) {
+        this.messageManager.sendAsyncMessage("remote:error", {
+          browsingContextId,
+          id: data.request.id,
+          error: {
+            name: e.name || "exception",
+            message: e.message || String(e),
+            stack: e.stack,
+          },
+        });
+      }
+      break;
+
+    case "remote:destroy":
+      this.destroy();
+      break;
+    }
+  }
+}
new file mode 100644
--- /dev/null
+++ b/remote/Error.jsm
@@ -0,0 +1,92 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+var EXPORTED_SYMBOLS = [
+  "FatalError",
+  "RemoteAgentError",
+  "UnknownMethodError",
+  "UnsupportedError",
+];
+
+const {Log} = ChromeUtils.import("chrome://remote/content/Log.jsm");
+const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
+const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+XPCOMUtils.defineLazyGetter(this, "log", Log.get);
+
+class RemoteAgentError extends Error {
+  constructor(message = "", cause = undefined) {
+    cause = cause || message;
+    super(cause);
+
+    this.name = this.constructor.name;
+    this.message = message;
+    this.cause = cause;
+
+    this.notify();
+  }
+
+  notify() {
+    Cu.reportError(this);
+    log.error(formatError(this));
+  }
+
+  toString({stack = false} = {}) {
+    return RemoteAgentError.format(this, {stack});
+  }
+
+  static format(e, {stack = false} = {}) {
+    return formatError(e, {stack});
+  }
+}
+
+/**
+ * A fatal error that it is not possible to recover from
+ * or send back to the client.
+ *
+ * Constructing this error will force the application to quit.
+ */
+class FatalError extends RemoteAgentError {
+  constructor(...args) {
+    super(...args);
+    this.quit();
+  }
+
+  notify() {
+    log.fatal(this.toString());
+  }
+
+  toString() {
+    return formatError(this, {stack: true});
+  }
+
+  quit(mode = Ci.nsIAppStartup.eForceQuit) {
+    Services.startup.quit(mode);
+  }
+}
+
+/** When an operation is not yet implemented. */
+class UnsupportedError extends RemoteAgentError {}
+
+/** The requested remote method does not exist. */
+class UnknownMethodError extends RemoteAgentError {}
+
+function formatError(error, {stack = false} = {}) {
+  const ls = [];
+
+  ls.push(`${error.name}: ${error.message ? `${error.message}:` : ""}`);
+
+  if (stack && error.stack) {
+    const stack = error.stack.trim().split("\n");
+    ls.push(stack.map(line => `\t${line}`).join("\n"));
+
+    if (error.cause) {
+      ls.push("caused by: " + formatError(error.cause, {stack}));
+    }
+  }
+
+  return ls.join("\n");
+}
new file mode 100644
--- /dev/null
+++ b/remote/JSONHandler.jsm
@@ -0,0 +1,67 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+var EXPORTED_SYMBOLS = ["JSONHandler"];
+
+const {HTTP_404} = ChromeUtils.import("chrome://remote/content/server/HTTPD.jsm");
+const {Log} = ChromeUtils.import("chrome://remote/content/Log.jsm");
+const {Protocol} = ChromeUtils.import("chrome://remote/content/Protocol.jsm");
+
+class JSONHandler {
+  constructor(agent) {
+    this.agent = agent;
+    this.routes = {
+      "/json/version": this.getVersion.bind(this),
+      "/json/protocol": this.getProtocol.bind(this),
+      "/json/list": this.getTargetList.bind(this),
+    };
+  }
+
+  getVersion() {
+    return {};
+  }
+
+  getProtocol() {
+    return Protocol.Description;
+  }
+
+  getTargetList() {
+    return [...this.agent.targets];
+  }
+
+  // nsIHttpRequestHandler
+
+  handle(request, response) {
+    if (request.method != "GET") {
+      throw HTTP_404;
+    }
+
+    if (!(request.path in this.routes)) {
+      throw HTTP_404;
+    }
+
+    const body = this.routes[request.path]();
+    const payload = JSON.stringify(body, sanitise, Log.verbose ? "\t" : undefined);
+
+    response.setStatusLine(request.httpVersion, 200, "OK");
+    response.setHeader("Content-Type", "application/json");
+    response.write(payload);
+  }
+
+  // XPCOM
+
+  get QueryInterface() {
+    return ChromeUtils.generateQI([Ci.nsIHttpRequestHandler]);
+  }
+}
+
+// Filters out null and empty strings
+function sanitise(key, value) {
+  if (value === null || (typeof value == "string" && value.length == 0)) {
+    return undefined;
+  }
+  return value;
+}
new file mode 100644
--- /dev/null
+++ b/remote/Log.jsm
@@ -0,0 +1,28 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+var EXPORTED_SYMBOLS = ["Log"];
+
+const {Preferences} = ChromeUtils.import("resource://gre/modules/Preferences.jsm");
+const {Log: StdLog} = ChromeUtils.import("resource://gre/modules/Log.jsm");
+
+const LOG_LEVEL = "remote.log.level";
+
+/** E10s compatible wrapper for the standard logger from Log.jsm. */
+class Log {
+  static get() {
+    const logger = StdLog.repository.getLogger("RemoteAgent");
+    if (logger.ownAppenders.length == 0) {
+      logger.addAppender(new StdLog.DumpAppender());
+      logger.manageLevelFromPref(LOG_LEVEL);
+    }
+    return logger;
+  }
+
+  static get verbose() {
+    return StdLog.Level[Preferences.get(LOG_LEVEL)] >= StdLog.Level.Info;
+  }
+}
new file mode 100644
--- /dev/null
+++ b/remote/Observer.jsm
@@ -0,0 +1,30 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+var EXPORTED_SYMBOLS = ["Observer"];
+
+const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
+
+class Observer {
+  static observe(type, observer) {
+    Services.obs.addObserver(observer, type);
+  }
+
+  static unobserve(type, observer) {
+    Services.obs.removeObserver(observer, type);
+  }
+
+  static once(type, observer = () => {}) {
+    return new Promise(resolve => {
+      const wrappedObserver = (first, ...rest) => {
+        Observer.unobserve(type, wrappedObserver);
+        observer.call(first, ...rest);
+        resolve();
+      };
+      Observer.observe(type, wrappedObserver);
+    });
+  }
+}
new file mode 100644
--- /dev/null
+++ b/remote/Protocol.jsm
@@ -0,0 +1,17356 @@
+"use strict";
+
+var EXPORTED_SYMBOLS = ["Protocol"];
+
+// TODO(ato): We send back a description of the protocol
+// when the user makes the initial HTTP request,
+// but the following is pure fiction.
+const Description = {
+    "domains": [
+        {
+            "domain": "Accessibility",
+            "experimental": true,
+            "dependencies": [
+                "DOM"
+            ],
+            "types": [
+                {
+                    "id": "AXNodeId",
+                    "description": "Unique accessibility node identifier.",
+                    "type": "string"
+                },
+                {
+                    "id": "AXValueType",
+                    "description": "Enum of possible property types.",
+                    "type": "string",
+                    "enum": [
+                        "boolean",
+                        "tristate",
+                        "booleanOrUndefined",
+                        "idref",
+                        "idrefList",
+                        "integer",
+                        "node",
+                        "nodeList",
+                        "number",
+                        "string",
+                        "computedString",
+                        "token",
+                        "tokenList",
+                        "domRelation",
+                        "role",
+                        "internalRole",
+                        "valueUndefined"
+                    ]
+                },
+                {
+                    "id": "AXValueSourceType",
+                    "description": "Enum of possible property sources.",
+                    "type": "string",
+                    "enum": [
+                        "attribute",
+                        "implicit",
+                        "style",
+                        "contents",
+                        "placeholder",
+                        "relatedElement"
+                    ]
+                },
+                {
+                    "id": "AXValueNativeSourceType",
+                    "description": "Enum of possible native property sources (as a subtype of a particular AXValueSourceType).",
+                    "type": "string",
+                    "enum": [
+                        "figcaption",
+                        "label",
+                        "labelfor",
+                        "labelwrapped",
+                        "legend",
+                        "tablecaption",
+                        "title",
+                        "other"
+                    ]
+                },
+                {
+                    "id": "AXValueSource",
+                    "description": "A single source for a computed AX property.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "type",
+                            "description": "What type of source this is.",
+                            "$ref": "AXValueSourceType"
+                        },
+                        {
+                            "name": "value",
+                            "description": "The value of this property source.",
+                            "optional": true,
+                            "$ref": "AXValue"
+                        },
+                        {
+                            "name": "attribute",
+                            "description": "The name of the relevant attribute, if any.",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "attributeValue",
+                            "description": "The value of the relevant attribute, if any.",
+                            "optional": true,
+                            "$ref": "AXValue"
+                        },
+                        {
+                            "name": "superseded",
+                            "description": "Whether this source is superseded by a higher priority source.",
+                            "optional": true,
+                            "type": "boolean"
+                        },
+                        {
+                            "name": "nativeSource",
+                            "description": "The native markup source for this value, e.g. a <label> element.",
+                            "optional": true,
+                            "$ref": "AXValueNativeSourceType"
+                        },
+                        {
+                            "name": "nativeSourceValue",
+                            "description": "The value, such as a node or node list, of the native source.",
+                            "optional": true,
+                            "$ref": "AXValue"
+                        },
+                        {
+                            "name": "invalid",
+                            "description": "Whether the value for this property is invalid.",
+                            "optional": true,
+                            "type": "boolean"
+                        },
+                        {
+                            "name": "invalidReason",
+                            "description": "Reason for the value being invalid, if it is.",
+                            "optional": true,
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "id": "AXRelatedNode",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "backendDOMNodeId",
+                            "description": "The BackendNodeId of the related DOM node.",
+                            "$ref": "DOM.BackendNodeId"
+                        },
+                        {
+                            "name": "idref",
+                            "description": "The IDRef value provided, if any.",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "text",
+                            "description": "The text alternative of this node in the current context.",
+                            "optional": true,
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "id": "AXProperty",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "name",
+                            "description": "The name of this property.",
+                            "$ref": "AXPropertyName"
+                        },
+                        {
+                            "name": "value",
+                            "description": "The value of this property.",
+                            "$ref": "AXValue"
+                        }
+                    ]
+                },
+                {
+                    "id": "AXValue",
+                    "description": "A single computed AX property.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "type",
+                            "description": "The type of this value.",
+                            "$ref": "AXValueType"
+                        },
+                        {
+                            "name": "value",
+                            "description": "The computed value of this property.",
+                            "optional": true,
+                            "type": "any"
+                        },
+                        {
+                            "name": "relatedNodes",
+                            "description": "One or more related nodes, if applicable.",
+                            "optional": true,
+                            "type": "array",
+                            "items": {
+                                "$ref": "AXRelatedNode"
+                            }
+                        },
+                        {
+                            "name": "sources",
+                            "description": "The sources which contributed to the computation of this property.",
+                            "optional": true,
+                            "type": "array",
+                            "items": {
+                                "$ref": "AXValueSource"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "id": "AXPropertyName",
+                    "description": "Values of AXProperty name: from 'busy' to 'roledescription' - states which apply to every AX\nnode, from 'live' to 'root' - attributes which apply to nodes in live regions, from\n'autocomplete' to 'valuetext' - attributes which apply to widgets, from 'checked' to 'selected'\n- states which apply to widgets, from 'activedescendant' to 'owns' - relationships between\nelements other than parent/child/sibling.",
+                    "type": "string",
+                    "enum": [
+                        "busy",
+                        "disabled",
+                        "editable",
+                        "focusable",
+                        "focused",
+                        "hidden",
+                        "hiddenRoot",
+                        "invalid",
+                        "keyshortcuts",
+                        "settable",
+                        "roledescription",
+                        "live",
+                        "atomic",
+                        "relevant",
+                        "root",
+                        "autocomplete",
+                        "hasPopup",
+                        "level",
+                        "multiselectable",
+                        "orientation",
+                        "multiline",
+                        "readonly",
+                        "required",
+                        "valuemin",
+                        "valuemax",
+                        "valuetext",
+                        "checked",
+                        "expanded",
+                        "modal",
+                        "pressed",
+                        "selected",
+                        "activedescendant",
+                        "controls",
+                        "describedby",
+                        "details",
+                        "errormessage",
+                        "flowto",
+                        "labelledby",
+                        "owns"
+                    ]
+                },
+                {
+                    "id": "AXNode",
+                    "description": "A node in the accessibility tree.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "nodeId",
+                            "description": "Unique identifier for this node.",
+                            "$ref": "AXNodeId"
+                        },
+                        {
+                            "name": "ignored",
+                            "description": "Whether this node is ignored for accessibility",
+                            "type": "boolean"
+                        },
+                        {
+                            "name": "ignoredReasons",
+                            "description": "Collection of reasons why this node is hidden.",
+                            "optional": true,
+                            "type": "array",
+                            "items": {
+                                "$ref": "AXProperty"
+                            }
+                        },
+                        {
+                            "name": "role",
+                            "description": "This `Node`'s role, whether explicit or implicit.",
+                            "optional": true,
+                            "$ref": "AXValue"
+                        },
+                        {
+                            "name": "name",
+                            "description": "The accessible name for this `Node`.",
+                            "optional": true,
+                            "$ref": "AXValue"
+                        },
+                        {
+                            "name": "description",
+                            "description": "The accessible description for this `Node`.",
+                            "optional": true,
+                            "$ref": "AXValue"
+                        },
+                        {
+                            "name": "value",
+                            "description": "The value for this `Node`.",
+                            "optional": true,
+                            "$ref": "AXValue"
+                        },
+                        {
+                            "name": "properties",
+                            "description": "All other properties",
+                            "optional": true,
+                            "type": "array",
+                            "items": {
+                                "$ref": "AXProperty"
+                            }
+                        },
+                        {
+                            "name": "childIds",
+                            "description": "IDs for each of this node's child nodes.",
+                            "optional": true,
+                            "type": "array",
+                            "items": {
+                                "$ref": "AXNodeId"
+                            }
+                        },
+                        {
+                            "name": "backendDOMNodeId",
+                            "description": "The backend ID for the associated DOM node, if any.",
+                            "optional": true,
+                            "$ref": "DOM.BackendNodeId"
+                        }
+                    ]
+                }
+            ],
+            "commands": [
+                {
+                    "name": "disable",
+                    "description": "Disables the accessibility domain."
+                },
+                {
+                    "name": "enable",
+                    "description": "Enables the accessibility domain which causes `AXNodeId`s to remain consistent between method calls.\nThis turns on accessibility for the page, which can impact performance until accessibility is disabled."
+                },
+                {
+                    "name": "getPartialAXTree",
+                    "description": "Fetches the accessibility node and partial accessibility tree for this DOM node, if it exists.",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "nodeId",
+                            "description": "Identifier of the node to get the partial accessibility tree for.",
+                            "optional": true,
+                            "$ref": "DOM.NodeId"
+                        },
+                        {
+                            "name": "backendNodeId",
+                            "description": "Identifier of the backend node to get the partial accessibility tree for.",
+                            "optional": true,
+                            "$ref": "DOM.BackendNodeId"
+                        },
+                        {
+                            "name": "objectId",
+                            "description": "JavaScript object id of the node wrapper to get the partial accessibility tree for.",
+                            "optional": true,
+                            "$ref": "Runtime.RemoteObjectId"
+                        },
+                        {
+                            "name": "fetchRelatives",
+                            "description": "Whether to fetch this nodes ancestors, siblings and children. Defaults to true.",
+                            "optional": true,
+                            "type": "boolean"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "nodes",
+                            "description": "The `Accessibility.AXNode` for this DOM node, if it exists, plus its ancestors, siblings and\nchildren, if requested.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "AXNode"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "name": "getFullAXTree",
+                    "description": "Fetches the entire accessibility tree",
+                    "experimental": true,
+                    "returns": [
+                        {
+                            "name": "nodes",
+                            "type": "array",
+                            "items": {
+                                "$ref": "AXNode"
+                            }
+                        }
+                    ]
+                }
+            ]
+        },
+        {
+            "domain": "Animation",
+            "experimental": true,
+            "dependencies": [
+                "Runtime",
+                "DOM"
+            ],
+            "types": [
+                {
+                    "id": "Animation",
+                    "description": "Animation instance.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "id",
+                            "description": "`Animation`'s id.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "name",
+                            "description": "`Animation`'s name.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "pausedState",
+                            "description": "`Animation`'s internal paused state.",
+                            "type": "boolean"
+                        },
+                        {
+                            "name": "playState",
+                            "description": "`Animation`'s play state.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "playbackRate",
+                            "description": "`Animation`'s playback rate.",
+                            "type": "number"
+                        },
+                        {
+                            "name": "startTime",
+                            "description": "`Animation`'s start time.",
+                            "type": "number"
+                        },
+                        {
+                            "name": "currentTime",
+                            "description": "`Animation`'s current time.",
+                            "type": "number"
+                        },
+                        {
+                            "name": "type",
+                            "description": "Animation type of `Animation`.",
+                            "type": "string",
+                            "enum": [
+                                "CSSTransition",
+                                "CSSAnimation",
+                                "WebAnimation"
+                            ]
+                        },
+                        {
+                            "name": "source",
+                            "description": "`Animation`'s source animation node.",
+                            "optional": true,
+                            "$ref": "AnimationEffect"
+                        },
+                        {
+                            "name": "cssId",
+                            "description": "A unique ID for `Animation` representing the sources that triggered this CSS\nanimation/transition.",
+                            "optional": true,
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "id": "AnimationEffect",
+                    "description": "AnimationEffect instance",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "delay",
+                            "description": "`AnimationEffect`'s delay.",
+                            "type": "number"
+                        },
+                        {
+                            "name": "endDelay",
+                            "description": "`AnimationEffect`'s end delay.",
+                            "type": "number"
+                        },
+                        {
+                            "name": "iterationStart",
+                            "description": "`AnimationEffect`'s iteration start.",
+                            "type": "number"
+                        },
+                        {
+                            "name": "iterations",
+                            "description": "`AnimationEffect`'s iterations.",
+                            "type": "number"
+                        },
+                        {
+                            "name": "duration",
+                            "description": "`AnimationEffect`'s iteration duration.",
+                            "type": "number"
+                        },
+                        {
+                            "name": "direction",
+                            "description": "`AnimationEffect`'s playback direction.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "fill",
+                            "description": "`AnimationEffect`'s fill mode.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "backendNodeId",
+                            "description": "`AnimationEffect`'s target node.",
+                            "optional": true,
+                            "$ref": "DOM.BackendNodeId"
+                        },
+                        {
+                            "name": "keyframesRule",
+                            "description": "`AnimationEffect`'s keyframes.",
+                            "optional": true,
+                            "$ref": "KeyframesRule"
+                        },
+                        {
+                            "name": "easing",
+                            "description": "`AnimationEffect`'s timing function.",
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "id": "KeyframesRule",
+                    "description": "Keyframes Rule",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "name",
+                            "description": "CSS keyframed animation's name.",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "keyframes",
+                            "description": "List of animation keyframes.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "KeyframeStyle"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "id": "KeyframeStyle",
+                    "description": "Keyframe Style",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "offset",
+                            "description": "Keyframe's time offset.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "easing",
+                            "description": "`AnimationEffect`'s timing function.",
+                            "type": "string"
+                        }
+                    ]
+                }
+            ],
+            "commands": [
+                {
+                    "name": "disable",
+                    "description": "Disables animation domain notifications."
+                },
+                {
+                    "name": "enable",
+                    "description": "Enables animation domain notifications."
+                },
+                {
+                    "name": "getCurrentTime",
+                    "description": "Returns the current time of the an animation.",
+                    "parameters": [
+                        {
+                            "name": "id",
+                            "description": "Id of animation.",
+                            "type": "string"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "currentTime",
+                            "description": "Current time of the page.",
+                            "type": "number"
+                        }
+                    ]
+                },
+                {
+                    "name": "getPlaybackRate",
+                    "description": "Gets the playback rate of the document timeline.",
+                    "returns": [
+                        {
+                            "name": "playbackRate",
+                            "description": "Playback rate for animations on page.",
+                            "type": "number"
+                        }
+                    ]
+                },
+                {
+                    "name": "releaseAnimations",
+                    "description": "Releases a set of animations to no longer be manipulated.",
+                    "parameters": [
+                        {
+                            "name": "animations",
+                            "description": "List of animation ids to seek.",
+                            "type": "array",
+                            "items": {
+                                "type": "string"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "name": "resolveAnimation",
+                    "description": "Gets the remote object of the Animation.",
+                    "parameters": [
+                        {
+                            "name": "animationId",
+                            "description": "Animation id.",
+                            "type": "string"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "remoteObject",
+                            "description": "Corresponding remote object.",
+                            "$ref": "Runtime.RemoteObject"
+                        }
+                    ]
+                },
+                {
+                    "name": "seekAnimations",
+                    "description": "Seek a set of animations to a particular time within each animation.",
+                    "parameters": [
+                        {
+                            "name": "animations",
+                            "description": "List of animation ids to seek.",
+                            "type": "array",
+                            "items": {
+                                "type": "string"
+                            }
+                        },
+                        {
+                            "name": "currentTime",
+                            "description": "Set the current time of each animation.",
+                            "type": "number"
+                        }
+                    ]
+                },
+                {
+                    "name": "setPaused",
+                    "description": "Sets the paused state of a set of animations.",
+                    "parameters": [
+                        {
+                            "name": "animations",
+                            "description": "Animations to set the pause state of.",
+                            "type": "array",
+                            "items": {
+                                "type": "string"
+                            }
+                        },
+                        {
+                            "name": "paused",
+                            "description": "Paused state to set to.",
+                            "type": "boolean"
+                        }
+                    ]
+                },
+                {
+                    "name": "setPlaybackRate",
+                    "description": "Sets the playback rate of the document timeline.",
+                    "parameters": [
+                        {
+                            "name": "playbackRate",
+                            "description": "Playback rate for animations on page",
+                            "type": "number"
+                        }
+                    ]
+                },
+                {
+                    "name": "setTiming",
+                    "description": "Sets the timing of an animation node.",
+                    "parameters": [
+                        {
+                            "name": "animationId",
+                            "description": "Animation id.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "duration",
+                            "description": "Duration of the animation.",
+                            "type": "number"
+                        },
+                        {
+                            "name": "delay",
+                            "description": "Delay of the animation.",
+                            "type": "number"
+                        }
+                    ]
+                }
+            ],
+            "events": [
+                {
+                    "name": "animationCanceled",
+                    "description": "Event for when an animation has been cancelled.",
+                    "parameters": [
+                        {
+                            "name": "id",
+                            "description": "Id of the animation that was cancelled.",
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "name": "animationCreated",
+                    "description": "Event for each animation that has been created.",
+                    "parameters": [
+                        {
+                            "name": "id",
+                            "description": "Id of the animation that was created.",
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "name": "animationStarted",
+                    "description": "Event for animation that has been started.",
+                    "parameters": [
+                        {
+                            "name": "animation",
+                            "description": "Animation that was started.",
+                            "$ref": "Animation"
+                        }
+                    ]
+                }
+            ]
+        },
+        {
+            "domain": "ApplicationCache",
+            "experimental": true,
+            "types": [
+                {
+                    "id": "ApplicationCacheResource",
+                    "description": "Detailed application cache resource information.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "url",
+                            "description": "Resource url.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "size",
+                            "description": "Resource size.",
+                            "type": "integer"
+                        },
+                        {
+                            "name": "type",
+                            "description": "Resource type.",
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "id": "ApplicationCache",
+                    "description": "Detailed application cache information.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "manifestURL",
+                            "description": "Manifest URL.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "size",
+                            "description": "Application cache size.",
+                            "type": "number"
+                        },
+                        {
+                            "name": "creationTime",
+                            "description": "Application cache creation time.",
+                            "type": "number"
+                        },
+                        {
+                            "name": "updateTime",
+                            "description": "Application cache update time.",
+                            "type": "number"
+                        },
+                        {
+                            "name": "resources",
+                            "description": "Application cache resources.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "ApplicationCacheResource"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "id": "FrameWithManifest",
+                    "description": "Frame identifier - manifest URL pair.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "frameId",
+                            "description": "Frame identifier.",
+                            "$ref": "Page.FrameId"
+                        },
+                        {
+                            "name": "manifestURL",
+                            "description": "Manifest URL.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "status",
+                            "description": "Application cache status.",
+                            "type": "integer"
+                        }
+                    ]
+                }
+            ],
+            "commands": [
+                {
+                    "name": "enable",
+                    "description": "Enables application cache domain notifications."
+                },
+                {
+                    "name": "getApplicationCacheForFrame",
+                    "description": "Returns relevant application cache data for the document in given frame.",
+                    "parameters": [
+                        {
+                            "name": "frameId",
+                            "description": "Identifier of the frame containing document whose application cache is retrieved.",
+                            "$ref": "Page.FrameId"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "applicationCache",
+                            "description": "Relevant application cache data for the document in given frame.",
+                            "$ref": "ApplicationCache"
+                        }
+                    ]
+                },
+                {
+                    "name": "getFramesWithManifests",
+                    "description": "Returns array of frame identifiers with manifest urls for each frame containing a document\nassociated with some application cache.",
+                    "returns": [
+                        {
+                            "name": "frameIds",
+                            "description": "Array of frame identifiers with manifest urls for each frame containing a document\nassociated with some application cache.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "FrameWithManifest"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "name": "getManifestForFrame",
+                    "description": "Returns manifest URL for document in the given frame.",
+                    "parameters": [
+                        {
+                            "name": "frameId",
+                            "description": "Identifier of the frame containing document whose manifest is retrieved.",
+                            "$ref": "Page.FrameId"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "manifestURL",
+                            "description": "Manifest URL for document in the given frame.",
+                            "type": "string"
+                        }
+                    ]
+                }
+            ],
+            "events": [
+                {
+                    "name": "applicationCacheStatusUpdated",
+                    "parameters": [
+                        {
+                            "name": "frameId",
+                            "description": "Identifier of the frame containing document whose application cache updated status.",
+                            "$ref": "Page.FrameId"
+                        },
+                        {
+                            "name": "manifestURL",
+                            "description": "Manifest URL.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "status",
+                            "description": "Updated application cache status.",
+                            "type": "integer"
+                        }
+                    ]
+                },
+                {
+                    "name": "networkStateUpdated",
+                    "parameters": [
+                        {
+                            "name": "isNowOnline",
+                            "type": "boolean"
+                        }
+                    ]
+                }
+            ]
+        },
+        {
+            "domain": "Audits",
+            "description": "Audits domain allows investigation of page violations and possible improvements.",
+            "experimental": true,
+            "dependencies": [
+                "Network"
+            ],
+            "commands": [
+                {
+                    "name": "getEncodedResponse",
+                    "description": "Returns the response body and size if it were re-encoded with the specified settings. Only\napplies to images.",
+                    "parameters": [
+                        {
+                            "name": "requestId",
+                            "description": "Identifier of the network request to get content for.",
+                            "$ref": "Network.RequestId"
+                        },
+                        {
+                            "name": "encoding",
+                            "description": "The encoding to use.",
+                            "type": "string",
+                            "enum": [
+                                "webp",
+                                "jpeg",
+                                "png"
+                            ]
+                        },
+                        {
+                            "name": "quality",
+                            "description": "The quality of the encoding (0-1). (defaults to 1)",
+                            "optional": true,
+                            "type": "number"
+                        },
+                        {
+                            "name": "sizeOnly",
+                            "description": "Whether to only return the size information (defaults to false).",
+                            "optional": true,
+                            "type": "boolean"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "body",
+                            "description": "The encoded body as a base64 string. Omitted if sizeOnly is true.",
+                            "optional": true,
+                            "type": "binary"
+                        },
+                        {
+                            "name": "originalSize",
+                            "description": "Size before re-encoding.",
+                            "type": "integer"
+                        },
+                        {
+                            "name": "encodedSize",
+                            "description": "Size after re-encoding.",
+                            "type": "integer"
+                        }
+                    ]
+                }
+            ]
+        },
+        {
+            "domain": "Browser",
+            "description": "The Browser domain defines methods and events for browser managing.",
+            "types": [
+                {
+                    "id": "WindowID",
+                    "experimental": true,
+                    "type": "integer"
+                },
+                {
+                    "id": "WindowState",
+                    "description": "The state of the browser window.",
+                    "experimental": true,
+                    "type": "string",
+                    "enum": [
+                        "normal",
+                        "minimized",
+                        "maximized",
+                        "fullscreen"
+                    ]
+                },
+                {
+                    "id": "Bounds",
+                    "description": "Browser window bounds information",
+                    "experimental": true,
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "left",
+                            "description": "The offset from the left edge of the screen to the window in pixels.",
+                            "optional": true,
+                            "type": "integer"
+                        },
+                        {
+                            "name": "top",
+                            "description": "The offset from the top edge of the screen to the window in pixels.",
+                            "optional": true,
+                            "type": "integer"
+                        },
+                        {
+                            "name": "width",
+                            "description": "The window width in pixels.",
+                            "optional": true,
+                            "type": "integer"
+                        },
+                        {
+                            "name": "height",
+                            "description": "The window height in pixels.",
+                            "optional": true,
+                            "type": "integer"
+                        },
+                        {
+                            "name": "windowState",
+                            "description": "The window state. Default to normal.",
+                            "optional": true,
+                            "$ref": "WindowState"
+                        }
+                    ]
+                },
+                {
+                    "id": "PermissionType",
+                    "experimental": true,
+                    "type": "string",
+                    "enum": [
+                        "accessibilityEvents",
+                        "audioCapture",
+                        "backgroundSync",
+                        "backgroundFetch",
+                        "clipboardRead",
+                        "clipboardWrite",
+                        "durableStorage",
+                        "flash",
+                        "geolocation",
+                        "midi",
+                        "midiSysex",
+                        "notifications",
+                        "paymentHandler",
+                        "protectedMediaIdentifier",
+                        "sensors",
+                        "videoCapture"
+                    ]
+                },
+                {
+                    "id": "Bucket",
+                    "description": "Chrome histogram bucket.",
+                    "experimental": true,
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "low",
+                            "description": "Minimum value (inclusive).",
+                            "type": "integer"
+                        },
+                        {
+                            "name": "high",
+                            "description": "Maximum value (exclusive).",
+                            "type": "integer"
+                        },
+                        {
+                            "name": "count",
+                            "description": "Number of samples.",
+                            "type": "integer"
+                        }
+                    ]
+                },
+                {
+                    "id": "Histogram",
+                    "description": "Chrome histogram.",
+                    "experimental": true,
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "name",
+                            "description": "Name.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "sum",
+                            "description": "Sum of sample values.",
+                            "type": "integer"
+                        },
+                        {
+                            "name": "count",
+                            "description": "Total number of samples.",
+                            "type": "integer"
+                        },
+                        {
+                            "name": "buckets",
+                            "description": "Buckets.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "Bucket"
+                            }
+                        }
+                    ]
+                }
+            ],
+            "commands": [
+                {
+                    "name": "grantPermissions",
+                    "description": "Grant specific permissions to the given origin and reject all others.",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "origin",
+                            "type": "string"
+                        },
+                        {
+                            "name": "permissions",
+                            "type": "array",
+                            "items": {
+                                "$ref": "PermissionType"
+                            }
+                        },
+                        {
+                            "name": "browserContextId",
+                            "description": "BrowserContext to override permissions. When omitted, default browser context is used.",
+                            "optional": true,
+                            "$ref": "Target.BrowserContextID"
+                        }
+                    ]
+                },
+                {
+                    "name": "resetPermissions",
+                    "description": "Reset all permission management for all origins.",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "browserContextId",
+                            "description": "BrowserContext to reset permissions. When omitted, default browser context is used.",
+                            "optional": true,
+                            "$ref": "Target.BrowserContextID"
+                        }
+                    ]
+                },
+                {
+                    "name": "close",
+                    "description": "Close browser gracefully."
+                },
+                {
+                    "name": "crash",
+                    "description": "Crashes browser on the main thread.",
+                    "experimental": true
+                },
+                {
+                    "name": "getVersion",
+                    "description": "Returns version information.",
+                    "returns": [
+                        {
+                            "name": "protocolVersion",
+                            "description": "Protocol version.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "product",
+                            "description": "Product name.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "revision",
+                            "description": "Product revision.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "userAgent",
+                            "description": "User-Agent.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "jsVersion",
+                            "description": "V8 version.",
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "name": "getBrowserCommandLine",
+                    "description": "Returns the command line switches for the browser process if, and only if\n--enable-automation is on the commandline.",
+                    "experimental": true,
+                    "returns": [
+                        {
+                            "name": "arguments",
+                            "description": "Commandline parameters",
+                            "type": "array",
+                            "items": {
+                                "type": "string"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "name": "getHistograms",
+                    "description": "Get Chrome histograms.",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "query",
+                            "description": "Requested substring in name. Only histograms which have query as a\nsubstring in their name are extracted. An empty or absent query returns\nall histograms.",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "delta",
+                            "description": "If true, retrieve delta since last call.",
+                            "optional": true,
+                            "type": "boolean"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "histograms",
+                            "description": "Histograms.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "Histogram"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "name": "getHistogram",
+                    "description": "Get a Chrome histogram by name.",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "name",
+                            "description": "Requested histogram name.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "delta",
+                            "description": "If true, retrieve delta since last call.",
+                            "optional": true,
+                            "type": "boolean"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "histogram",
+                            "description": "Histogram.",
+                            "$ref": "Histogram"
+                        }
+                    ]
+                },
+                {
+                    "name": "getWindowBounds",
+                    "description": "Get position and size of the browser window.",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "windowId",
+                            "description": "Browser window id.",
+                            "$ref": "WindowID"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "bounds",
+                            "description": "Bounds information of the window. When window state is 'minimized', the restored window\nposition and size are returned.",
+                            "$ref": "Bounds"
+                        }
+                    ]
+                },
+                {
+                    "name": "getWindowForTarget",
+                    "description": "Get the browser window that contains the devtools target.",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "targetId",
+                            "description": "Devtools agent host id. If called as a part of the session, associated targetId is used.",
+                            "optional": true,
+                            "$ref": "Target.TargetID"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "windowId",
+                            "description": "Browser window id.",
+                            "$ref": "WindowID"
+                        },
+                        {
+                            "name": "bounds",
+                            "description": "Bounds information of the window. When window state is 'minimized', the restored window\nposition and size are returned.",
+                            "$ref": "Bounds"
+                        }
+                    ]
+                },
+                {
+                    "name": "setWindowBounds",
+                    "description": "Set position and/or size of the browser window.",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "windowId",
+                            "description": "Browser window id.",
+                            "$ref": "WindowID"
+                        },
+                        {
+                            "name": "bounds",
+                            "description": "New window bounds. The 'minimized', 'maximized' and 'fullscreen' states cannot be combined\nwith 'left', 'top', 'width' or 'height'. Leaves unspecified fields unchanged.",
+                            "$ref": "Bounds"
+                        }
+                    ]
+                },
+                {
+                    "name": "setDockTile",
+                    "description": "Set dock tile details, platform-specific.",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "badgeLabel",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "image",
+                            "description": "Png encoded image.",
+                            "optional": true,
+                            "type": "binary"
+                        }
+                    ]
+                }
+            ]
+        },
+        {
+            "domain": "CSS",
+            "description": "This domain exposes CSS read/write operations. All CSS objects (stylesheets, rules, and styles)\nhave an associated `id` used in subsequent operations on the related object. Each object type has\na specific `id` structure, and those are not interchangeable between objects of different kinds.\nCSS objects can be loaded using the `get*ForNode()` calls (which accept a DOM node id). A client\ncan also keep track of stylesheets via the `styleSheetAdded`/`styleSheetRemoved` events and\nsubsequently load the required stylesheet contents using the `getStyleSheet[Text]()` methods.",
+            "experimental": true,
+            "dependencies": [
+                "DOM"
+            ],
+            "types": [
+                {
+                    "id": "StyleSheetId",
+                    "type": "string"
+                },
+                {
+                    "id": "StyleSheetOrigin",
+                    "description": "Stylesheet type: \"injected\" for stylesheets injected via extension, \"user-agent\" for user-agent\nstylesheets, \"inspector\" for stylesheets created by the inspector (i.e. those holding the \"via\ninspector\" rules), \"regular\" for regular stylesheets.",
+                    "type": "string",
+                    "enum": [
+                        "injected",
+                        "user-agent",
+                        "inspector",
+                        "regular"
+                    ]
+                },
+                {
+                    "id": "PseudoElementMatches",
+                    "description": "CSS rule collection for a single pseudo style.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "pseudoType",
+                            "description": "Pseudo element type.",
+                            "$ref": "DOM.PseudoType"
+                        },
+                        {
+                            "name": "matches",
+                            "description": "Matches of CSS rules applicable to the pseudo style.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "RuleMatch"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "id": "InheritedStyleEntry",
+                    "description": "Inherited CSS rule collection from ancestor node.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "inlineStyle",
+                            "description": "The ancestor node's inline style, if any, in the style inheritance chain.",
+                            "optional": true,
+                            "$ref": "CSSStyle"
+                        },
+                        {
+                            "name": "matchedCSSRules",
+                            "description": "Matches of CSS rules matching the ancestor node in the style inheritance chain.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "RuleMatch"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "id": "RuleMatch",
+                    "description": "Match data for a CSS rule.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "rule",
+                            "description": "CSS rule in the match.",
+                            "$ref": "CSSRule"
+                        },
+                        {
+                            "name": "matchingSelectors",
+                            "description": "Matching selector indices in the rule's selectorList selectors (0-based).",
+                            "type": "array",
+                            "items": {
+                                "type": "integer"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "id": "Value",
+                    "description": "Data for a simple selector (these are delimited by commas in a selector list).",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "text",
+                            "description": "Value text.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "range",
+                            "description": "Value range in the underlying resource (if available).",
+                            "optional": true,
+                            "$ref": "SourceRange"
+                        }
+                    ]
+                },
+                {
+                    "id": "SelectorList",
+                    "description": "Selector list data.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "selectors",
+                            "description": "Selectors in the list.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "Value"
+                            }
+                        },
+                        {
+                            "name": "text",
+                            "description": "Rule selector text.",
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "id": "CSSStyleSheetHeader",
+                    "description": "CSS stylesheet metainformation.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "styleSheetId",
+                            "description": "The stylesheet identifier.",
+                            "$ref": "StyleSheetId"
+                        },
+                        {
+                            "name": "frameId",
+                            "description": "Owner frame identifier.",
+                            "$ref": "Page.FrameId"
+                        },
+                        {
+                            "name": "sourceURL",
+                            "description": "Stylesheet resource URL.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "sourceMapURL",
+                            "description": "URL of source map associated with the stylesheet (if any).",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "origin",
+                            "description": "Stylesheet origin.",
+                            "$ref": "StyleSheetOrigin"
+                        },
+                        {
+                            "name": "title",
+                            "description": "Stylesheet title.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "ownerNode",
+                            "description": "The backend id for the owner node of the stylesheet.",
+                            "optional": true,
+                            "$ref": "DOM.BackendNodeId"
+                        },
+                        {
+                            "name": "disabled",
+                            "description": "Denotes whether the stylesheet is disabled.",
+                            "type": "boolean"
+                        },
+                        {
+                            "name": "hasSourceURL",
+                            "description": "Whether the sourceURL field value comes from the sourceURL comment.",
+                            "optional": true,
+                            "type": "boolean"
+                        },
+                        {
+                            "name": "isInline",
+                            "description": "Whether this stylesheet is created for STYLE tag by parser. This flag is not set for\ndocument.written STYLE tags.",
+                            "type": "boolean"
+                        },
+                        {
+                            "name": "startLine",
+                            "description": "Line offset of the stylesheet within the resource (zero based).",
+                            "type": "number"
+                        },
+                        {
+                            "name": "startColumn",
+                            "description": "Column offset of the stylesheet within the resource (zero based).",
+                            "type": "number"
+                        },
+                        {
+                            "name": "length",
+                            "description": "Size of the content (in characters).",
+                            "type": "number"
+                        }
+                    ]
+                },
+                {
+                    "id": "CSSRule",
+                    "description": "CSS rule representation.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "styleSheetId",
+                            "description": "The css style sheet identifier (absent for user agent stylesheet and user-specified\nstylesheet rules) this rule came from.",
+                            "optional": true,
+                            "$ref": "StyleSheetId"
+                        },
+                        {
+                            "name": "selectorList",
+                            "description": "Rule selector data.",
+                            "$ref": "SelectorList"
+                        },
+                        {
+                            "name": "origin",
+                            "description": "Parent stylesheet's origin.",
+                            "$ref": "StyleSheetOrigin"
+                        },
+                        {
+                            "name": "style",
+                            "description": "Associated style declaration.",
+                            "$ref": "CSSStyle"
+                        },
+                        {
+                            "name": "media",
+                            "description": "Media list array (for rules involving media queries). The array enumerates media queries\nstarting with the innermost one, going outwards.",
+                            "optional": true,
+                            "type": "array",
+                            "items": {
+                                "$ref": "CSSMedia"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "id": "RuleUsage",
+                    "description": "CSS coverage information.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "styleSheetId",
+                            "description": "The css style sheet identifier (absent for user agent stylesheet and user-specified\nstylesheet rules) this rule came from.",
+                            "$ref": "StyleSheetId"
+                        },
+                        {
+                            "name": "startOffset",
+                            "description": "Offset of the start of the rule (including selector) from the beginning of the stylesheet.",
+                            "type": "number"
+                        },
+                        {
+                            "name": "endOffset",
+                            "description": "Offset of the end of the rule body from the beginning of the stylesheet.",
+                            "type": "number"
+                        },
+                        {
+                            "name": "used",
+                            "description": "Indicates whether the rule was actually used by some element in the page.",
+                            "type": "boolean"
+                        }
+                    ]
+                },
+                {
+                    "id": "SourceRange",
+                    "description": "Text range within a resource. All numbers are zero-based.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "startLine",
+                            "description": "Start line of range.",
+                            "type": "integer"
+                        },
+                        {
+                            "name": "startColumn",
+                            "description": "Start column of range (inclusive).",
+                            "type": "integer"
+                        },
+                        {
+                            "name": "endLine",
+                            "description": "End line of range",
+                            "type": "integer"
+                        },
+                        {
+                            "name": "endColumn",
+                            "description": "End column of range (exclusive).",
+                            "type": "integer"
+                        }
+                    ]
+                },
+                {
+                    "id": "ShorthandEntry",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "name",
+                            "description": "Shorthand name.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "value",
+                            "description": "Shorthand value.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "important",
+                            "description": "Whether the property has \"!important\" annotation (implies `false` if absent).",
+                            "optional": true,
+                            "type": "boolean"
+                        }
+                    ]
+                },
+                {
+                    "id": "CSSComputedStyleProperty",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "name",
+                            "description": "Computed style property name.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "value",
+                            "description": "Computed style property value.",
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "id": "CSSStyle",
+                    "description": "CSS style representation.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "styleSheetId",
+                            "description": "The css style sheet identifier (absent for user agent stylesheet and user-specified\nstylesheet rules) this rule came from.",
+                            "optional": true,
+                            "$ref": "StyleSheetId"
+                        },
+                        {
+                            "name": "cssProperties",
+                            "description": "CSS properties in the style.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "CSSProperty"
+                            }
+                        },
+                        {
+                            "name": "shorthandEntries",
+                            "description": "Computed values for all shorthands found in the style.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "ShorthandEntry"
+                            }
+                        },
+                        {
+                            "name": "cssText",
+                            "description": "Style declaration text (if available).",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "range",
+                            "description": "Style declaration range in the enclosing stylesheet (if available).",
+                            "optional": true,
+                            "$ref": "SourceRange"
+                        }
+                    ]
+                },
+                {
+                    "id": "CSSProperty",
+                    "description": "CSS property declaration data.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "name",
+                            "description": "The property name.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "value",
+                            "description": "The property value.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "important",
+                            "description": "Whether the property has \"!important\" annotation (implies `false` if absent).",
+                            "optional": true,
+                            "type": "boolean"
+                        },
+                        {
+                            "name": "implicit",
+                            "description": "Whether the property is implicit (implies `false` if absent).",
+                            "optional": true,
+                            "type": "boolean"
+                        },
+                        {
+                            "name": "text",
+                            "description": "The full property text as specified in the style.",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "parsedOk",
+                            "description": "Whether the property is understood by the browser (implies `true` if absent).",
+                            "optional": true,
+                            "type": "boolean"
+                        },
+                        {
+                            "name": "disabled",
+                            "description": "Whether the property is disabled by the user (present for source-based properties only).",
+                            "optional": true,
+                            "type": "boolean"
+                        },
+                        {
+                            "name": "range",
+                            "description": "The entire property range in the enclosing style declaration (if available).",
+                            "optional": true,
+                            "$ref": "SourceRange"
+                        }
+                    ]
+                },
+                {
+                    "id": "CSSMedia",
+                    "description": "CSS media rule descriptor.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "text",
+                            "description": "Media query text.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "source",
+                            "description": "Source of the media query: \"mediaRule\" if specified by a @media rule, \"importRule\" if\nspecified by an @import rule, \"linkedSheet\" if specified by a \"media\" attribute in a linked\nstylesheet's LINK tag, \"inlineSheet\" if specified by a \"media\" attribute in an inline\nstylesheet's STYLE tag.",
+                            "type": "string",
+                            "enum": [
+                                "mediaRule",
+                                "importRule",
+                                "linkedSheet",
+                                "inlineSheet"
+                            ]
+                        },
+                        {
+                            "name": "sourceURL",
+                            "description": "URL of the document containing the media query description.",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "range",
+                            "description": "The associated rule (@media or @import) header range in the enclosing stylesheet (if\navailable).",
+                            "optional": true,
+                            "$ref": "SourceRange"
+                        },
+                        {
+                            "name": "styleSheetId",
+                            "description": "Identifier of the stylesheet containing this object (if exists).",
+                            "optional": true,
+                            "$ref": "StyleSheetId"
+                        },
+                        {
+                            "name": "mediaList",
+                            "description": "Array of media queries.",
+                            "optional": true,
+                            "type": "array",
+                            "items": {
+                                "$ref": "MediaQuery"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "id": "MediaQuery",
+                    "description": "Media query descriptor.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "expressions",
+                            "description": "Array of media query expressions.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "MediaQueryExpression"
+                            }
+                        },
+                        {
+                            "name": "active",
+                            "description": "Whether the media query condition is satisfied.",
+                            "type": "boolean"
+                        }
+                    ]
+                },
+                {
+                    "id": "MediaQueryExpression",
+                    "description": "Media query expression descriptor.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "value",
+                            "description": "Media query expression value.",
+                            "type": "number"
+                        },
+                        {
+                            "name": "unit",
+                            "description": "Media query expression units.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "feature",
+                            "description": "Media query expression feature.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "valueRange",
+                            "description": "The associated range of the value text in the enclosing stylesheet (if available).",
+                            "optional": true,
+                            "$ref": "SourceRange"
+                        },
+                        {
+                            "name": "computedLength",
+                            "description": "Computed length of media query expression (if applicable).",
+                            "optional": true,
+                            "type": "number"
+                        }
+                    ]
+                },
+                {
+                    "id": "PlatformFontUsage",
+                    "description": "Information about amount of glyphs that were rendered with given font.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "familyName",
+                            "description": "Font's family name reported by platform.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "isCustomFont",
+                            "description": "Indicates if the font was downloaded or resolved locally.",
+                            "type": "boolean"
+                        },
+                        {
+                            "name": "glyphCount",
+                            "description": "Amount of glyphs that were rendered with this font.",
+                            "type": "number"
+                        }
+                    ]
+                },
+                {
+                    "id": "FontFace",
+                    "description": "Properties of a web font: https://www.w3.org/TR/2008/REC-CSS2-20080411/fonts.html#font-descriptions",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "fontFamily",
+                            "description": "The font-family.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "fontStyle",
+                            "description": "The font-style.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "fontVariant",
+                            "description": "The font-variant.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "fontWeight",
+                            "description": "The font-weight.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "fontStretch",
+                            "description": "The font-stretch.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "unicodeRange",
+                            "description": "The unicode-range.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "src",
+                            "description": "The src.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "platformFontFamily",
+                            "description": "The resolved platform font family",
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "id": "CSSKeyframesRule",
+                    "description": "CSS keyframes rule representation.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "animationName",
+                            "description": "Animation name.",
+                            "$ref": "Value"
+                        },
+                        {
+                            "name": "keyframes",
+                            "description": "List of keyframes.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "CSSKeyframeRule"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "id": "CSSKeyframeRule",
+                    "description": "CSS keyframe rule representation.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "styleSheetId",
+                            "description": "The css style sheet identifier (absent for user agent stylesheet and user-specified\nstylesheet rules) this rule came from.",
+                            "optional": true,
+                            "$ref": "StyleSheetId"
+                        },
+                        {
+                            "name": "origin",
+                            "description": "Parent stylesheet's origin.",
+                            "$ref": "StyleSheetOrigin"
+                        },
+                        {
+                            "name": "keyText",
+                            "description": "Associated key text.",
+                            "$ref": "Value"
+                        },
+                        {
+                            "name": "style",
+                            "description": "Associated style declaration.",
+                            "$ref": "CSSStyle"
+                        }
+                    ]
+                },
+                {
+                    "id": "StyleDeclarationEdit",
+                    "description": "A descriptor of operation to mutate style declaration text.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "styleSheetId",
+                            "description": "The css style sheet identifier.",
+                            "$ref": "StyleSheetId"
+                        },
+                        {
+                            "name": "range",
+                            "description": "The range of the style text in the enclosing stylesheet.",
+                            "$ref": "SourceRange"
+                        },
+                        {
+                            "name": "text",
+                            "description": "New style text.",
+                            "type": "string"
+                        }
+                    ]
+                }
+            ],
+            "commands": [
+                {
+                    "name": "addRule",
+                    "description": "Inserts a new rule with the given `ruleText` in a stylesheet with given `styleSheetId`, at the\nposition specified by `location`.",
+                    "parameters": [
+                        {
+                            "name": "styleSheetId",
+                            "description": "The css style sheet identifier where a new rule should be inserted.",
+                            "$ref": "StyleSheetId"
+                        },
+                        {
+                            "name": "ruleText",
+                            "description": "The text of a new rule.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "location",
+                            "description": "Text position of a new rule in the target style sheet.",
+                            "$ref": "SourceRange"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "rule",
+                            "description": "The newly created rule.",
+                            "$ref": "CSSRule"
+                        }
+                    ]
+                },
+                {
+                    "name": "collectClassNames",
+                    "description": "Returns all class names from specified stylesheet.",
+                    "parameters": [
+                        {
+                            "name": "styleSheetId",
+                            "$ref": "StyleSheetId"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "classNames",
+                            "description": "Class name list.",
+                            "type": "array",
+                            "items": {
+                                "type": "string"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "name": "createStyleSheet",
+                    "description": "Creates a new special \"via-inspector\" stylesheet in the frame with given `frameId`.",
+                    "parameters": [
+                        {
+                            "name": "frameId",
+                            "description": "Identifier of the frame where \"via-inspector\" stylesheet should be created.",
+                            "$ref": "Page.FrameId"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "styleSheetId",
+                            "description": "Identifier of the created \"via-inspector\" stylesheet.",
+                            "$ref": "StyleSheetId"
+                        }
+                    ]
+                },
+                {
+                    "name": "disable",
+                    "description": "Disables the CSS agent for the given page."
+                },
+                {
+                    "name": "enable",
+                    "description": "Enables the CSS agent for the given page. Clients should not assume that the CSS agent has been\nenabled until the result of this command is received."
+                },
+                {
+                    "name": "forcePseudoState",
+                    "description": "Ensures that the given node will have specified pseudo-classes whenever its style is computed by\nthe browser.",
+                    "parameters": [
+                        {
+                            "name": "nodeId",
+                            "description": "The element id for which to force the pseudo state.",
+                            "$ref": "DOM.NodeId"
+                        },
+                        {
+                            "name": "forcedPseudoClasses",
+                            "description": "Element pseudo classes to force when computing the element's style.",
+                            "type": "array",
+                            "items": {
+                                "type": "string"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "name": "getBackgroundColors",
+                    "parameters": [
+                        {
+                            "name": "nodeId",
+                            "description": "Id of the node to get background colors for.",
+                            "$ref": "DOM.NodeId"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "backgroundColors",
+                            "description": "The range of background colors behind this element, if it contains any visible text. If no\nvisible text is present, this will be undefined. In the case of a flat background color,\nthis will consist of simply that color. In the case of a gradient, this will consist of each\nof the color stops. For anything more complicated, this will be an empty array. Images will\nbe ignored (as if the image had failed to load).",
+                            "optional": true,
+                            "type": "array",
+                            "items": {
+                                "type": "string"
+                            }
+                        },
+                        {
+                            "name": "computedFontSize",
+                            "description": "The computed font size for this node, as a CSS computed value string (e.g. '12px').",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "computedFontWeight",
+                            "description": "The computed font weight for this node, as a CSS computed value string (e.g. 'normal' or\n'100').",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "computedBodyFontSize",
+                            "description": "The computed font size for the document body, as a computed CSS value string (e.g. '16px').",
+                            "optional": true,
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "name": "getComputedStyleForNode",
+                    "description": "Returns the computed style for a DOM node identified by `nodeId`.",
+                    "parameters": [
+                        {
+                            "name": "nodeId",
+                            "$ref": "DOM.NodeId"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "computedStyle",
+                            "description": "Computed style for the specified DOM node.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "CSSComputedStyleProperty"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "name": "getInlineStylesForNode",
+                    "description": "Returns the styles defined inline (explicitly in the \"style\" attribute and implicitly, using DOM\nattributes) for a DOM node identified by `nodeId`.",
+                    "parameters": [
+                        {
+                            "name": "nodeId",
+                            "$ref": "DOM.NodeId"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "inlineStyle",
+                            "description": "Inline style for the specified DOM node.",
+                            "optional": true,
+                            "$ref": "CSSStyle"
+                        },
+                        {
+                            "name": "attributesStyle",
+                            "description": "Attribute-defined element style (e.g. resulting from \"width=20 height=100%\").",
+                            "optional": true,
+                            "$ref": "CSSStyle"
+                        }
+                    ]
+                },
+                {
+                    "name": "getMatchedStylesForNode",
+                    "description": "Returns requested styles for a DOM node identified by `nodeId`.",
+                    "parameters": [
+                        {
+                            "name": "nodeId",
+                            "$ref": "DOM.NodeId"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "inlineStyle",
+                            "description": "Inline style for the specified DOM node.",
+                            "optional": true,
+                            "$ref": "CSSStyle"
+                        },
+                        {
+                            "name": "attributesStyle",
+                            "description": "Attribute-defined element style (e.g. resulting from \"width=20 height=100%\").",
+                            "optional": true,
+                            "$ref": "CSSStyle"
+                        },
+                        {
+                            "name": "matchedCSSRules",
+                            "description": "CSS rules matching this node, from all applicable stylesheets.",
+                            "optional": true,
+                            "type": "array",
+                            "items": {
+                                "$ref": "RuleMatch"
+                            }
+                        },
+                        {
+                            "name": "pseudoElements",
+                            "description": "Pseudo style matches for this node.",
+                            "optional": true,
+                            "type": "array",
+                            "items": {
+                                "$ref": "PseudoElementMatches"
+                            }
+                        },
+                        {
+                            "name": "inherited",
+                            "description": "A chain of inherited styles (from the immediate node parent up to the DOM tree root).",
+                            "optional": true,
+                            "type": "array",
+                            "items": {
+                                "$ref": "InheritedStyleEntry"
+                            }
+                        },
+                        {
+                            "name": "cssKeyframesRules",
+                            "description": "A list of CSS keyframed animations matching this node.",
+                            "optional": true,
+                            "type": "array",
+                            "items": {
+                                "$ref": "CSSKeyframesRule"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "name": "getMediaQueries",
+                    "description": "Returns all media queries parsed by the rendering engine.",
+                    "returns": [
+                        {
+                            "name": "medias",
+                            "type": "array",
+                            "items": {
+                                "$ref": "CSSMedia"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "name": "getPlatformFontsForNode",
+                    "description": "Requests information about platform fonts which we used to render child TextNodes in the given\nnode.",
+                    "parameters": [
+                        {
+                            "name": "nodeId",
+                            "$ref": "DOM.NodeId"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "fonts",
+                            "description": "Usage statistics for every employed platform font.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "PlatformFontUsage"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "name": "getStyleSheetText",
+                    "description": "Returns the current textual content for a stylesheet.",
+                    "parameters": [
+                        {
+                            "name": "styleSheetId",
+                            "$ref": "StyleSheetId"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "text",
+                            "description": "The stylesheet text.",
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "name": "setEffectivePropertyValueForNode",
+                    "description": "Find a rule with the given active property for the given node and set the new value for this\nproperty",
+                    "parameters": [
+                        {
+                            "name": "nodeId",
+                            "description": "The element id for which to set property.",
+                            "$ref": "DOM.NodeId"
+                        },
+                        {
+                            "name": "propertyName",
+                            "type": "string"
+                        },
+                        {
+                            "name": "value",
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "name": "setKeyframeKey",
+                    "description": "Modifies the keyframe rule key text.",
+                    "parameters": [
+                        {
+                            "name": "styleSheetId",
+                            "$ref": "StyleSheetId"
+                        },
+                        {
+                            "name": "range",
+                            "$ref": "SourceRange"
+                        },
+                        {
+                            "name": "keyText",
+                            "type": "string"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "keyText",
+                            "description": "The resulting key text after modification.",
+                            "$ref": "Value"
+                        }
+                    ]
+                },
+                {
+                    "name": "setMediaText",
+                    "description": "Modifies the rule selector.",
+                    "parameters": [
+                        {
+                            "name": "styleSheetId",
+                            "$ref": "StyleSheetId"
+                        },
+                        {
+                            "name": "range",
+                            "$ref": "SourceRange"
+                        },
+                        {
+                            "name": "text",
+                            "type": "string"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "media",
+                            "description": "The resulting CSS media rule after modification.",
+                            "$ref": "CSSMedia"
+                        }
+                    ]
+                },
+                {
+                    "name": "setRuleSelector",
+                    "description": "Modifies the rule selector.",
+                    "parameters": [
+                        {
+                            "name": "styleSheetId",
+                            "$ref": "StyleSheetId"
+                        },
+                        {
+                            "name": "range",
+                            "$ref": "SourceRange"
+                        },
+                        {
+                            "name": "selector",
+                            "type": "string"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "selectorList",
+                            "description": "The resulting selector list after modification.",
+                            "$ref": "SelectorList"
+                        }
+                    ]
+                },
+                {
+                    "name": "setStyleSheetText",
+                    "description": "Sets the new stylesheet text.",
+                    "parameters": [
+                        {
+                            "name": "styleSheetId",
+                            "$ref": "StyleSheetId"
+                        },
+                        {
+                            "name": "text",
+                            "type": "string"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "sourceMapURL",
+                            "description": "URL of source map associated with script (if any).",
+                            "optional": true,
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "name": "setStyleTexts",
+                    "description": "Applies specified style edits one after another in the given order.",
+                    "parameters": [
+                        {
+                            "name": "edits",
+                            "type": "array",
+                            "items": {
+                                "$ref": "StyleDeclarationEdit"
+                            }
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "styles",
+                            "description": "The resulting styles after modification.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "CSSStyle"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "name": "startRuleUsageTracking",
+                    "description": "Enables the selector recording."
+                },
+                {
+                    "name": "stopRuleUsageTracking",
+                    "description": "Stop tracking rule usage and return the list of rules that were used since last call to\n`takeCoverageDelta` (or since start of coverage instrumentation)",
+                    "returns": [
+                        {
+                            "name": "ruleUsage",
+                            "type": "array",
+                            "items": {
+                                "$ref": "RuleUsage"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "name": "takeCoverageDelta",
+                    "description": "Obtain list of rules that became used since last call to this method (or since start of coverage\ninstrumentation)",
+                    "returns": [
+                        {
+                            "name": "coverage",
+                            "type": "array",
+                            "items": {
+                                "$ref": "RuleUsage"
+                            }
+                        }
+                    ]
+                }
+            ],
+            "events": [
+                {
+                    "name": "fontsUpdated",
+                    "description": "Fires whenever a web font is updated.  A non-empty font parameter indicates a successfully loaded\nweb font",
+                    "parameters": [
+                        {
+                            "name": "font",
+                            "description": "The web font that has loaded.",
+                            "optional": true,
+                            "$ref": "FontFace"
+                        }
+                    ]
+                },
+                {
+                    "name": "mediaQueryResultChanged",
+                    "description": "Fires whenever a MediaQuery result changes (for example, after a browser window has been\nresized.) The current implementation considers only viewport-dependent media features."
+                },
+                {
+                    "name": "styleSheetAdded",
+                    "description": "Fired whenever an active document stylesheet is added.",
+                    "parameters": [
+                        {
+                            "name": "header",
+                            "description": "Added stylesheet metainfo.",
+                            "$ref": "CSSStyleSheetHeader"
+                        }
+                    ]
+                },
+                {
+                    "name": "styleSheetChanged",
+                    "description": "Fired whenever a stylesheet is changed as a result of the client operation.",
+                    "parameters": [
+                        {
+                            "name": "styleSheetId",
+                            "$ref": "StyleSheetId"
+                        }
+                    ]
+                },
+                {
+                    "name": "styleSheetRemoved",
+                    "description": "Fired whenever an active document stylesheet is removed.",
+                    "parameters": [
+                        {
+                            "name": "styleSheetId",
+                            "description": "Identifier of the removed stylesheet.",
+                            "$ref": "StyleSheetId"
+                        }
+                    ]
+                }
+            ]
+        },
+        {
+            "domain": "CacheStorage",
+            "experimental": true,
+            "types": [
+                {
+                    "id": "CacheId",
+                    "description": "Unique identifier of the Cache object.",
+                    "type": "string"
+                },
+                {
+                    "id": "CachedResponseType",
+                    "description": "type of HTTP response cached",
+                    "type": "string",
+                    "enum": [
+                        "basic",
+                        "cors",
+                        "default",
+                        "error",
+                        "opaqueResponse",
+                        "opaqueRedirect"
+                    ]
+                },
+                {
+                    "id": "DataEntry",
+                    "description": "Data entry.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "requestURL",
+                            "description": "Request URL.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "requestMethod",
+                            "description": "Request method.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "requestHeaders",
+                            "description": "Request headers",
+                            "type": "array",
+                            "items": {
+                                "$ref": "Header"
+                            }
+                        },
+                        {
+                            "name": "responseTime",
+                            "description": "Number of seconds since epoch.",
+                            "type": "number"
+                        },
+                        {
+                            "name": "responseStatus",
+                            "description": "HTTP response status code.",
+                            "type": "integer"
+                        },
+                        {
+                            "name": "responseStatusText",
+                            "description": "HTTP response status text.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "responseType",
+                            "description": "HTTP response type",
+                            "$ref": "CachedResponseType"
+                        },
+                        {
+                            "name": "responseHeaders",
+                            "description": "Response headers",
+                            "type": "array",
+                            "items": {
+                                "$ref": "Header"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "id": "Cache",
+                    "description": "Cache identifier.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "cacheId",
+                            "description": "An opaque unique id of the cache.",
+                            "$ref": "CacheId"
+                        },
+                        {
+                            "name": "securityOrigin",
+                            "description": "Security origin of the cache.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "cacheName",
+                            "description": "The name of the cache.",
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "id": "Header",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "name",
+                            "type": "string"
+                        },
+                        {
+                            "name": "value",
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "id": "CachedResponse",
+                    "description": "Cached response",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "body",
+                            "description": "Entry content, base64-encoded.",
+                            "type": "binary"
+                        }
+                    ]
+                }
+            ],
+            "commands": [
+                {
+                    "name": "deleteCache",
+                    "description": "Deletes a cache.",
+                    "parameters": [
+                        {
+                            "name": "cacheId",
+                            "description": "Id of cache for deletion.",
+                            "$ref": "CacheId"
+                        }
+                    ]
+                },
+                {
+                    "name": "deleteEntry",
+                    "description": "Deletes a cache entry.",
+                    "parameters": [
+                        {
+                            "name": "cacheId",
+                            "description": "Id of cache where the entry will be deleted.",
+                            "$ref": "CacheId"
+                        },
+                        {
+                            "name": "request",
+                            "description": "URL spec of the request.",
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "name": "requestCacheNames",
+                    "description": "Requests cache names.",
+                    "parameters": [
+                        {
+                            "name": "securityOrigin",
+                            "description": "Security origin.",
+                            "type": "string"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "caches",
+                            "description": "Caches for the security origin.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "Cache"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "name": "requestCachedResponse",
+                    "description": "Fetches cache entry.",
+                    "parameters": [
+                        {
+                            "name": "cacheId",
+                            "description": "Id of cache that contains the enty.",
+                            "$ref": "CacheId"
+                        },
+                        {
+                            "name": "requestURL",
+                            "description": "URL spec of the request.",
+                            "type": "string"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "response",
+                            "description": "Response read from the cache.",
+                            "$ref": "CachedResponse"
+                        }
+                    ]
+                },
+                {
+                    "name": "requestEntries",
+                    "description": "Requests data from cache.",
+                    "parameters": [
+                        {
+                            "name": "cacheId",
+                            "description": "ID of cache to get entries from.",
+                            "$ref": "CacheId"
+                        },
+                        {
+                            "name": "skipCount",
+                            "description": "Number of records to skip.",
+                            "type": "integer"
+                        },
+                        {
+                            "name": "pageSize",
+                            "description": "Number of records to fetch.",
+                            "type": "integer"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "cacheDataEntries",
+                            "description": "Array of object store data entries.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "DataEntry"
+                            }
+                        },
+                        {
+                            "name": "hasMore",
+                            "description": "If true, there are more entries to fetch in the given range.",
+                            "type": "boolean"
+                        }
+                    ]
+                }
+            ]
+        },
+        {
+            "domain": "DOM",
+            "description": "This domain exposes DOM read/write operations. Each DOM Node is represented with its mirror object\nthat has an `id`. This `id` can be used to get additional information on the Node, resolve it into\nthe JavaScript object wrapper, etc. It is important that client receives DOM events only for the\nnodes that are known to the client. Backend keeps track of the nodes that were sent to the client\nand never sends the same node twice. It is client's responsibility to collect information about\nthe nodes that were sent to the client.<p>Note that `iframe` owner elements will return\ncorresponding document elements as their child nodes.</p>",
+            "dependencies": [
+                "Runtime"
+            ],
+            "types": [
+                {
+                    "id": "NodeId",
+                    "description": "Unique DOM node identifier.",
+                    "type": "integer"
+                },
+                {
+                    "id": "BackendNodeId",
+                    "description": "Unique DOM node identifier used to reference a node that may not have been pushed to the\nfront-end.",
+                    "type": "integer"
+                },
+                {
+                    "id": "BackendNode",
+                    "description": "Backend node with a friendly name.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "nodeType",
+                            "description": "`Node`'s nodeType.",
+                            "type": "integer"
+                        },
+                        {
+                            "name": "nodeName",
+                            "description": "`Node`'s nodeName.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "backendNodeId",
+                            "$ref": "BackendNodeId"
+                        }
+                    ]
+                },
+                {
+                    "id": "PseudoType",
+                    "description": "Pseudo element type.",
+                    "type": "string",
+                    "enum": [
+                        "first-line",
+                        "first-letter",
+                        "before",
+                        "after",
+                        "backdrop",
+                        "selection",
+                        "first-line-inherited",
+                        "scrollbar",
+                        "scrollbar-thumb",
+                        "scrollbar-button",
+                        "scrollbar-track",
+                        "scrollbar-track-piece",
+                        "scrollbar-corner",
+                        "resizer",
+                        "input-list-button"
+                    ]
+                },
+                {
+                    "id": "ShadowRootType",
+                    "description": "Shadow root type.",
+                    "type": "string",
+                    "enum": [
+                        "user-agent",
+                        "open",
+                        "closed"
+                    ]
+                },
+                {
+                    "id": "Node",
+                    "description": "DOM interaction is implemented in terms of mirror objects that represent the actual DOM nodes.\nDOMNode is a base node mirror type.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "nodeId",
+                            "description": "Node identifier that is passed into the rest of the DOM messages as the `nodeId`. Backend\nwill only push node with given `id` once. It is aware of all requested nodes and will only\nfire DOM events for nodes known to the client.",
+                            "$ref": "NodeId"
+                        },
+                        {
+                            "name": "parentId",
+                            "description": "The id of the parent node if any.",
+                            "optional": true,
+                            "$ref": "NodeId"
+                        },
+                        {
+                            "name": "backendNodeId",
+                            "description": "The BackendNodeId for this node.",
+                            "$ref": "BackendNodeId"
+                        },
+                        {
+                            "name": "nodeType",
+                            "description": "`Node`'s nodeType.",
+                            "type": "integer"
+                        },
+                        {
+                            "name": "nodeName",
+                            "description": "`Node`'s nodeName.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "localName",
+                            "description": "`Node`'s localName.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "nodeValue",
+                            "description": "`Node`'s nodeValue.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "childNodeCount",
+                            "description": "Child count for `Container` nodes.",
+                            "optional": true,
+                            "type": "integer"
+                        },
+                        {
+                            "name": "children",
+                            "description": "Child nodes of this node when requested with children.",
+                            "optional": true,
+                            "type": "array",
+                            "items": {
+                                "$ref": "Node"
+                            }
+                        },
+                        {
+                            "name": "attributes",
+                            "description": "Attributes of the `Element` node in the form of flat array `[name1, value1, name2, value2]`.",
+                            "optional": true,
+                            "type": "array",
+                            "items": {
+                                "type": "string"
+                            }
+                        },
+                        {
+                            "name": "documentURL",
+                            "description": "Document URL that `Document` or `FrameOwner` node points to.",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "baseURL",
+                            "description": "Base URL that `Document` or `FrameOwner` node uses for URL completion.",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "publicId",
+                            "description": "`DocumentType`'s publicId.",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "systemId",
+                            "description": "`DocumentType`'s systemId.",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "internalSubset",
+                            "description": "`DocumentType`'s internalSubset.",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "xmlVersion",
+                            "description": "`Document`'s XML version in case of XML documents.",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "name",
+                            "description": "`Attr`'s name.",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "value",
+                            "description": "`Attr`'s value.",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "pseudoType",
+                            "description": "Pseudo element type for this node.",
+                            "optional": true,
+                            "$ref": "PseudoType"
+                        },
+                        {
+                            "name": "shadowRootType",
+                            "description": "Shadow root type.",
+                            "optional": true,
+                            "$ref": "ShadowRootType"
+                        },
+                        {
+                            "name": "frameId",
+                            "description": "Frame ID for frame owner elements.",
+                            "optional": true,
+                            "$ref": "Page.FrameId"
+                        },
+                        {
+                            "name": "contentDocument",
+                            "description": "Content document for frame owner elements.",
+                            "optional": true,
+                            "$ref": "Node"
+                        },
+                        {
+                            "name": "shadowRoots",
+                            "description": "Shadow root list for given element host.",
+                            "optional": true,
+                            "type": "array",
+                            "items": {
+                                "$ref": "Node"
+                            }
+                        },
+                        {
+                            "name": "templateContent",
+                            "description": "Content document fragment for template elements.",
+                            "optional": true,
+                            "$ref": "Node"
+                        },
+                        {
+                            "name": "pseudoElements",
+                            "description": "Pseudo elements associated with this node.",
+                            "optional": true,
+                            "type": "array",
+                            "items": {
+                                "$ref": "Node"
+                            }
+                        },
+                        {
+                            "name": "importedDocument",
+                            "description": "Import document for the HTMLImport links.",
+                            "optional": true,
+                            "$ref": "Node"
+                        },
+                        {
+                            "name": "distributedNodes",
+                            "description": "Distributed nodes for given insertion point.",
+                            "optional": true,
+                            "type": "array",
+                            "items": {
+                                "$ref": "BackendNode"
+                            }
+                        },
+                        {
+                            "name": "isSVG",
+                            "description": "Whether the node is SVG.",
+                            "optional": true,
+                            "type": "boolean"
+                        }
+                    ]
+                },
+                {
+                    "id": "RGBA",
+                    "description": "A structure holding an RGBA color.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "r",
+                            "description": "The red component, in the [0-255] range.",
+                            "type": "integer"
+                        },
+                        {
+                            "name": "g",
+                            "description": "The green component, in the [0-255] range.",
+                            "type": "integer"
+                        },
+                        {
+                            "name": "b",
+                            "description": "The blue component, in the [0-255] range.",
+                            "type": "integer"
+                        },
+                        {
+                            "name": "a",
+                            "description": "The alpha component, in the [0-1] range (default: 1).",
+                            "optional": true,
+                            "type": "number"
+                        }
+                    ]
+                },
+                {
+                    "id": "Quad",
+                    "description": "An array of quad vertices, x immediately followed by y for each point, points clock-wise.",
+                    "type": "array",
+                    "items": {
+                        "type": "number"
+                    }
+                },
+                {
+                    "id": "BoxModel",
+                    "description": "Box model.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "content",
+                            "description": "Content box",
+                            "$ref": "Quad"
+                        },
+                        {
+                            "name": "padding",
+                            "description": "Padding box",
+                            "$ref": "Quad"
+                        },
+                        {
+                            "name": "border",
+                            "description": "Border box",
+                            "$ref": "Quad"
+                        },
+                        {
+                            "name": "margin",
+                            "description": "Margin box",
+                            "$ref": "Quad"
+                        },
+                        {
+                            "name": "width",
+                            "description": "Node width",
+                            "type": "integer"
+                        },
+                        {
+                            "name": "height",
+                            "description": "Node height",
+                            "type": "integer"
+                        },
+                        {
+                            "name": "shapeOutside",
+                            "description": "Shape outside coordinates",
+                            "optional": true,
+                            "$ref": "ShapeOutsideInfo"
+                        }
+                    ]
+                },
+                {
+                    "id": "ShapeOutsideInfo",
+                    "description": "CSS Shape Outside details.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "bounds",
+                            "description": "Shape bounds",
+                            "$ref": "Quad"
+                        },
+                        {
+                            "name": "shape",
+                            "description": "Shape coordinate details",
+                            "type": "array",
+                            "items": {
+                                "type": "any"
+                            }
+                        },
+                        {
+                            "name": "marginShape",
+                            "description": "Margin shape bounds",
+                            "type": "array",
+                            "items": {
+                                "type": "any"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "id": "Rect",
+                    "description": "Rectangle.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "x",
+                            "description": "X coordinate",
+                            "type": "number"
+                        },
+                        {
+                            "name": "y",
+                            "description": "Y coordinate",
+                            "type": "number"
+                        },
+                        {
+                            "name": "width",
+                            "description": "Rectangle width",
+                            "type": "number"
+                        },
+                        {
+                            "name": "height",
+                            "description": "Rectangle height",
+                            "type": "number"
+                        }
+                    ]
+                }
+            ],
+            "commands": [
+                {
+                    "name": "collectClassNamesFromSubtree",
+                    "description": "Collects class names for the node with given id and all of it's child nodes.",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "nodeId",
+                            "description": "Id of the node to collect class names.",
+                            "$ref": "NodeId"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "classNames",
+                            "description": "Class name list.",
+                            "type": "array",
+                            "items": {
+                                "type": "string"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "name": "copyTo",
+                    "description": "Creates a deep copy of the specified node and places it into the target container before the\ngiven anchor.",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "nodeId",
+                            "description": "Id of the node to copy.",
+                            "$ref": "NodeId"
+                        },
+                        {
+                            "name": "targetNodeId",
+                            "description": "Id of the element to drop the copy into.",
+                            "$ref": "NodeId"
+                        },
+                        {
+                            "name": "insertBeforeNodeId",
+                            "description": "Drop the copy before this node (if absent, the copy becomes the last child of\n`targetNodeId`).",
+                            "optional": true,
+                            "$ref": "NodeId"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "nodeId",
+                            "description": "Id of the node clone.",
+                            "$ref": "NodeId"
+                        }
+                    ]
+                },
+                {
+                    "name": "describeNode",
+                    "description": "Describes node given its id, does not require domain to be enabled. Does not start tracking any\nobjects, can be used for automation.",
+                    "parameters": [
+                        {
+                            "name": "nodeId",
+                            "description": "Identifier of the node.",
+                            "optional": true,
+                            "$ref": "NodeId"
+                        },
+                        {
+                            "name": "backendNodeId",
+                            "description": "Identifier of the backend node.",
+                            "optional": true,
+                            "$ref": "BackendNodeId"
+                        },
+                        {
+                            "name": "objectId",
+                            "description": "JavaScript object id of the node wrapper.",
+                            "optional": true,
+                            "$ref": "Runtime.RemoteObjectId"
+                        },
+                        {
+                            "name": "depth",
+                            "description": "The maximum depth at which children should be retrieved, defaults to 1. Use -1 for the\nentire subtree or provide an integer larger than 0.",
+                            "optional": true,
+                            "type": "integer"
+                        },
+                        {
+                            "name": "pierce",
+                            "description": "Whether or not iframes and shadow roots should be traversed when returning the subtree\n(default is false).",
+                            "optional": true,
+                            "type": "boolean"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "node",
+                            "description": "Node description.",
+                            "$ref": "Node"
+                        }
+                    ]
+                },
+                {
+                    "name": "disable",
+                    "description": "Disables DOM agent for the given page."
+                },
+                {
+                    "name": "discardSearchResults",
+                    "description": "Discards search results from the session with the given id. `getSearchResults` should no longer\nbe called for that search.",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "searchId",
+                            "description": "Unique search session identifier.",
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "name": "enable",
+                    "description": "Enables DOM agent for the given page."
+                },
+                {
+                    "name": "focus",
+                    "description": "Focuses the given element.",
+                    "parameters": [
+                        {
+                            "name": "nodeId",
+                            "description": "Identifier of the node.",
+                            "optional": true,
+                            "$ref": "NodeId"
+                        },
+                        {
+                            "name": "backendNodeId",
+                            "description": "Identifier of the backend node.",
+                            "optional": true,
+                            "$ref": "BackendNodeId"
+                        },
+                        {
+                            "name": "objectId",
+                            "description": "JavaScript object id of the node wrapper.",
+                            "optional": true,
+                            "$ref": "Runtime.RemoteObjectId"
+                        }
+                    ]
+                },
+                {
+                    "name": "getAttributes",
+                    "description": "Returns attributes for the specified node.",
+                    "parameters": [
+                        {
+                            "name": "nodeId",
+                            "description": "Id of the node to retrieve attibutes for.",
+                            "$ref": "NodeId"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "attributes",
+                            "description": "An interleaved array of node attribute names and values.",
+                            "type": "array",
+                            "items": {
+                                "type": "string"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "name": "getBoxModel",
+                    "description": "Returns boxes for the given node.",
+                    "parameters": [
+                        {
+                            "name": "nodeId",
+                            "description": "Identifier of the node.",
+                            "optional": true,
+                            "$ref": "NodeId"
+                        },
+                        {
+                            "name": "backendNodeId",
+                            "description": "Identifier of the backend node.",
+                            "optional": true,
+                            "$ref": "BackendNodeId"
+                        },
+                        {
+                            "name": "objectId",
+                            "description": "JavaScript object id of the node wrapper.",
+                            "optional": true,
+                            "$ref": "Runtime.RemoteObjectId"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "model",
+                            "description": "Box model for the node.",
+                            "$ref": "BoxModel"
+                        }
+                    ]
+                },
+                {
+                    "name": "getContentQuads",
+                    "description": "Returns quads that describe node position on the page. This method\nmight return multiple quads for inline nodes.",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "nodeId",
+                            "description": "Identifier of the node.",
+                            "optional": true,
+                            "$ref": "NodeId"
+                        },
+                        {
+                            "name": "backendNodeId",
+                            "description": "Identifier of the backend node.",
+                            "optional": true,
+                            "$ref": "BackendNodeId"
+                        },
+                        {
+                            "name": "objectId",
+                            "description": "JavaScript object id of the node wrapper.",
+                            "optional": true,
+                            "$ref": "Runtime.RemoteObjectId"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "quads",
+                            "description": "Quads that describe node layout relative to viewport.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "Quad"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "name": "getDocument",
+                    "description": "Returns the root DOM node (and optionally the subtree) to the caller.",
+                    "parameters": [
+                        {
+                            "name": "depth",
+                            "description": "The maximum depth at which children should be retrieved, defaults to 1. Use -1 for the\nentire subtree or provide an integer larger than 0.",
+                            "optional": true,
+                            "type": "integer"
+                        },
+                        {
+                            "name": "pierce",
+                            "description": "Whether or not iframes and shadow roots should be traversed when returning the subtree\n(default is false).",
+                            "optional": true,
+                            "type": "boolean"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "root",
+                            "description": "Resulting node.",
+                            "$ref": "Node"
+                        }
+                    ]
+                },
+                {
+                    "name": "getFlattenedDocument",
+                    "description": "Returns the root DOM node (and optionally the subtree) to the caller.",
+                    "parameters": [
+                        {
+                            "name": "depth",
+                            "description": "The maximum depth at which children should be retrieved, defaults to 1. Use -1 for the\nentire subtree or provide an integer larger than 0.",
+                            "optional": true,
+                            "type": "integer"
+                        },
+                        {
+                            "name": "pierce",
+                            "description": "Whether or not iframes and shadow roots should be traversed when returning the subtree\n(default is false).",
+                            "optional": true,
+                            "type": "boolean"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "nodes",
+                            "description": "Resulting node.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "Node"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "name": "getNodeForLocation",
+                    "description": "Returns node id at given location. Depending on whether DOM domain is enabled, nodeId is\neither returned or not.",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "x",
+                            "description": "X coordinate.",
+                            "type": "integer"
+                        },
+                        {
+                            "name": "y",
+                            "description": "Y coordinate.",
+                            "type": "integer"
+                        },
+                        {
+                            "name": "includeUserAgentShadowDOM",
+                            "description": "False to skip to the nearest non-UA shadow root ancestor (default: false).",
+                            "optional": true,
+                            "type": "boolean"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "backendNodeId",
+                            "description": "Resulting node.",
+                            "$ref": "BackendNodeId"
+                        },
+                        {
+                            "name": "nodeId",
+                            "description": "Id of the node at given coordinates, only when enabled.",
+                            "optional": true,
+                            "$ref": "NodeId"
+                        }
+                    ]
+                },
+                {
+                    "name": "getOuterHTML",
+                    "description": "Returns node's HTML markup.",
+                    "parameters": [
+                        {
+                            "name": "nodeId",
+                            "description": "Identifier of the node.",
+                            "optional": true,
+                            "$ref": "NodeId"
+                        },
+                        {
+                            "name": "backendNodeId",
+                            "description": "Identifier of the backend node.",
+                            "optional": true,
+                            "$ref": "BackendNodeId"
+                        },
+                        {
+                            "name": "objectId",
+                            "description": "JavaScript object id of the node wrapper.",
+                            "optional": true,
+                            "$ref": "Runtime.RemoteObjectId"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "outerHTML",
+                            "description": "Outer HTML markup.",
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "name": "getRelayoutBoundary",
+                    "description": "Returns the id of the nearest ancestor that is a relayout boundary.",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "nodeId",
+                            "description": "Id of the node.",
+                            "$ref": "NodeId"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "nodeId",
+                            "description": "Relayout boundary node id for the given node.",
+                            "$ref": "NodeId"
+                        }
+                    ]
+                },
+                {
+                    "name": "getSearchResults",
+                    "description": "Returns search results from given `fromIndex` to given `toIndex` from the search with the given\nidentifier.",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "searchId",
+                            "description": "Unique search session identifier.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "fromIndex",
+                            "description": "Start index of the search result to be returned.",
+                            "type": "integer"
+                        },
+                        {
+                            "name": "toIndex",
+                            "description": "End index of the search result to be returned.",
+                            "type": "integer"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "nodeIds",
+                            "description": "Ids of the search result nodes.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "NodeId"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "name": "hideHighlight",
+                    "description": "Hides any highlight.",
+                    "redirect": "Overlay"
+                },
+                {
+                    "name": "highlightNode",
+                    "description": "Highlights DOM node.",
+                    "redirect": "Overlay"
+                },
+                {
+                    "name": "highlightRect",
+                    "description": "Highlights given rectangle.",
+                    "redirect": "Overlay"
+                },
+                {
+                    "name": "markUndoableState",
+                    "description": "Marks last undoable state.",
+                    "experimental": true
+                },
+                {
+                    "name": "moveTo",
+                    "description": "Moves node into the new container, places it before the given anchor.",
+                    "parameters": [
+                        {
+                            "name": "nodeId",
+                            "description": "Id of the node to move.",
+                            "$ref": "NodeId"
+                        },
+                        {
+                            "name": "targetNodeId",
+                            "description": "Id of the element to drop the moved node into.",
+                            "$ref": "NodeId"
+                        },
+                        {
+                            "name": "insertBeforeNodeId",
+                            "description": "Drop node before this one (if absent, the moved node becomes the last child of\n`targetNodeId`).",
+                            "optional": true,
+                            "$ref": "NodeId"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "nodeId",
+                            "description": "New id of the moved node.",
+                            "$ref": "NodeId"
+                        }
+                    ]
+                },
+                {
+                    "name": "performSearch",
+                    "description": "Searches for a given string in the DOM tree. Use `getSearchResults` to access search results or\n`cancelSearch` to end this search session.",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "query",
+                            "description": "Plain text or query selector or XPath search query.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "includeUserAgentShadowDOM",
+                            "description": "True to search in user agent shadow DOM.",
+                            "optional": true,
+                            "type": "boolean"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "searchId",
+                            "description": "Unique search session identifier.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "resultCount",
+                            "description": "Number of search results.",
+                            "type": "integer"
+                        }
+                    ]
+                },
+                {
+                    "name": "pushNodeByPathToFrontend",
+                    "description": "Requests that the node is sent to the caller given its path. // FIXME, use XPath",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "path",
+                            "description": "Path to node in the proprietary format.",
+                            "type": "string"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "nodeId",
+                            "description": "Id of the node for given path.",
+                            "$ref": "NodeId"
+                        }
+                    ]
+                },
+                {
+                    "name": "pushNodesByBackendIdsToFrontend",
+                    "description": "Requests that a batch of nodes is sent to the caller given their backend node ids.",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "backendNodeIds",
+                            "description": "The array of backend node ids.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "BackendNodeId"
+                            }
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "nodeIds",
+                            "description": "The array of ids of pushed nodes that correspond to the backend ids specified in\nbackendNodeIds.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "NodeId"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "name": "querySelector",
+                    "description": "Executes `querySelector` on a given node.",
+                    "parameters": [
+                        {
+                            "name": "nodeId",
+                            "description": "Id of the node to query upon.",
+                            "$ref": "NodeId"
+                        },
+                        {
+                            "name": "selector",
+                            "description": "Selector string.",
+                            "type": "string"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "nodeId",
+                            "description": "Query selector result.",
+                            "$ref": "NodeId"
+                        }
+                    ]
+                },
+                {
+                    "name": "querySelectorAll",
+                    "description": "Executes `querySelectorAll` on a given node.",
+                    "parameters": [
+                        {
+                            "name": "nodeId",
+                            "description": "Id of the node to query upon.",
+                            "$ref": "NodeId"
+                        },
+                        {
+                            "name": "selector",
+                            "description": "Selector string.",
+                            "type": "string"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "nodeIds",
+                            "description": "Query selector result.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "NodeId"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "name": "redo",
+                    "description": "Re-does the last undone action.",
+                    "experimental": true
+                },
+                {
+                    "name": "removeAttribute",
+                    "description": "Removes attribute with given name from an element with given id.",
+                    "parameters": [
+                        {
+                            "name": "nodeId",
+                            "description": "Id of the element to remove attribute from.",
+                            "$ref": "NodeId"
+                        },
+                        {
+                            "name": "name",
+                            "description": "Name of the attribute to remove.",
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "name": "removeNode",
+                    "description": "Removes node with given id.",
+                    "parameters": [
+                        {
+                            "name": "nodeId",
+                            "description": "Id of the node to remove.",
+                            "$ref": "NodeId"
+                        }
+                    ]
+                },
+                {
+                    "name": "requestChildNodes",
+                    "description": "Requests that children of the node with given id are returned to the caller in form of\n`setChildNodes` events where not only immediate children are retrieved, but all children down to\nthe specified depth.",
+                    "parameters": [
+                        {
+                            "name": "nodeId",
+                            "description": "Id of the node to get children for.",
+                            "$ref": "NodeId"
+                        },
+                        {
+                            "name": "depth",
+                            "description": "The maximum depth at which children should be retrieved, defaults to 1. Use -1 for the\nentire subtree or provide an integer larger than 0.",
+                            "optional": true,
+                            "type": "integer"
+                        },
+                        {
+                            "name": "pierce",
+                            "description": "Whether or not iframes and shadow roots should be traversed when returning the sub-tree\n(default is false).",
+                            "optional": true,
+                            "type": "boolean"
+                        }
+                    ]
+                },
+                {
+                    "name": "requestNode",
+                    "description": "Requests that the node is sent to the caller given the JavaScript node object reference. All\nnodes that form the path from the node to the root are also sent to the client as a series of\n`setChildNodes` notifications.",
+                    "parameters": [
+                        {
+                            "name": "objectId",
+                            "description": "JavaScript object id to convert into node.",
+                            "$ref": "Runtime.RemoteObjectId"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "nodeId",
+                            "description": "Node id for given object.",
+                            "$ref": "NodeId"
+                        }
+                    ]
+                },
+                {
+                    "name": "resolveNode",
+                    "description": "Resolves the JavaScript node object for a given NodeId or BackendNodeId.",
+                    "parameters": [
+                        {
+                            "name": "nodeId",
+                            "description": "Id of the node to resolve.",
+                            "optional": true,
+                            "$ref": "NodeId"
+                        },
+                        {
+                            "name": "backendNodeId",
+                            "description": "Backend identifier of the node to resolve.",
+                            "optional": true,
+                            "$ref": "DOM.BackendNodeId"
+                        },
+                        {
+                            "name": "objectGroup",
+                            "description": "Symbolic group name that can be used to release multiple objects.",
+                            "optional": true,
+                            "type": "string"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "object",
+                            "description": "JavaScript object wrapper for given node.",
+                            "$ref": "Runtime.RemoteObject"
+                        }
+                    ]
+                },
+                {
+                    "name": "setAttributeValue",
+                    "description": "Sets attribute for an element with given id.",
+                    "parameters": [
+                        {
+                            "name": "nodeId",
+                            "description": "Id of the element to set attribute for.",
+                            "$ref": "NodeId"
+                        },
+                        {
+                            "name": "name",
+                            "description": "Attribute name.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "value",
+                            "description": "Attribute value.",
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "name": "setAttributesAsText",
+                    "description": "Sets attributes on element with given id. This method is useful when user edits some existing\nattribute value and types in several attribute name/value pairs.",
+                    "parameters": [
+                        {
+                            "name": "nodeId",
+                            "description": "Id of the element to set attributes for.",
+                            "$ref": "NodeId"
+                        },
+                        {
+                            "name": "text",
+                            "description": "Text with a number of attributes. Will parse this text using HTML parser.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "name",
+                            "description": "Attribute name to replace with new attributes derived from text in case text parsed\nsuccessfully.",
+                            "optional": true,
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "name": "setFileInputFiles",
+                    "description": "Sets files for the given file input element.",
+                    "parameters": [
+                        {
+                            "name": "files",
+                            "description": "Array of file paths to set.",
+                            "type": "array",
+                            "items": {
+                                "type": "string"
+                            }
+                        },
+                        {
+                            "name": "nodeId",
+                            "description": "Identifier of the node.",
+                            "optional": true,
+                            "$ref": "NodeId"
+                        },
+                        {
+                            "name": "backendNodeId",
+                            "description": "Identifier of the backend node.",
+                            "optional": true,
+                            "$ref": "BackendNodeId"
+                        },
+                        {
+                            "name": "objectId",
+                            "description": "JavaScript object id of the node wrapper.",
+                            "optional": true,
+                            "$ref": "Runtime.RemoteObjectId"
+                        }
+                    ]
+                },
+                {
+                    "name": "setInspectedNode",
+                    "description": "Enables console to refer to the node with given id via $x (see Command Line API for more details\n$x functions).",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "nodeId",
+                            "description": "DOM node id to be accessible by means of $x command line API.",
+                            "$ref": "NodeId"
+                        }
+                    ]
+                },
+                {
+                    "name": "setNodeName",
+                    "description": "Sets node name for a node with given id.",
+                    "parameters": [
+                        {
+                            "name": "nodeId",
+                            "description": "Id of the node to set name for.",
+                            "$ref": "NodeId"
+                        },
+                        {
+                            "name": "name",
+                            "description": "New node's name.",
+                            "type": "string"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "nodeId",
+                            "description": "New node's id.",
+                            "$ref": "NodeId"
+                        }
+                    ]
+                },
+                {
+                    "name": "setNodeValue",
+                    "description": "Sets node value for a node with given id.",
+                    "parameters": [
+                        {
+                            "name": "nodeId",
+                            "description": "Id of the node to set value for.",
+                            "$ref": "NodeId"
+                        },
+                        {
+                            "name": "value",
+                            "description": "New node's value.",
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "name": "setOuterHTML",
+                    "description": "Sets node HTML markup, returns new node id.",
+                    "parameters": [
+                        {
+                            "name": "nodeId",
+                            "description": "Id of the node to set markup for.",
+                            "$ref": "NodeId"
+                        },
+                        {
+                            "name": "outerHTML",
+                            "description": "Outer HTML markup to set.",
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "name": "undo",
+                    "description": "Undoes the last performed action.",
+                    "experimental": true
+                },
+                {
+                    "name": "getFrameOwner",
+                    "description": "Returns iframe node that owns iframe with the given domain.",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "frameId",
+                            "$ref": "Page.FrameId"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "backendNodeId",
+                            "description": "Resulting node.",
+                            "$ref": "BackendNodeId"
+                        },
+                        {
+                            "name": "nodeId",
+                            "description": "Id of the node at given coordinates, only when enabled.",
+                            "optional": true,
+                            "$ref": "NodeId"
+                        }
+                    ]
+                }
+            ],
+            "events": [
+                {
+                    "name": "attributeModified",
+                    "description": "Fired when `Element`'s attribute is modified.",
+                    "parameters": [
+                        {
+                            "name": "nodeId",
+                            "description": "Id of the node that has changed.",
+                            "$ref": "NodeId"
+                        },
+                        {
+                            "name": "name",
+                            "description": "Attribute name.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "value",
+                            "description": "Attribute value.",
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "name": "attributeRemoved",
+                    "description": "Fired when `Element`'s attribute is removed.",
+                    "parameters": [
+                        {
+                            "name": "nodeId",
+                            "description": "Id of the node that has changed.",
+                            "$ref": "NodeId"
+                        },
+                        {
+                            "name": "name",
+                            "description": "A ttribute name.",
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "name": "characterDataModified",
+                    "description": "Mirrors `DOMCharacterDataModified` event.",
+                    "parameters": [
+                        {
+                            "name": "nodeId",
+                            "description": "Id of the node that has changed.",
+                            "$ref": "NodeId"
+                        },
+                        {
+                            "name": "characterData",
+                            "description": "New text value.",
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "name": "childNodeCountUpdated",
+                    "description": "Fired when `Container`'s child node count has changed.",
+                    "parameters": [
+                        {
+                            "name": "nodeId",
+                            "description": "Id of the node that has changed.",
+                            "$ref": "NodeId"
+                        },
+                        {
+                            "name": "childNodeCount",
+                            "description": "New node count.",
+                            "type": "integer"
+                        }
+                    ]
+                },
+                {
+                    "name": "childNodeInserted",
+                    "description": "Mirrors `DOMNodeInserted` event.",
+                    "parameters": [
+                        {
+                            "name": "parentNodeId",
+                            "description": "Id of the node that has changed.",
+                            "$ref": "NodeId"
+                        },
+                        {
+                            "name": "previousNodeId",
+                            "description": "If of the previous siblint.",
+                            "$ref": "NodeId"
+                        },
+                        {
+                            "name": "node",
+                            "description": "Inserted node data.",
+                            "$ref": "Node"
+                        }
+                    ]
+                },
+                {
+                    "name": "childNodeRemoved",
+                    "description": "Mirrors `DOMNodeRemoved` event.",
+                    "parameters": [
+                        {
+                            "name": "parentNodeId",
+                            "description": "Parent id.",
+                            "$ref": "NodeId"
+                        },
+                        {
+                            "name": "nodeId",
+                            "description": "Id of the node that has been removed.",
+                            "$ref": "NodeId"
+                        }
+                    ]
+                },
+                {
+                    "name": "distributedNodesUpdated",
+                    "description": "Called when distrubution is changed.",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "insertionPointId",
+                            "description": "Insertion point where distrubuted nodes were updated.",
+                            "$ref": "NodeId"
+                        },
+                        {
+                            "name": "distributedNodes",
+                            "description": "Distributed nodes for given insertion point.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "BackendNode"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "name": "documentUpdated",
+                    "description": "Fired when `Document` has been totally updated. Node ids are no longer valid."
+                },
+                {
+                    "name": "inlineStyleInvalidated",
+                    "description": "Fired when `Element`'s inline style is modified via a CSS property modification.",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "nodeIds",
+                            "description": "Ids of the nodes for which the inline styles have been invalidated.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "NodeId"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "name": "pseudoElementAdded",
+                    "description": "Called when a pseudo element is added to an element.",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "parentId",
+                            "description": "Pseudo element's parent element id.",
+                            "$ref": "NodeId"
+                        },
+                        {
+                            "name": "pseudoElement",
+                            "description": "The added pseudo element.",
+                            "$ref": "Node"
+                        }
+                    ]
+                },
+                {
+                    "name": "pseudoElementRemoved",
+                    "description": "Called when a pseudo element is removed from an element.",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "parentId",
+                            "description": "Pseudo element's parent element id.",
+                            "$ref": "NodeId"
+                        },
+                        {
+                            "name": "pseudoElementId",
+                            "description": "The removed pseudo element id.",
+                            "$ref": "NodeId"
+                        }
+                    ]
+                },
+                {
+                    "name": "setChildNodes",
+                    "description": "Fired when backend wants to provide client with the missing DOM structure. This happens upon\nmost of the calls requesting node ids.",
+                    "parameters": [
+                        {
+                            "name": "parentId",
+                            "description": "Parent node id to populate with children.",
+                            "$ref": "NodeId"
+                        },
+                        {
+                            "name": "nodes",
+                            "description": "Child nodes array.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "Node"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "name": "shadowRootPopped",
+                    "description": "Called when shadow root is popped from the element.",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "hostId",
+                            "description": "Host element id.",
+                            "$ref": "NodeId"
+                        },
+                        {
+                            "name": "rootId",
+                            "description": "Shadow root id.",
+                            "$ref": "NodeId"
+                        }
+                    ]
+                },
+                {
+                    "name": "shadowRootPushed",
+                    "description": "Called when shadow root is pushed into the element.",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "hostId",
+                            "description": "Host element id.",
+                            "$ref": "NodeId"
+                        },
+                        {
+                            "name": "root",
+                            "description": "Shadow root.",
+                            "$ref": "Node"
+                        }
+                    ]
+                }
+            ]
+        },
+        {
+            "domain": "DOMDebugger",
+            "description": "DOM debugging allows setting breakpoints on particular DOM operations and events. JavaScript\nexecution will stop on these operations as if there was a regular breakpoint set.",
+            "dependencies": [
+                "DOM",
+                "Debugger",
+                "Runtime"
+            ],
+            "types": [
+                {
+                    "id": "DOMBreakpointType",
+                    "description": "DOM breakpoint type.",
+                    "type": "string",
+                    "enum": [
+                        "subtree-modified",
+                        "attribute-modified",
+                        "node-removed"
+                    ]
+                },
+                {
+                    "id": "EventListener",
+                    "description": "Object event listener.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "type",
+                            "description": "`EventListener`'s type.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "useCapture",
+                            "description": "`EventListener`'s useCapture.",
+                            "type": "boolean"
+                        },
+                        {
+                            "name": "passive",
+                            "description": "`EventListener`'s passive flag.",
+                            "type": "boolean"
+                        },
+                        {
+                            "name": "once",
+                            "description": "`EventListener`'s once flag.",
+                            "type": "boolean"
+                        },
+                        {
+                            "name": "scriptId",
+                            "description": "Script id of the handler code.",
+                            "$ref": "Runtime.ScriptId"
+                        },
+                        {
+                            "name": "lineNumber",
+                            "description": "Line number in the script (0-based).",
+                            "type": "integer"
+                        },
+                        {
+                            "name": "columnNumber",
+                            "description": "Column number in the script (0-based).",
+                            "type": "integer"
+                        },
+                        {
+                            "name": "handler",
+                            "description": "Event handler function value.",
+                            "optional": true,
+                            "$ref": "Runtime.RemoteObject"
+                        },
+                        {
+                            "name": "originalHandler",
+                            "description": "Event original handler function value.",
+                            "optional": true,
+                            "$ref": "Runtime.RemoteObject"
+                        },
+                        {
+                            "name": "backendNodeId",
+                            "description": "Node the listener is added to (if any).",
+                            "optional": true,
+                            "$ref": "DOM.BackendNodeId"
+                        }
+                    ]
+                }
+            ],
+            "commands": [
+                {
+                    "name": "getEventListeners",
+                    "description": "Returns event listeners of the given object.",
+                    "parameters": [
+                        {
+                            "name": "objectId",
+                            "description": "Identifier of the object to return listeners for.",
+                            "$ref": "Runtime.RemoteObjectId"
+                        },
+                        {
+                            "name": "depth",
+                            "description": "The maximum depth at which Node children should be retrieved, defaults to 1. Use -1 for the\nentire subtree or provide an integer larger than 0.",
+                            "optional": true,
+                            "type": "integer"
+                        },
+                        {
+                            "name": "pierce",
+                            "description": "Whether or not iframes and shadow roots should be traversed when returning the subtree\n(default is false). Reports listeners for all contexts if pierce is enabled.",
+                            "optional": true,
+                            "type": "boolean"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "listeners",
+                            "description": "Array of relevant listeners.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "EventListener"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "name": "removeDOMBreakpoint",
+                    "description": "Removes DOM breakpoint that was set using `setDOMBreakpoint`.",
+                    "parameters": [
+                        {
+                            "name": "nodeId",
+                            "description": "Identifier of the node to remove breakpoint from.",
+                            "$ref": "DOM.NodeId"
+                        },
+                        {
+                            "name": "type",
+                            "description": "Type of the breakpoint to remove.",
+                            "$ref": "DOMBreakpointType"
+                        }
+                    ]
+                },
+                {
+                    "name": "removeEventListenerBreakpoint",
+                    "description": "Removes breakpoint on particular DOM event.",
+                    "parameters": [
+                        {
+                            "name": "eventName",
+                            "description": "Event name.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "targetName",
+                            "description": "EventTarget interface name.",
+                            "experimental": true,
+                            "optional": true,
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "name": "removeInstrumentationBreakpoint",
+                    "description": "Removes breakpoint on particular native event.",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "eventName",
+                            "description": "Instrumentation name to stop on.",
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "name": "removeXHRBreakpoint",
+                    "description": "Removes breakpoint from XMLHttpRequest.",
+                    "parameters": [
+                        {
+                            "name": "url",
+                            "description": "Resource URL substring.",
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "name": "setDOMBreakpoint",
+                    "description": "Sets breakpoint on particular operation with DOM.",
+                    "parameters": [
+                        {
+                            "name": "nodeId",
+                            "description": "Identifier of the node to set breakpoint on.",
+                            "$ref": "DOM.NodeId"
+                        },
+                        {
+                            "name": "type",
+                            "description": "Type of the operation to stop upon.",
+                            "$ref": "DOMBreakpointType"
+                        }
+                    ]
+                },
+                {
+                    "name": "setEventListenerBreakpoint",
+                    "description": "Sets breakpoint on particular DOM event.",
+                    "parameters": [
+                        {
+                            "name": "eventName",
+                            "description": "DOM Event name to stop on (any DOM event will do).",
+                            "type": "string"
+                        },
+                        {
+                            "name": "targetName",
+                            "description": "EventTarget interface name to stop on. If equal to `\"*\"` or not provided, will stop on any\nEventTarget.",
+                            "experimental": true,
+                            "optional": true,
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "name": "setInstrumentationBreakpoint",
+                    "description": "Sets breakpoint on particular native event.",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "eventName",
+                            "description": "Instrumentation name to stop on.",
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "name": "setXHRBreakpoint",
+                    "description": "Sets breakpoint on XMLHttpRequest.",
+                    "parameters": [
+                        {
+                            "name": "url",
+                            "description": "Resource URL substring. All XHRs having this substring in the URL will get stopped upon.",
+                            "type": "string"
+                        }
+                    ]
+                }
+            ]
+        },
+        {
+            "domain": "DOMSnapshot",
+            "description": "This domain facilitates obtaining document snapshots with DOM, layout, and style information.",
+            "experimental": true,
+            "dependencies": [
+                "CSS",
+                "DOM",
+                "DOMDebugger",
+                "Page"
+            ],
+            "types": [
+                {
+                    "id": "DOMNode",
+                    "description": "A Node in the DOM tree.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "nodeType",
+                            "description": "`Node`'s nodeType.",
+                            "type": "integer"
+                        },
+                        {
+                            "name": "nodeName",
+                            "description": "`Node`'s nodeName.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "nodeValue",
+                            "description": "`Node`'s nodeValue.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "textValue",
+                            "description": "Only set for textarea elements, contains the text value.",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "inputValue",
+                            "description": "Only set for input elements, contains the input's associated text value.",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "inputChecked",
+                            "description": "Only set for radio and checkbox input elements, indicates if the element has been checked",
+                            "optional": true,
+                            "type": "boolean"
+                        },
+                        {
+                            "name": "optionSelected",
+                            "description": "Only set for option elements, indicates if the element has been selected",
+                            "optional": true,
+                            "type": "boolean"
+                        },
+                        {
+                            "name": "backendNodeId",
+                            "description": "`Node`'s id, corresponds to DOM.Node.backendNodeId.",
+                            "$ref": "DOM.BackendNodeId"
+                        },
+                        {
+                            "name": "childNodeIndexes",
+                            "description": "The indexes of the node's child nodes in the `domNodes` array returned by `getSnapshot`, if\nany.",
+                            "optional": true,
+                            "type": "array",
+                            "items": {
+                                "type": "integer"
+                            }
+                        },
+                        {
+                            "name": "attributes",
+                            "description": "Attributes of an `Element` node.",
+                            "optional": true,
+                            "type": "array",
+                            "items": {
+                                "$ref": "NameValue"
+                            }
+                        },
+                        {
+                            "name": "pseudoElementIndexes",
+                            "description": "Indexes of pseudo elements associated with this node in the `domNodes` array returned by\n`getSnapshot`, if any.",
+                            "optional": true,
+                            "type": "array",
+                            "items": {
+                                "type": "integer"
+                            }
+                        },
+                        {
+                            "name": "layoutNodeIndex",
+                            "description": "The index of the node's related layout tree node in the `layoutTreeNodes` array returned by\n`getSnapshot`, if any.",
+                            "optional": true,
+                            "type": "integer"
+                        },
+                        {
+                            "name": "documentURL",
+                            "description": "Document URL that `Document` or `FrameOwner` node points to.",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "baseURL",
+                            "description": "Base URL that `Document` or `FrameOwner` node uses for URL completion.",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "contentLanguage",
+                            "description": "Only set for documents, contains the document's content language.",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "documentEncoding",
+                            "description": "Only set for documents, contains the document's character set encoding.",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "publicId",
+                            "description": "`DocumentType` node's publicId.",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "systemId",
+                            "description": "`DocumentType` node's systemId.",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "frameId",
+                            "description": "Frame ID for frame owner elements and also for the document node.",
+                            "optional": true,
+                            "$ref": "Page.FrameId"
+                        },
+                        {
+                            "name": "contentDocumentIndex",
+                            "description": "The index of a frame owner element's content document in the `domNodes` array returned by\n`getSnapshot`, if any.",
+                            "optional": true,
+                            "type": "integer"
+                        },
+                        {
+                            "name": "pseudoType",
+                            "description": "Type of a pseudo element node.",
+                            "optional": true,
+                            "$ref": "DOM.PseudoType"
+                        },
+                        {
+                            "name": "shadowRootType",
+                            "description": "Shadow root type.",
+                            "optional": true,
+                            "$ref": "DOM.ShadowRootType"
+                        },
+                        {
+                            "name": "isClickable",
+                            "description": "Whether this DOM node responds to mouse clicks. This includes nodes that have had click\nevent listeners attached via JavaScript as well as anchor tags that naturally navigate when\nclicked.",
+                            "optional": true,
+                            "type": "boolean"
+                        },
+                        {
+                            "name": "eventListeners",
+                            "description": "Details of the node's event listeners, if any.",
+                            "optional": true,
+                            "type": "array",
+                            "items": {
+                                "$ref": "DOMDebugger.EventListener"
+                            }
+                        },
+                        {
+                            "name": "currentSourceURL",
+                            "description": "The selected url for nodes with a srcset attribute.",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "originURL",
+                            "description": "The url of the script (if any) that generates this node.",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "scrollOffsetX",
+                            "description": "Scroll offsets, set when this node is a Document.",
+                            "optional": true,
+                            "type": "number"
+                        },
+                        {
+                            "name": "scrollOffsetY",
+                            "optional": true,
+                            "type": "number"
+                        }
+                    ]
+                },
+                {
+                    "id": "InlineTextBox",
+                    "description": "Details of post layout rendered text positions. The exact layout should not be regarded as\nstable and may change between versions.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "boundingBox",
+                            "description": "The bounding box in document coordinates. Note that scroll offset of the document is ignored.",
+                            "$ref": "DOM.Rect"
+                        },
+                        {
+                            "name": "startCharacterIndex",
+                            "description": "The starting index in characters, for this post layout textbox substring. Characters that\nwould be represented as a surrogate pair in UTF-16 have length 2.",
+                            "type": "integer"
+                        },
+                        {
+                            "name": "numCharacters",
+                            "description": "The number of characters in this post layout textbox substring. Characters that would be\nrepresented as a surrogate pair in UTF-16 have length 2.",
+                            "type": "integer"
+                        }
+                    ]
+                },
+                {
+                    "id": "LayoutTreeNode",
+                    "description": "Details of an element in the DOM tree with a LayoutObject.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "domNodeIndex",
+                            "description": "The index of the related DOM node in the `domNodes` array returned by `getSnapshot`.",
+                            "type": "integer"
+                        },
+                        {
+                            "name": "boundingBox",
+                            "description": "The bounding box in document coordinates. Note that scroll offset of the document is ignored.",
+                            "$ref": "DOM.Rect"
+                        },
+                        {
+                            "name": "layoutText",
+                            "description": "Contents of the LayoutText, if any.",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "inlineTextNodes",
+                            "description": "The post-layout inline text nodes, if any.",
+                            "optional": true,
+                            "type": "array",
+                            "items": {
+                                "$ref": "InlineTextBox"
+                            }
+                        },
+                        {
+                            "name": "styleIndex",
+                            "description": "Index into the `computedStyles` array returned by `getSnapshot`.",
+                            "optional": true,
+                            "type": "integer"
+                        },
+                        {
+                            "name": "paintOrder",
+                            "description": "Global paint order index, which is determined by the stacking order of the nodes. Nodes\nthat are painted together will have the same index. Only provided if includePaintOrder in\ngetSnapshot was true.",
+                            "optional": true,
+                            "type": "integer"
+                        },
+                        {
+                            "name": "isStackingContext",
+                            "description": "Set to true to indicate the element begins a new stacking context.",
+                            "optional": true,
+                            "type": "boolean"
+                        }
+                    ]
+                },
+                {
+                    "id": "ComputedStyle",
+                    "description": "A subset of the full ComputedStyle as defined by the request whitelist.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "properties",
+                            "description": "Name/value pairs of computed style properties.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "NameValue"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "id": "NameValue",
+                    "description": "A name/value pair.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "name",
+                            "description": "Attribute/property name.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "value",
+                            "description": "Attribute/property value.",
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "id": "StringIndex",
+                    "description": "Index of the string in the strings table.",
+                    "type": "integer"
+                },
+                {
+                    "id": "ArrayOfStrings",
+                    "description": "Index of the string in the strings table.",
+                    "type": "array",
+                    "items": {
+                        "$ref": "StringIndex"
+                    }
+                },
+                {
+                    "id": "RareStringData",
+                    "description": "Data that is only present on rare nodes.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "index",
+                            "type": "array",
+                            "items": {
+                                "type": "integer"
+                            }
+                        },
+                        {
+                            "name": "value",
+                            "type": "array",
+                            "items": {
+                                "$ref": "StringIndex"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "id": "RareBooleanData",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "index",
+                            "type": "array",
+                            "items": {
+                                "type": "integer"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "id": "RareIntegerData",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "index",
+                            "type": "array",
+                            "items": {
+                                "type": "integer"
+                            }
+                        },
+                        {
+                            "name": "value",
+                            "type": "array",
+                            "items": {
+                                "type": "integer"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "id": "Rectangle",
+                    "type": "array",
+                    "items": {
+                        "type": "number"
+                    }
+                },
+                {
+                    "id": "DocumentSnapshot",
+                    "description": "Document snapshot.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "documentURL",
+                            "description": "Document URL that `Document` or `FrameOwner` node points to.",
+                            "$ref": "StringIndex"
+                        },
+                        {
+                            "name": "baseURL",
+                            "description": "Base URL that `Document` or `FrameOwner` node uses for URL completion.",
+                            "$ref": "StringIndex"
+                        },
+                        {
+                            "name": "contentLanguage",
+                            "description": "Contains the document's content language.",
+                            "$ref": "StringIndex"
+                        },
+                        {
+                            "name": "encodingName",
+                            "description": "Contains the document's character set encoding.",
+                            "$ref": "StringIndex"
+                        },
+                        {
+                            "name": "publicId",
+                            "description": "`DocumentType` node's publicId.",
+                            "$ref": "StringIndex"
+                        },
+                        {
+                            "name": "systemId",
+                            "description": "`DocumentType` node's systemId.",
+                            "$ref": "StringIndex"
+                        },
+                        {
+                            "name": "frameId",
+                            "description": "Frame ID for frame owner elements and also for the document node.",
+                            "$ref": "StringIndex"
+                        },
+                        {
+                            "name": "nodes",
+                            "description": "A table with dom nodes.",
+                            "$ref": "NodeTreeSnapshot"
+                        },
+                        {
+                            "name": "layout",
+                            "description": "The nodes in the layout tree.",
+                            "$ref": "LayoutTreeSnapshot"
+                        },
+                        {
+                            "name": "textBoxes",
+                            "description": "The post-layout inline text nodes.",
+                            "$ref": "TextBoxSnapshot"
+                        },
+                        {
+                            "name": "scrollOffsetX",
+                            "description": "Scroll offsets.",
+                            "optional": true,
+                            "type": "number"
+                        },
+                        {
+                            "name": "scrollOffsetY",
+                            "optional": true,
+                            "type": "number"
+                        }
+                    ]
+                },
+                {
+                    "id": "NodeTreeSnapshot",
+                    "description": "Table containing nodes.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "parentIndex",
+                            "description": "Parent node index.",
+                            "optional": true,
+                            "type": "array",
+                            "items": {
+                                "type": "integer"
+                            }
+                        },
+                        {
+                            "name": "nodeType",
+                            "description": "`Node`'s nodeType.",
+                            "optional": true,
+                            "type": "array",
+                            "items": {
+                                "type": "integer"
+                            }
+                        },
+                        {
+                            "name": "nodeName",
+                            "description": "`Node`'s nodeName.",
+                            "optional": true,
+                            "type": "array",
+                            "items": {
+                                "$ref": "StringIndex"
+                            }
+                        },
+                        {
+                            "name": "nodeValue",
+                            "description": "`Node`'s nodeValue.",
+                            "optional": true,
+                            "type": "array",
+                            "items": {
+                                "$ref": "StringIndex"
+                            }
+                        },
+                        {
+                            "name": "backendNodeId",
+                            "description": "`Node`'s id, corresponds to DOM.Node.backendNodeId.",
+                            "optional": true,
+                            "type": "array",
+                            "items": {
+                                "$ref": "DOM.BackendNodeId"
+                            }
+                        },
+                        {
+                            "name": "attributes",
+                            "description": "Attributes of an `Element` node. Flatten name, value pairs.",
+                            "optional": true,
+                            "type": "array",
+                            "items": {
+                                "$ref": "ArrayOfStrings"
+                            }
+                        },
+                        {
+                            "name": "textValue",
+                            "description": "Only set for textarea elements, contains the text value.",
+                            "optional": true,
+                            "$ref": "RareStringData"
+                        },
+                        {
+                            "name": "inputValue",
+                            "description": "Only set for input elements, contains the input's associated text value.",
+                            "optional": true,
+                            "$ref": "RareStringData"
+                        },
+                        {
+                            "name": "inputChecked",
+                            "description": "Only set for radio and checkbox input elements, indicates if the element has been checked",
+                            "optional": true,
+                            "$ref": "RareBooleanData"
+                        },
+                        {
+                            "name": "optionSelected",
+                            "description": "Only set for option elements, indicates if the element has been selected",
+                            "optional": true,
+                            "$ref": "RareBooleanData"
+                        },
+                        {
+                            "name": "contentDocumentIndex",
+                            "description": "The index of the document in the list of the snapshot documents.",
+                            "optional": true,
+                            "$ref": "RareIntegerData"
+                        },
+                        {
+                            "name": "pseudoType",
+                            "description": "Type of a pseudo element node.",
+                            "optional": true,
+                            "$ref": "RareStringData"
+                        },
+                        {
+                            "name": "isClickable",
+                            "description": "Whether this DOM node responds to mouse clicks. This includes nodes that have had click\nevent listeners attached via JavaScript as well as anchor tags that naturally navigate when\nclicked.",
+                            "optional": true,
+                            "$ref": "RareBooleanData"
+                        },
+                        {
+                            "name": "currentSourceURL",
+                            "description": "The selected url for nodes with a srcset attribute.",
+                            "optional": true,
+                            "$ref": "RareStringData"
+                        },
+                        {
+                            "name": "originURL",
+                            "description": "The url of the script (if any) that generates this node.",
+                            "optional": true,
+                            "$ref": "RareStringData"
+                        }
+                    ]
+                },
+                {
+                    "id": "LayoutTreeSnapshot",
+                    "description": "Details of an element in the DOM tree with a LayoutObject.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "nodeIndex",
+                            "description": "The index of the related DOM node in the `domNodes` array returned by `getSnapshot`.",
+                            "type": "array",
+                            "items": {
+                                "type": "integer"
+                            }
+                        },
+                        {
+                            "name": "styles",
+                            "description": "Index into the `computedStyles` array returned by `captureSnapshot`.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "ArrayOfStrings"
+                            }
+                        },
+                        {
+                            "name": "bounds",
+                            "description": "The absolute position bounding box.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "Rectangle"
+                            }
+                        },
+                        {
+                            "name": "text",
+                            "description": "Contents of the LayoutText, if any.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "StringIndex"
+                            }
+                        },
+                        {
+                            "name": "stackingContexts",
+                            "description": "Stacking context information.",
+                            "$ref": "RareBooleanData"
+                        }
+                    ]
+                },
+                {
+                    "id": "TextBoxSnapshot",
+                    "description": "Details of post layout rendered text positions. The exact layout should not be regarded as\nstable and may change between versions.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "layoutIndex",
+                            "description": "Intex of th elayout tree node that owns this box collection.",
+                            "type": "array",
+                            "items": {
+                                "type": "integer"
+                            }
+                        },
+                        {
+                            "name": "bounds",
+                            "description": "The absolute position bounding box.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "Rectangle"
+                            }
+                        },
+                        {
+                            "name": "start",
+                            "description": "The starting index in characters, for this post layout textbox substring. Characters that\nwould be represented as a surrogate pair in UTF-16 have length 2.",
+                            "type": "array",
+                            "items": {
+                                "type": "integer"
+                            }
+                        },
+                        {
+                            "name": "length",
+                            "description": "The number of characters in this post layout textbox substring. Characters that would be\nrepresented as a surrogate pair in UTF-16 have length 2.",
+                            "type": "array",
+                            "items": {
+                                "type": "integer"
+                            }
+                        }
+                    ]
+                }
+            ],
+            "commands": [
+                {
+                    "name": "disable",
+                    "description": "Disables DOM snapshot agent for the given page."
+                },
+                {
+                    "name": "enable",
+                    "description": "Enables DOM snapshot agent for the given page."
+                },
+                {
+                    "name": "getSnapshot",
+                    "description": "Returns a document snapshot, including the full DOM tree of the root node (including iframes,\ntemplate contents, and imported documents) in a flattened array, as well as layout and\nwhite-listed computed style information for the nodes. Shadow DOM in the returned DOM tree is\nflattened.",
+                    "deprecated": true,
+                    "parameters": [
+                        {
+                            "name": "computedStyleWhitelist",
+                            "description": "Whitelist of computed styles to return.",
+                            "type": "array",
+                            "items": {
+                                "type": "string"
+                            }
+                        },
+                        {
+                            "name": "includeEventListeners",
+                            "description": "Whether or not to retrieve details of DOM listeners (default false).",
+                            "optional": true,
+                            "type": "boolean"
+                        },
+                        {
+                            "name": "includePaintOrder",
+                            "description": "Whether to determine and include the paint order index of LayoutTreeNodes (default false).",
+                            "optional": true,
+                            "type": "boolean"
+                        },
+                        {
+                            "name": "includeUserAgentShadowTree",
+                            "description": "Whether to include UA shadow tree in the snapshot (default false).",
+                            "optional": true,
+                            "type": "boolean"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "domNodes",
+                            "description": "The nodes in the DOM tree. The DOMNode at index 0 corresponds to the root document.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "DOMNode"
+                            }
+                        },
+                        {
+                            "name": "layoutTreeNodes",
+                            "description": "The nodes in the layout tree.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "LayoutTreeNode"
+                            }
+                        },
+                        {
+                            "name": "computedStyles",
+                            "description": "Whitelisted ComputedStyle properties for each node in the layout tree.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "ComputedStyle"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "name": "captureSnapshot",
+                    "description": "Returns a document snapshot, including the full DOM tree of the root node (including iframes,\ntemplate contents, and imported documents) in a flattened array, as well as layout and\nwhite-listed computed style information for the nodes. Shadow DOM in the returned DOM tree is\nflattened.",
+                    "parameters": [
+                        {
+                            "name": "computedStyles",
+                            "description": "Whitelist of computed styles to return.",
+                            "type": "array",
+                            "items": {
+                                "type": "string"
+                            }
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "documents",
+                            "description": "The nodes in the DOM tree. The DOMNode at index 0 corresponds to the root document.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "DocumentSnapshot"
+                            }
+                        },
+                        {
+                            "name": "strings",
+                            "description": "Shared string table that all string properties refer to with indexes.",
+                            "type": "array",
+                            "items": {
+                                "type": "string"
+                            }
+                        }
+                    ]
+                }
+            ]
+        },
+        {
+            "domain": "DOMStorage",
+            "description": "Query and modify DOM storage.",
+            "experimental": true,
+            "types": [
+                {
+                    "id": "StorageId",
+                    "description": "DOM Storage identifier.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "securityOrigin",
+                            "description": "Security origin for the storage.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "isLocalStorage",
+                            "description": "Whether the storage is local storage (not session storage).",
+                            "type": "boolean"
+                        }
+                    ]
+                },
+                {
+                    "id": "Item",
+                    "description": "DOM Storage item.",
+                    "type": "array",
+                    "items": {
+                        "type": "string"
+                    }
+                }
+            ],
+            "commands": [
+                {
+                    "name": "clear",
+                    "parameters": [
+                        {
+                            "name": "storageId",
+                            "$ref": "StorageId"
+                        }
+                    ]
+                },
+                {
+                    "name": "disable",
+                    "description": "Disables storage tracking, prevents storage events from being sent to the client."
+                },
+                {
+                    "name": "enable",
+                    "description": "Enables storage tracking, storage events will now be delivered to the client."
+                },
+                {
+                    "name": "getDOMStorageItems",
+                    "parameters": [
+                        {
+                            "name": "storageId",
+                            "$ref": "StorageId"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "entries",
+                            "type": "array",
+                            "items": {
+                                "$ref": "Item"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "name": "removeDOMStorageItem",
+                    "parameters": [
+                        {
+                            "name": "storageId",
+                            "$ref": "StorageId"
+                        },
+                        {
+                            "name": "key",
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "name": "setDOMStorageItem",
+                    "parameters": [
+                        {
+                            "name": "storageId",
+                            "$ref": "StorageId"
+                        },
+                        {
+                            "name": "key",
+                            "type": "string"
+                        },
+                        {
+                            "name": "value",
+                            "type": "string"
+                        }
+                    ]
+                }
+            ],
+            "events": [
+                {
+                    "name": "domStorageItemAdded",
+                    "parameters": [
+                        {
+                            "name": "storageId",
+                            "$ref": "StorageId"
+                        },
+                        {
+                            "name": "key",
+                            "type": "string"
+                        },
+                        {
+                            "name": "newValue",
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "name": "domStorageItemRemoved",
+                    "parameters": [
+                        {
+                            "name": "storageId",
+                            "$ref": "StorageId"
+                        },
+                        {
+                            "name": "key",
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "name": "domStorageItemUpdated",
+                    "parameters": [
+                        {
+                            "name": "storageId",
+                            "$ref": "StorageId"
+                        },
+                        {
+                            "name": "key",
+                            "type": "string"
+                        },
+                        {
+                            "name": "oldValue",
+                            "type": "string"
+                        },
+                        {
+                            "name": "newValue",
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "name": "domStorageItemsCleared",
+                    "parameters": [
+                        {
+                            "name": "storageId",
+                            "$ref": "StorageId"
+                        }
+                    ]
+                }
+            ]
+        },
+        {
+            "domain": "Database",
+            "experimental": true,
+            "types": [
+                {
+                    "id": "DatabaseId",
+                    "description": "Unique identifier of Database object.",
+                    "type": "string"
+                },
+                {
+                    "id": "Database",
+                    "description": "Database object.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "id",
+                            "description": "Database ID.",
+                            "$ref": "DatabaseId"
+                        },
+                        {
+                            "name": "domain",
+                            "description": "Database domain.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "name",
+                            "description": "Database name.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "version",
+                            "description": "Database version.",
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "id": "Error",
+                    "description": "Database error.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "message",
+                            "description": "Error message.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "code",
+                            "description": "Error code.",
+                            "type": "integer"
+                        }
+                    ]
+                }
+            ],
+            "commands": [
+                {
+                    "name": "disable",
+                    "description": "Disables database tracking, prevents database events from being sent to the client."
+                },
+                {
+                    "name": "enable",
+                    "description": "Enables database tracking, database events will now be delivered to the client."
+                },
+                {
+                    "name": "executeSQL",
+                    "parameters": [
+                        {
+                            "name": "databaseId",
+                            "$ref": "DatabaseId"
+                        },
+                        {
+                            "name": "query",
+                            "type": "string"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "columnNames",
+                            "optional": true,
+                            "type": "array",
+                            "items": {
+                                "type": "string"
+                            }
+                        },
+                        {
+                            "name": "values",
+                            "optional": true,
+                            "type": "array",
+                            "items": {
+                                "type": "any"
+                            }
+                        },
+                        {
+                            "name": "sqlError",
+                            "optional": true,
+                            "$ref": "Error"
+                        }
+                    ]
+                },
+                {
+                    "name": "getDatabaseTableNames",
+                    "parameters": [
+                        {
+                            "name": "databaseId",
+                            "$ref": "DatabaseId"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "tableNames",
+                            "type": "array",
+                            "items": {
+                                "type": "string"
+                            }
+                        }
+                    ]
+                }
+            ],
+            "events": [
+                {
+                    "name": "addDatabase",
+                    "parameters": [
+                        {
+                            "name": "database",
+                            "$ref": "Database"
+                        }
+                    ]
+                }
+            ]
+        },
+        {
+            "domain": "DeviceOrientation",
+            "experimental": true,
+            "commands": [
+                {
+                    "name": "clearDeviceOrientationOverride",
+                    "description": "Clears the overridden Device Orientation."
+                },
+                {
+                    "name": "setDeviceOrientationOverride",
+                    "description": "Overrides the Device Orientation.",
+                    "parameters": [
+                        {
+                            "name": "alpha",
+                            "description": "Mock alpha",
+                            "type": "number"
+                        },
+                        {
+                            "name": "beta",
+                            "description": "Mock beta",
+                            "type": "number"
+                        },
+                        {
+                            "name": "gamma",
+                            "description": "Mock gamma",
+                            "type": "number"
+                        }
+                    ]
+                }
+            ]
+        },
+        {
+            "domain": "Emulation",
+            "description": "This domain emulates different environments for the page.",
+            "dependencies": [
+                "DOM",
+                "Page",
+                "Runtime"
+            ],
+            "types": [
+                {
+                    "id": "ScreenOrientation",
+                    "description": "Screen orientation.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "type",
+                            "description": "Orientation type.",
+                            "type": "string",
+                            "enum": [
+                                "portraitPrimary",
+                                "portraitSecondary",
+                                "landscapePrimary",
+                                "landscapeSecondary"
+                            ]
+                        },
+                        {
+                            "name": "angle",
+                            "description": "Orientation angle.",
+                            "type": "integer"
+                        }
+                    ]
+                },
+                {
+                    "id": "VirtualTimePolicy",
+                    "description": "advance: If the scheduler runs out of immediate work, the virtual time base may fast forward to\nallow the next delayed task (if any) to run; pause: The virtual time base may not advance;\npauseIfNetworkFetchesPending: The virtual time base may not advance if there are any pending\nresource fetches.",
+                    "experimental": true,
+                    "type": "string",
+                    "enum": [
+                        "advance",
+                        "pause",
+                        "pauseIfNetworkFetchesPending"
+                    ]
+                }
+            ],
+            "commands": [
+                {
+                    "name": "canEmulate",
+                    "description": "Tells whether emulation is supported.",
+                    "returns": [
+                        {
+                            "name": "result",
+                            "description": "True if emulation is supported.",
+                            "type": "boolean"
+                        }
+                    ]
+                },
+                {
+                    "name": "clearDeviceMetricsOverride",
+                    "description": "Clears the overriden device metrics."
+                },
+                {
+                    "name": "clearGeolocationOverride",
+                    "description": "Clears the overriden Geolocation Position and Error."
+                },
+                {
+                    "name": "resetPageScaleFactor",
+                    "description": "Requests that page scale factor is reset to initial values.",
+                    "experimental": true
+                },
+                {
+                    "name": "setFocusEmulationEnabled",
+                    "description": "Enables or disables simulating a focused and active page.",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "enabled",
+                            "description": "Whether to enable to disable focus emulation.",
+                            "type": "boolean"
+                        }
+                    ]
+                },
+                {
+                    "name": "setCPUThrottlingRate",
+                    "description": "Enables CPU throttling to emulate slow CPUs.",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "rate",
+                            "description": "Throttling rate as a slowdown factor (1 is no throttle, 2 is 2x slowdown, etc).",
+                            "type": "number"
+                        }
+                    ]
+                },
+                {
+                    "name": "setDefaultBackgroundColorOverride",
+                    "description": "Sets or clears an override of the default background color of the frame. This override is used\nif the content does not specify one.",
+                    "parameters": [
+                        {
+                            "name": "color",
+                            "description": "RGBA of the default background color. If not specified, any existing override will be\ncleared.",
+                            "optional": true,
+                            "$ref": "DOM.RGBA"
+                        }
+                    ]
+                },
+                {
+                    "name": "setDeviceMetricsOverride",
+                    "description": "Overrides the values of device screen dimensions (window.screen.width, window.screen.height,\nwindow.innerWidth, window.innerHeight, and \"device-width\"/\"device-height\"-related CSS media\nquery results).",
+                    "parameters": [
+                        {
+                            "name": "width",
+                            "description": "Overriding width value in pixels (minimum 0, maximum 10000000). 0 disables the override.",
+                            "type": "integer"
+                        },
+                        {
+                            "name": "height",
+                            "description": "Overriding height value in pixels (minimum 0, maximum 10000000). 0 disables the override.",
+                            "type": "integer"
+                        },
+                        {
+                            "name": "deviceScaleFactor",
+                            "description": "Overriding device scale factor value. 0 disables the override.",
+                            "type": "number"
+                        },
+                        {
+                            "name": "mobile",
+                            "description": "Whether to emulate mobile device. This includes viewport meta tag, overlay scrollbars, text\nautosizing and more.",
+                            "type": "boolean"
+                        },
+                        {
+                            "name": "scale",
+                            "description": "Scale to apply to resulting view image.",
+                            "experimental": true,
+                            "optional": true,
+                            "type": "number"
+                        },
+                        {
+                            "name": "screenWidth",
+                            "description": "Overriding screen width value in pixels (minimum 0, maximum 10000000).",
+                            "experimental": true,
+                            "optional": true,
+                            "type": "integer"
+                        },
+                        {
+                            "name": "screenHeight",
+                            "description": "Overriding screen height value in pixels (minimum 0, maximum 10000000).",
+                            "experimental": true,
+                            "optional": true,
+                            "type": "integer"
+                        },
+                        {
+                            "name": "positionX",
+                            "description": "Overriding view X position on screen in pixels (minimum 0, maximum 10000000).",
+                            "experimental": true,
+                            "optional": true,
+                            "type": "integer"
+                        },
+                        {
+                            "name": "positionY",
+                            "description": "Overriding view Y position on screen in pixels (minimum 0, maximum 10000000).",
+                            "experimental": true,
+                            "optional": true,
+                            "type": "integer"
+                        },
+                        {
+                            "name": "dontSetVisibleSize",
+                            "description": "Do not set visible view size, rely upon explicit setVisibleSize call.",
+                            "experimental": true,
+                            "optional": true,
+                            "type": "boolean"
+                        },
+                        {
+                            "name": "screenOrientation",
+                            "description": "Screen orientation override.",
+                            "optional": true,
+                            "$ref": "ScreenOrientation"
+                        },
+                        {
+                            "name": "viewport",
+                            "description": "If set, the visible area of the page will be overridden to this viewport. This viewport\nchange is not observed by the page, e.g. viewport-relative elements do not change positions.",
+                            "experimental": true,
+                            "optional": true,
+                            "$ref": "Page.Viewport"
+                        }
+                    ]
+                },
+                {
+                    "name": "setScrollbarsHidden",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "hidden",
+                            "description": "Whether scrollbars should be always hidden.",
+                            "type": "boolean"
+                        }
+                    ]
+                },
+                {
+                    "name": "setDocumentCookieDisabled",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "disabled",
+                            "description": "Whether document.coookie API should be disabled.",
+                            "type": "boolean"
+                        }
+                    ]
+                },
+                {
+                    "name": "setEmitTouchEventsForMouse",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "enabled",
+                            "description": "Whether touch emulation based on mouse input should be enabled.",
+                            "type": "boolean"
+                        },
+                        {
+                            "name": "configuration",
+                            "description": "Touch/gesture events configuration. Default: current platform.",
+                            "optional": true,
+                            "type": "string",
+                            "enum": [
+                                "mobile",
+                                "desktop"
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "name": "setEmulatedMedia",
+                    "description": "Emulates the given media for CSS media queries.",
+                    "parameters": [
+                        {
+                            "name": "media",
+                            "description": "Media type to emulate. Empty string disables the override.",
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "name": "setGeolocationOverride",
+                    "description": "Overrides the Geolocation Position or Error. Omitting any of the parameters emulates position\nunavailable.",
+                    "parameters": [
+                        {
+                            "name": "latitude",
+                            "description": "Mock latitude",
+                            "optional": true,
+                            "type": "number"
+                        },
+                        {
+                            "name": "longitude",
+                            "description": "Mock longitude",
+                            "optional": true,
+                            "type": "number"
+                        },
+                        {
+                            "name": "accuracy",
+                            "description": "Mock accuracy",
+                            "optional": true,
+                            "type": "number"
+                        }
+                    ]
+                },
+                {
+                    "name": "setNavigatorOverrides",
+                    "description": "Overrides value returned by the javascript navigator object.",
+                    "experimental": true,
+                    "deprecated": true,
+                    "parameters": [
+                        {
+                            "name": "platform",
+                            "description": "The platform navigator.platform should return.",
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "name": "setPageScaleFactor",
+                    "description": "Sets a specified page scale factor.",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "pageScaleFactor",
+                            "description": "Page scale factor.",
+                            "type": "number"
+                        }
+                    ]
+                },
+                {
+                    "name": "setScriptExecutionDisabled",
+                    "description": "Switches script execution in the page.",
+                    "parameters": [
+                        {
+                            "name": "value",
+                            "description": "Whether script execution should be disabled in the page.",
+                            "type": "boolean"
+                        }
+                    ]
+                },
+                {
+                    "name": "setTouchEmulationEnabled",
+                    "description": "Enables touch on platforms which do not support them.",
+                    "parameters": [
+                        {
+                            "name": "enabled",
+                            "description": "Whether the touch event emulation should be enabled.",
+                            "type": "boolean"
+                        },
+                        {
+                            "name": "maxTouchPoints",
+                            "description": "Maximum touch points supported. Defaults to one.",
+                            "optional": true,
+                            "type": "integer"
+                        }
+                    ]
+                },
+                {
+                    "name": "setVirtualTimePolicy",
+                    "description": "Turns on virtual time for all frames (replacing real-time with a synthetic time source) and sets\nthe current virtual time policy.  Note this supersedes any previous time budget.",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "policy",
+                            "$ref": "VirtualTimePolicy"
+                        },
+                        {
+                            "name": "budget",
+                            "description": "If set, after this many virtual milliseconds have elapsed virtual time will be paused and a\nvirtualTimeBudgetExpired event is sent.",
+                            "optional": true,
+                            "type": "number"
+                        },
+                        {
+                            "name": "maxVirtualTimeTaskStarvationCount",
+                            "description": "If set this specifies the maximum number of tasks that can be run before virtual is forced\nforwards to prevent deadlock.",
+                            "optional": true,
+                            "type": "integer"
+                        },
+                        {
+                            "name": "waitForNavigation",
+                            "description": "If set the virtual time policy change should be deferred until any frame starts navigating.\nNote any previous deferred policy change is superseded.",
+                            "optional": true,
+                            "type": "boolean"
+                        },
+                        {
+                            "name": "initialVirtualTime",
+                            "description": "If set, base::Time::Now will be overriden to initially return this value.",
+                            "optional": true,
+                            "$ref": "Network.TimeSinceEpoch"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "virtualTimeTicksBase",
+                            "description": "Absolute timestamp at which virtual time was first enabled (up time in milliseconds).",
+                            "type": "number"
+                        }
+                    ]
+                },
+                {
+                    "name": "setVisibleSize",
+                    "description": "Resizes the frame/viewport of the page. Note that this does not affect the frame's container\n(e.g. browser window). Can be used to produce screenshots of the specified size. Not supported\non Android.",
+                    "experimental": true,
+                    "deprecated": true,
+                    "parameters": [
+                        {
+                            "name": "width",
+                            "description": "Frame width (DIP).",
+                            "type": "integer"
+                        },
+                        {
+                            "name": "height",
+                            "description": "Frame height (DIP).",
+                            "type": "integer"
+                        }
+                    ]
+                },
+                {
+                    "name": "setUserAgentOverride",
+                    "description": "Allows overriding user agent with the given string.",
+                    "parameters": [
+                        {
+                            "name": "userAgent",
+                            "description": "User agent to use.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "acceptLanguage",
+                            "description": "Browser langugage to emulate.",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "platform",
+                            "description": "The platform navigator.platform should return.",
+                            "optional": true,
+                            "type": "string"
+                        }
+                    ]
+                }
+            ],
+            "events": [
+                {
+                    "name": "virtualTimeAdvanced",
+                    "description": "Notification sent after the virtual time has advanced.",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "virtualTimeElapsed",
+                            "description": "The amount of virtual time that has elapsed in milliseconds since virtual time was first\nenabled.",
+                            "type": "number"
+                        }
+                    ]
+                },
+                {
+                    "name": "virtualTimeBudgetExpired",
+                    "description": "Notification sent after the virtual time budget for the current VirtualTimePolicy has run out.",
+                    "experimental": true
+                },
+                {
+                    "name": "virtualTimePaused",
+                    "description": "Notification sent after the virtual time has paused.",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "virtualTimeElapsed",
+                            "description": "The amount of virtual time that has elapsed in milliseconds since virtual time was first\nenabled.",
+                            "type": "number"
+                        }
+                    ]
+                }
+            ]
+        },
+        {
+            "domain": "HeadlessExperimental",
+            "description": "This domain provides experimental commands only supported in headless mode.",
+            "experimental": true,
+            "dependencies": [
+                "Page",
+                "Runtime"
+            ],
+            "types": [
+                {
+                    "id": "ScreenshotParams",
+                    "description": "Encoding options for a screenshot.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "format",
+                            "description": "Image compression format (defaults to png).",
+                            "optional": true,
+                            "type": "string",
+                            "enum": [
+                                "jpeg",
+                                "png"
+                            ]
+                        },
+                        {
+                            "name": "quality",
+                            "description": "Compression quality from range [0..100] (jpeg only).",
+                            "optional": true,
+                            "type": "integer"
+                        }
+                    ]
+                }
+            ],
+            "commands": [
+                {
+                    "name": "beginFrame",
+                    "description": "Sends a BeginFrame to the target and returns when the frame was completed. Optionally captures a\nscreenshot from the resulting frame. Requires that the target was created with enabled\nBeginFrameControl. Designed for use with --run-all-compositor-stages-before-draw, see also\nhttps://goo.gl/3zHXhB for more background.",
+                    "parameters": [
+                        {
+                            "name": "frameTimeTicks",
+                            "description": "Timestamp of this BeginFrame in Renderer TimeTicks (milliseconds of uptime). If not set,\nthe current time will be used.",
+                            "optional": true,
+                            "type": "number"
+                        },
+                        {
+                            "name": "interval",
+                            "description": "The interval between BeginFrames that is reported to the compositor, in milliseconds.\nDefaults to a 60 frames/second interval, i.e. about 16.666 milliseconds.",
+                            "optional": true,
+                            "type": "number"
+                        },
+                        {
+                            "name": "noDisplayUpdates",
+                            "description": "Whether updates should not be committed and drawn onto the display. False by default. If\ntrue, only side effects of the BeginFrame will be run, such as layout and animations, but\nany visual updates may not be visible on the display or in screenshots.",
+                            "optional": true,
+                            "type": "boolean"
+                        },
+                        {
+                            "name": "screenshot",
+                            "description": "If set, a screenshot of the frame will be captured and returned in the response. Otherwise,\nno screenshot will be captured. Note that capturing a screenshot can fail, for example,\nduring renderer initialization. In such a case, no screenshot data will be returned.",
+                            "optional": true,
+                            "$ref": "ScreenshotParams"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "hasDamage",
+                            "description": "Whether the BeginFrame resulted in damage and, thus, a new frame was committed to the\ndisplay. Reported for diagnostic uses, may be removed in the future.",
+                            "type": "boolean"
+                        },
+                        {
+                            "name": "screenshotData",
+                            "description": "Base64-encoded image data of the screenshot, if one was requested and successfully taken.",
+                            "optional": true,
+                            "type": "binary"
+                        }
+                    ]
+                },
+                {
+                    "name": "disable",
+                    "description": "Disables headless events for the target."
+                },
+                {
+                    "name": "enable",
+                    "description": "Enables headless events for the target."
+                }
+            ],
+            "events": [
+                {
+                    "name": "needsBeginFramesChanged",
+                    "description": "Issued when the target starts or stops needing BeginFrames.",
+                    "parameters": [
+                        {
+                            "name": "needsBeginFrames",
+                            "description": "True if BeginFrames are needed, false otherwise.",
+                            "type": "boolean"
+                        }
+                    ]
+                }
+            ]
+        },
+        {
+            "domain": "IO",
+            "description": "Input/Output operations for streams produced by DevTools.",
+            "types": [
+                {
+                    "id": "StreamHandle",
+                    "description": "This is either obtained from another method or specifed as `blob:&lt;uuid&gt;` where\n`&lt;uuid&gt` is an UUID of a Blob.",
+                    "type": "string"
+                }
+            ],
+            "commands": [
+                {
+                    "name": "close",
+                    "description": "Close the stream, discard any temporary backing storage.",
+                    "parameters": [
+                        {
+                            "name": "handle",
+                            "description": "Handle of the stream to close.",
+                            "$ref": "StreamHandle"
+                        }
+                    ]
+                },
+                {
+                    "name": "read",
+                    "description": "Read a chunk of the stream",
+                    "parameters": [
+                        {
+                            "name": "handle",
+                            "description": "Handle of the stream to read.",
+                            "$ref": "StreamHandle"
+                        },
+                        {
+                            "name": "offset",
+                            "description": "Seek to the specified offset before reading (if not specificed, proceed with offset\nfollowing the last read). Some types of streams may only support sequential reads.",
+                            "optional": true,
+                            "type": "integer"
+                        },
+                        {
+                            "name": "size",
+                            "description": "Maximum number of bytes to read (left upon the agent discretion if not specified).",
+                            "optional": true,
+                            "type": "integer"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "base64Encoded",
+                            "description": "Set if the data is base64-encoded",
+                            "optional": true,
+                            "type": "boolean"
+                        },
+                        {
+                            "name": "data",
+                            "description": "Data that were read.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "eof",
+                            "description": "Set if the end-of-file condition occured while reading.",
+                            "type": "boolean"
+                        }
+                    ]
+                },
+                {
+                    "name": "resolveBlob",
+                    "description": "Return UUID of Blob object specified by a remote object id.",
+                    "parameters": [
+                        {
+                            "name": "objectId",
+                            "description": "Object id of a Blob object wrapper.",
+                            "$ref": "Runtime.RemoteObjectId"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "uuid",
+                            "description": "UUID of the specified Blob.",
+                            "type": "string"
+                        }
+                    ]
+                }
+            ]
+        },
+        {
+            "domain": "IndexedDB",
+            "experimental": true,
+            "dependencies": [
+                "Runtime"
+            ],
+            "types": [
+                {
+                    "id": "DatabaseWithObjectStores",
+                    "description": "Database with an array of object stores.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "name",
+                            "description": "Database name.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "version",
+                            "description": "Database version.",
+                            "type": "integer"
+                        },
+                        {
+                            "name": "objectStores",
+                            "description": "Object stores in this database.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "ObjectStore"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "id": "ObjectStore",
+                    "description": "Object store.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "name",
+                            "description": "Object store name.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "keyPath",
+                            "description": "Object store key path.",
+                            "$ref": "KeyPath"
+                        },
+                        {
+                            "name": "autoIncrement",
+                            "description": "If true, object store has auto increment flag set.",
+                            "type": "boolean"
+                        },
+                        {
+                            "name": "indexes",
+                            "description": "Indexes in this object store.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "ObjectStoreIndex"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "id": "ObjectStoreIndex",
+                    "description": "Object store index.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "name",
+                            "description": "Index name.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "keyPath",
+                            "description": "Index key path.",
+                            "$ref": "KeyPath"
+                        },
+                        {
+                            "name": "unique",
+                            "description": "If true, index is unique.",
+                            "type": "boolean"
+                        },
+                        {
+                            "name": "multiEntry",
+                            "description": "If true, index allows multiple entries for a key.",
+                            "type": "boolean"
+                        }
+                    ]
+                },
+                {
+                    "id": "Key",
+                    "description": "Key.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "type",
+                            "description": "Key type.",
+                            "type": "string",
+                            "enum": [
+                                "number",
+                                "string",
+                                "date",
+                                "array"
+                            ]
+                        },
+                        {
+                            "name": "number",
+                            "description": "Number value.",
+                            "optional": true,
+                            "type": "number"
+                        },
+                        {
+                            "name": "string",
+                            "description": "String value.",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "date",
+                            "description": "Date value.",
+                            "optional": true,
+                            "type": "number"
+                        },
+                        {
+                            "name": "array",
+                            "description": "Array value.",
+                            "optional": true,
+                            "type": "array",
+                            "items": {
+                                "$ref": "Key"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "id": "KeyRange",
+                    "description": "Key range.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "lower",
+                            "description": "Lower bound.",
+                            "optional": true,
+                            "$ref": "Key"
+                        },
+                        {
+                            "name": "upper",
+                            "description": "Upper bound.",
+                            "optional": true,
+                            "$ref": "Key"
+                        },
+                        {
+                            "name": "lowerOpen",
+                            "description": "If true lower bound is open.",
+                            "type": "boolean"
+                        },
+                        {
+                            "name": "upperOpen",
+                            "description": "If true upper bound is open.",
+                            "type": "boolean"
+                        }
+                    ]
+                },
+                {
+                    "id": "DataEntry",
+                    "description": "Data entry.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "key",
+                            "description": "Key object.",
+                            "$ref": "Runtime.RemoteObject"
+                        },
+                        {
+                            "name": "primaryKey",
+                            "description": "Primary key object.",
+                            "$ref": "Runtime.RemoteObject"
+                        },
+                        {
+                            "name": "value",
+                            "description": "Value object.",
+                            "$ref": "Runtime.RemoteObject"
+                        }
+                    ]
+                },
+                {
+                    "id": "KeyPath",
+                    "description": "Key path.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "type",
+                            "description": "Key path type.",
+                            "type": "string",
+                            "enum": [
+                                "null",
+                                "string",
+                                "array"
+                            ]
+                        },
+                        {
+                            "name": "string",
+                            "description": "String value.",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "array",
+                            "description": "Array value.",
+                            "optional": true,
+                            "type": "array",
+                            "items": {
+                                "type": "string"
+                            }
+                        }
+                    ]
+                }
+            ],
+            "commands": [
+                {
+                    "name": "clearObjectStore",
+                    "description": "Clears all entries from an object store.",
+                    "parameters": [
+                        {
+                            "name": "securityOrigin",
+                            "description": "Security origin.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "databaseName",
+                            "description": "Database name.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "objectStoreName",
+                            "description": "Object store name.",
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "name": "deleteDatabase",
+                    "description": "Deletes a database.",
+                    "parameters": [
+                        {
+                            "name": "securityOrigin",
+                            "description": "Security origin.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "databaseName",
+                            "description": "Database name.",
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "name": "deleteObjectStoreEntries",
+                    "description": "Delete a range of entries from an object store",
+                    "parameters": [
+                        {
+                            "name": "securityOrigin",
+                            "type": "string"
+                        },
+                        {
+                            "name": "databaseName",
+                            "type": "string"
+                        },
+                        {
+                            "name": "objectStoreName",
+                            "type": "string"
+                        },
+                        {
+                            "name": "keyRange",
+                            "description": "Range of entry keys to delete",
+                            "$ref": "KeyRange"
+                        }
+                    ]
+                },
+                {
+                    "name": "disable",
+                    "description": "Disables events from backend."
+                },
+                {
+                    "name": "enable",
+                    "description": "Enables events from backend."
+                },
+                {
+                    "name": "requestData",
+                    "description": "Requests data from object store or index.",
+                    "parameters": [
+                        {
+                            "name": "securityOrigin",
+                            "description": "Security origin.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "databaseName",
+                            "description": "Database name.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "objectStoreName",
+                            "description": "Object store name.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "indexName",
+                            "description": "Index name, empty string for object store data requests.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "skipCount",
+                            "description": "Number of records to skip.",
+                            "type": "integer"
+                        },
+                        {
+                            "name": "pageSize",
+                            "description": "Number of records to fetch.",
+                            "type": "integer"
+                        },
+                        {
+                            "name": "keyRange",
+                            "description": "Key range.",
+                            "optional": true,
+                            "$ref": "KeyRange"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "objectStoreDataEntries",
+                            "description": "Array of object store data entries.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "DataEntry"
+                            }
+                        },
+                        {
+                            "name": "hasMore",
+                            "description": "If true, there are more entries to fetch in the given range.",
+                            "type": "boolean"
+                        }
+                    ]
+                },
+                {
+                    "name": "requestDatabase",
+                    "description": "Requests database with given name in given frame.",
+                    "parameters": [
+                        {
+                            "name": "securityOrigin",
+                            "description": "Security origin.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "databaseName",
+                            "description": "Database name.",
+                            "type": "string"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "databaseWithObjectStores",
+                            "description": "Database with an array of object stores.",
+                            "$ref": "DatabaseWithObjectStores"
+                        }
+                    ]
+                },
+                {
+                    "name": "requestDatabaseNames",
+                    "description": "Requests database names for given security origin.",
+                    "parameters": [
+                        {
+                            "name": "securityOrigin",
+                            "description": "Security origin.",
+                            "type": "string"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "databaseNames",
+                            "description": "Database names for origin.",
+                            "type": "array",
+                            "items": {
+                                "type": "string"
+                            }
+                        }
+                    ]
+                }
+            ]
+        },
+        {
+            "domain": "Input",
+            "types": [
+                {
+                    "id": "TouchPoint",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "x",
+                            "description": "X coordinate of the event relative to the main frame's viewport in CSS pixels.",
+                            "type": "number"
+                        },
+                        {
+                            "name": "y",
+                            "description": "Y coordinate of the event relative to the main frame's viewport in CSS pixels. 0 refers to\nthe top of the viewport and Y increases as it proceeds towards the bottom of the viewport.",
+                            "type": "number"
+                        },
+                        {
+                            "name": "radiusX",
+                            "description": "X radius of the touch area (default: 1.0).",
+                            "optional": true,
+                            "type": "number"
+                        },
+                        {
+                            "name": "radiusY",
+                            "description": "Y radius of the touch area (default: 1.0).",
+                            "optional": true,
+                            "type": "number"
+                        },
+                        {
+                            "name": "rotationAngle",
+                            "description": "Rotation angle (default: 0.0).",
+                            "optional": true,
+                            "type": "number"
+                        },
+                        {
+                            "name": "force",
+                            "description": "Force (default: 1.0).",
+                            "optional": true,
+                            "type": "number"
+                        },
+                        {
+                            "name": "id",
+                            "description": "Identifier used to track touch sources between events, must be unique within an event.",
+                            "optional": true,
+                            "type": "number"
+                        }
+                    ]
+                },
+                {
+                    "id": "GestureSourceType",
+                    "experimental": true,
+                    "type": "string",
+                    "enum": [
+                        "default",
+                        "touch",
+                        "mouse"
+                    ]
+                },
+                {
+                    "id": "TimeSinceEpoch",
+                    "description": "UTC time in seconds, counted from January 1, 1970.",
+                    "type": "number"
+                }
+            ],
+            "commands": [
+                {
+                    "name": "dispatchKeyEvent",
+                    "description": "Dispatches a key event to the page.",
+                    "parameters": [
+                        {
+                            "name": "type",
+                            "description": "Type of the key event.",
+                            "type": "string",
+                            "enum": [
+                                "keyDown",
+                                "keyUp",
+                                "rawKeyDown",
+                                "char"
+                            ]
+                        },
+                        {
+                            "name": "modifiers",
+                            "description": "Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8\n(default: 0).",
+                            "optional": true,
+                            "type": "integer"
+                        },
+                        {
+                            "name": "timestamp",
+                            "description": "Time at which the event occurred.",
+                            "optional": true,
+                            "$ref": "TimeSinceEpoch"
+                        },
+                        {
+                            "name": "text",
+                            "description": "Text as generated by processing a virtual key code with a keyboard layout. Not needed for\nfor `keyUp` and `rawKeyDown` events (default: \"\")",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "unmodifiedText",
+                            "description": "Text that would have been generated by the keyboard if no modifiers were pressed (except for\nshift). Useful for shortcut (accelerator) key handling (default: \"\").",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "keyIdentifier",
+                            "description": "Unique key identifier (e.g., 'U+0041') (default: \"\").",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "code",
+                            "description": "Unique DOM defined string value for each physical key (e.g., 'KeyA') (default: \"\").",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "key",
+                            "description": "Unique DOM defined string value describing the meaning of the key in the context of active\nmodifiers, keyboard layout, etc (e.g., 'AltGr') (default: \"\").",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "windowsVirtualKeyCode",
+                            "description": "Windows virtual key code (default: 0).",
+                            "optional": true,
+                            "type": "integer"
+                        },
+                        {
+                            "name": "nativeVirtualKeyCode",
+                            "description": "Native virtual key code (default: 0).",
+                            "optional": true,
+                            "type": "integer"
+                        },
+                        {
+                            "name": "autoRepeat",
+                            "description": "Whether the event was generated from auto repeat (default: false).",
+                            "optional": true,
+                            "type": "boolean"
+                        },
+                        {
+                            "name": "isKeypad",
+                            "description": "Whether the event was generated from the keypad (default: false).",
+                            "optional": true,
+                            "type": "boolean"
+                        },
+                        {
+                            "name": "isSystemKey",
+                            "description": "Whether the event was a system key event (default: false).",
+                            "optional": true,
+                            "type": "boolean"
+                        },
+                        {
+                            "name": "location",
+                            "description": "Whether the event was from the left or right side of the keyboard. 1=Left, 2=Right (default:\n0).",
+                            "optional": true,
+                            "type": "integer"
+                        }
+                    ]
+                },
+                {
+                    "name": "insertText",
+                    "description": "This method emulates inserting text that doesn't come from a key press,\nfor example an emoji keyboard or an IME.",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "text",
+                            "description": "The text to insert.",
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "name": "dispatchMouseEvent",
+                    "description": "Dispatches a mouse event to the page.",
+                    "parameters": [
+                        {
+                            "name": "type",
+                            "description": "Type of the mouse event.",
+                            "type": "string",
+                            "enum": [
+                                "mousePressed",
+                                "mouseReleased",
+                                "mouseMoved",
+                                "mouseWheel"
+                            ]
+                        },
+                        {
+                            "name": "x",
+                            "description": "X coordinate of the event relative to the main frame's viewport in CSS pixels.",
+                            "type": "number"
+                        },
+                        {
+                            "name": "y",
+                            "description": "Y coordinate of the event relative to the main frame's viewport in CSS pixels. 0 refers to\nthe top of the viewport and Y increases as it proceeds towards the bottom of the viewport.",
+                            "type": "number"
+                        },
+                        {
+                            "name": "modifiers",
+                            "description": "Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8\n(default: 0).",
+                            "optional": true,
+                            "type": "integer"
+                        },
+                        {
+                            "name": "timestamp",
+                            "description": "Time at which the event occurred.",
+                            "optional": true,
+                            "$ref": "TimeSinceEpoch"
+                        },
+                        {
+                            "name": "button",
+                            "description": "Mouse button (default: \"none\").",
+                            "optional": true,
+                            "type": "string",
+                            "enum": [
+                                "none",
+                                "left",
+                                "middle",
+                                "right"
+                            ]
+                        },
+                        {
+                            "name": "clickCount",
+                            "description": "Number of times the mouse button was clicked (default: 0).",
+                            "optional": true,
+                            "type": "integer"
+                        },
+                        {
+                            "name": "deltaX",
+                            "description": "X delta in CSS pixels for mouse wheel event (default: 0).",
+                            "optional": true,
+                            "type": "number"
+                        },
+                        {
+                            "name": "deltaY",
+                            "description": "Y delta in CSS pixels for mouse wheel event (default: 0).",
+                            "optional": true,
+                            "type": "number"
+                        }
+                    ]
+                },
+                {
+                    "name": "dispatchTouchEvent",
+                    "description": "Dispatches a touch event to the page.",
+                    "parameters": [
+                        {
+                            "name": "type",
+                            "description": "Type of the touch event. TouchEnd and TouchCancel must not contain any touch points, while\nTouchStart and TouchMove must contains at least one.",
+                            "type": "string",
+                            "enum": [
+                                "touchStart",
+                                "touchEnd",
+                                "touchMove",
+                                "touchCancel"
+                            ]
+                        },
+                        {
+                            "name": "touchPoints",
+                            "description": "Active touch points on the touch device. One event per any changed point (compared to\nprevious touch event in a sequence) is generated, emulating pressing/moving/releasing points\none by one.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "TouchPoint"
+                            }
+                        },
+                        {
+                            "name": "modifiers",
+                            "description": "Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8\n(default: 0).",
+                            "optional": true,
+                            "type": "integer"
+                        },
+                        {
+                            "name": "timestamp",
+                            "description": "Time at which the event occurred.",
+                            "optional": true,
+                            "$ref": "TimeSinceEpoch"
+                        }
+                    ]
+                },
+                {
+                    "name": "emulateTouchFromMouseEvent",
+                    "description": "Emulates touch event from the mouse event parameters.",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "type",
+                            "description": "Type of the mouse event.",
+                            "type": "string",
+                            "enum": [
+                                "mousePressed",
+                                "mouseReleased",
+                                "mouseMoved",
+                                "mouseWheel"
+                            ]
+                        },
+                        {
+                            "name": "x",
+                            "description": "X coordinate of the mouse pointer in DIP.",
+                            "type": "integer"
+                        },
+                        {
+                            "name": "y",
+                            "description": "Y coordinate of the mouse pointer in DIP.",
+                            "type": "integer"
+                        },
+                        {
+                            "name": "button",
+                            "description": "Mouse button.",
+                            "type": "string",
+                            "enum": [
+                                "none",
+                                "left",
+                                "middle",
+                                "right"
+                            ]
+                        },
+                        {
+                            "name": "timestamp",
+                            "description": "Time at which the event occurred (default: current time).",
+                            "optional": true,
+                            "$ref": "TimeSinceEpoch"
+                        },
+                        {
+                            "name": "deltaX",
+                            "description": "X delta in DIP for mouse wheel event (default: 0).",
+                            "optional": true,
+                            "type": "number"
+                        },
+                        {
+                            "name": "deltaY",
+                            "description": "Y delta in DIP for mouse wheel event (default: 0).",
+                            "optional": true,
+                            "type": "number"
+                        },
+                        {
+                            "name": "modifiers",
+                            "description": "Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8\n(default: 0).",
+                            "optional": true,
+                            "type": "integer"
+                        },
+                        {
+                            "name": "clickCount",
+                            "description": "Number of times the mouse button was clicked (default: 0).",
+                            "optional": true,
+                            "type": "integer"
+                        }
+                    ]
+                },
+                {
+                    "name": "setIgnoreInputEvents",
+                    "description": "Ignores input events (useful while auditing page).",
+                    "parameters": [
+                        {
+                            "name": "ignore",
+                            "description": "Ignores input events processing when set to true.",
+                            "type": "boolean"
+                        }
+                    ]
+                },
+                {
+                    "name": "synthesizePinchGesture",
+                    "description": "Synthesizes a pinch gesture over a time period by issuing appropriate touch events.",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "x",
+                            "description": "X coordinate of the start of the gesture in CSS pixels.",
+                            "type": "number"
+                        },
+                        {
+                            "name": "y",
+                            "description": "Y coordinate of the start of the gesture in CSS pixels.",
+                            "type": "number"
+                        },
+                        {
+                            "name": "scaleFactor",
+                            "description": "Relative scale factor after zooming (>1.0 zooms in, <1.0 zooms out).",
+                            "type": "number"
+                        },
+                        {
+                            "name": "relativeSpeed",
+                            "description": "Relative pointer speed in pixels per second (default: 800).",
+                            "optional": true,
+                            "type": "integer"
+                        },
+                        {
+                            "name": "gestureSourceType",
+                            "description": "Which type of input events to be generated (default: 'default', which queries the platform\nfor the preferred input type).",
+                            "optional": true,
+                            "$ref": "GestureSourceType"
+                        }
+                    ]
+                },
+                {
+                    "name": "synthesizeScrollGesture",
+                    "description": "Synthesizes a scroll gesture over a time period by issuing appropriate touch events.",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "x",
+                            "description": "X coordinate of the start of the gesture in CSS pixels.",
+                            "type": "number"
+                        },
+                        {
+                            "name": "y",
+                            "description": "Y coordinate of the start of the gesture in CSS pixels.",
+                            "type": "number"
+                        },
+                        {
+                            "name": "xDistance",
+                            "description": "The distance to scroll along the X axis (positive to scroll left).",
+                            "optional": true,
+                            "type": "number"
+                        },
+                        {
+                            "name": "yDistance",
+                            "description": "The distance to scroll along the Y axis (positive to scroll up).",
+                            "optional": true,
+                            "type": "number"
+                        },
+                        {
+                            "name": "xOverscroll",
+                            "description": "The number of additional pixels to scroll back along the X axis, in addition to the given\ndistance.",
+                            "optional": true,
+                            "type": "number"
+                        },
+                        {
+                            "name": "yOverscroll",
+                            "description": "The number of additional pixels to scroll back along the Y axis, in addition to the given\ndistance.",
+                            "optional": true,
+                            "type": "number"
+                        },
+                        {
+                            "name": "preventFling",
+                            "description": "Prevent fling (default: true).",
+                            "optional": true,
+                            "type": "boolean"
+                        },
+                        {
+                            "name": "speed",
+                            "description": "Swipe speed in pixels per second (default: 800).",
+                            "optional": true,
+                            "type": "integer"
+                        },
+                        {
+                            "name": "gestureSourceType",
+                            "description": "Which type of input events to be generated (default: 'default', which queries the platform\nfor the preferred input type).",
+                            "optional": true,
+                            "$ref": "GestureSourceType"
+                        },
+                        {
+                            "name": "repeatCount",
+                            "description": "The number of times to repeat the gesture (default: 0).",
+                            "optional": true,
+                            "type": "integer"
+                        },
+                        {
+                            "name": "repeatDelayMs",
+                            "description": "The number of milliseconds delay between each repeat. (default: 250).",
+                            "optional": true,
+                            "type": "integer"
+                        },
+                        {
+                            "name": "interactionMarkerName",
+                            "description": "The name of the interaction markers to generate, if not empty (default: \"\").",
+                            "optional": true,
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "name": "synthesizeTapGesture",
+                    "description": "Synthesizes a tap gesture over a time period by issuing appropriate touch events.",
+                    "experimental": true,
+                    "parameters": [
+                        {
+                            "name": "x",
+                            "description": "X coordinate of the start of the gesture in CSS pixels.",
+                            "type": "number"
+                        },
+                        {
+                            "name": "y",
+                            "description": "Y coordinate of the start of the gesture in CSS pixels.",
+                            "type": "number"
+                        },
+                        {
+                            "name": "duration",
+                            "description": "Duration between touchdown and touchup events in ms (default: 50).",
+                            "optional": true,
+                            "type": "integer"
+                        },
+                        {
+                            "name": "tapCount",
+                            "description": "Number of times to perform the tap (e.g. 2 for double tap, default: 1).",
+                            "optional": true,
+                            "type": "integer"
+                        },
+                        {
+                            "name": "gestureSourceType",
+                            "description": "Which type of input events to be generated (default: 'default', which queries the platform\nfor the preferred input type).",
+                            "optional": true,
+                            "$ref": "GestureSourceType"
+                        }
+                    ]
+                }
+            ]
+        },
+        {
+            "domain": "Inspector",
+            "experimental": true,
+            "commands": [
+                {
+                    "name": "disable",
+                    "description": "Disables inspector domain notifications."
+                },
+                {
+                    "name": "enable",
+                    "description": "Enables inspector domain notifications."
+                }
+            ],
+            "events": [
+                {
+                    "name": "detached",
+                    "description": "Fired when remote debugging connection is about to be terminated. Contains detach reason.",
+                    "parameters": [
+                        {
+                            "name": "reason",
+                            "description": "The reason why connection has been terminated.",
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "name": "targetCrashed",
+                    "description": "Fired when debugging target has crashed"
+                },
+                {
+                    "name": "targetReloadedAfterCrash",
+                    "description": "Fired when debugging target has reloaded after crash"
+                }
+            ]
+        },
+        {
+            "domain": "LayerTree",
+            "experimental": true,
+            "dependencies": [
+                "DOM"
+            ],
+            "types": [
+                {
+                    "id": "LayerId",
+                    "description": "Unique Layer identifier.",
+                    "type": "string"
+                },
+                {
+                    "id": "SnapshotId",
+                    "description": "Unique snapshot identifier.",
+                    "type": "string"
+                },
+                {
+                    "id": "ScrollRect",
+                    "description": "Rectangle where scrolling happens on the main thread.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "rect",
+                            "description": "Rectangle itself.",
+                            "$ref": "DOM.Rect"
+                        },
+                        {
+                            "name": "type",
+                            "description": "Reason for rectangle to force scrolling on the main thread",
+                            "type": "string",
+                            "enum": [
+                                "RepaintsOnScroll",
+                                "TouchEventHandler",
+                                "WheelEventHandler"
+                            ]
+                        }
+                    ]
+                },
+                {
+                    "id": "StickyPositionConstraint",
+                    "description": "Sticky position constraints.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "stickyBoxRect",
+                            "description": "Layout rectangle of the sticky element before being shifted",
+                            "$ref": "DOM.Rect"
+                        },
+                        {
+                            "name": "containingBlockRect",
+                            "description": "Layout rectangle of the containing block of the sticky element",
+                            "$ref": "DOM.Rect"
+                        },
+                        {
+                            "name": "nearestLayerShiftingStickyBox",
+                            "description": "The nearest sticky layer that shifts the sticky box",
+                            "optional": true,
+                            "$ref": "LayerId"
+                        },
+                        {
+                            "name": "nearestLayerShiftingContainingBlock",
+                            "description": "The nearest sticky layer that shifts the containing block",
+                            "optional": true,
+                            "$ref": "LayerId"
+                        }
+                    ]
+                },
+                {
+                    "id": "PictureTile",
+                    "description": "Serialized fragment of layer picture along with its offset within the layer.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "x",
+                            "description": "Offset from owning layer left boundary",
+                            "type": "number"
+                        },
+                        {
+                            "name": "y",
+                            "description": "Offset from owning layer top boundary",
+                            "type": "number"
+                        },
+                        {
+                            "name": "picture",
+                            "description": "Base64-encoded snapshot data.",
+                            "type": "binary"
+                        }
+                    ]
+                },
+                {
+                    "id": "Layer",
+                    "description": "Information about a compositing layer.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "layerId",
+                            "description": "The unique id for this layer.",
+                            "$ref": "LayerId"
+                        },
+                        {
+                            "name": "parentLayerId",
+                            "description": "The id of parent (not present for root).",
+                            "optional": true,
+                            "$ref": "LayerId"
+                        },
+                        {
+                            "name": "backendNodeId",
+                            "description": "The backend id for the node associated with this layer.",
+                            "optional": true,
+                            "$ref": "DOM.BackendNodeId"
+                        },
+                        {
+                            "name": "offsetX",
+                            "description": "Offset from parent layer, X coordinate.",
+                            "type": "number"
+                        },
+                        {
+                            "name": "offsetY",
+                            "description": "Offset from parent layer, Y coordinate.",
+                            "type": "number"
+                        },
+                        {
+                            "name": "width",
+                            "description": "Layer width.",
+                            "type": "number"
+                        },
+                        {
+                            "name": "height",
+                            "description": "Layer height.",
+                            "type": "number"
+                        },
+                        {
+                            "name": "transform",
+                            "description": "Transformation matrix for layer, default is identity matrix",
+                            "optional": true,
+                            "type": "array",
+                            "items": {
+                                "type": "number"
+                            }
+                        },
+                        {
+                            "name": "anchorX",
+                            "description": "Transform anchor point X, absent if no transform specified",
+                            "optional": true,
+                            "type": "number"
+                        },
+                        {
+                            "name": "anchorY",
+                            "description": "Transform anchor point Y, absent if no transform specified",
+                            "optional": true,
+                            "type": "number"
+                        },
+                        {
+                            "name": "anchorZ",
+                            "description": "Transform anchor point Z, absent if no transform specified",
+                            "optional": true,
+                            "type": "number"
+                        },
+                        {
+                            "name": "paintCount",
+                            "description": "Indicates how many time this layer has painted.",
+                            "type": "integer"
+                        },
+                        {
+                            "name": "drawsContent",
+                            "description": "Indicates whether this layer hosts any content, rather than being used for\ntransform/scrolling purposes only.",
+                            "type": "boolean"
+                        },
+                        {
+                            "name": "invisible",
+                            "description": "Set if layer is not visible.",
+                            "optional": true,
+                            "type": "boolean"
+                        },
+                        {
+                            "name": "scrollRects",
+                            "description": "Rectangles scrolling on main thread only.",
+                            "optional": true,
+                            "type": "array",
+                            "items": {
+                                "$ref": "ScrollRect"
+                            }
+                        },
+                        {
+                            "name": "stickyPositionConstraint",
+                            "description": "Sticky position constraint information",
+                            "optional": true,
+                            "$ref": "StickyPositionConstraint"
+                        }
+                    ]
+                },
+                {
+                    "id": "PaintProfile",
+                    "description": "Array of timings, one per paint step.",
+                    "type": "array",
+                    "items": {
+                        "type": "number"
+                    }
+                }
+            ],
+            "commands": [
+                {
+                    "name": "compositingReasons",
+                    "description": "Provides the reasons why the given layer was composited.",
+                    "parameters": [
+                        {
+                            "name": "layerId",
+                            "description": "The id of the layer for which we want to get the reasons it was composited.",
+                            "$ref": "LayerId"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "compositingReasons",
+                            "description": "A list of strings specifying reasons for the given layer to become composited.",
+                            "type": "array",
+                            "items": {
+                                "type": "string"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "name": "disable",
+                    "description": "Disables compositing tree inspection."
+                },
+                {
+                    "name": "enable",
+                    "description": "Enables compositing tree inspection."
+                },
+                {
+                    "name": "loadSnapshot",
+                    "description": "Returns the snapshot identifier.",
+                    "parameters": [
+                        {
+                            "name": "tiles",
+                            "description": "An array of tiles composing the snapshot.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "PictureTile"
+                            }
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "snapshotId",
+                            "description": "The id of the snapshot.",
+                            "$ref": "SnapshotId"
+                        }
+                    ]
+                },
+                {
+                    "name": "makeSnapshot",
+                    "description": "Returns the layer snapshot identifier.",
+                    "parameters": [
+                        {
+                            "name": "layerId",
+                            "description": "The id of the layer.",
+                            "$ref": "LayerId"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "snapshotId",
+                            "description": "The id of the layer snapshot.",
+                            "$ref": "SnapshotId"
+                        }
+                    ]
+                },
+                {
+                    "name": "profileSnapshot",
+                    "parameters": [
+                        {
+                            "name": "snapshotId",
+                            "description": "The id of the layer snapshot.",
+                            "$ref": "SnapshotId"
+                        },
+                        {
+                            "name": "minRepeatCount",
+                            "description": "The maximum number of times to replay the snapshot (1, if not specified).",
+                            "optional": true,
+                            "type": "integer"
+                        },
+                        {
+                            "name": "minDuration",
+                            "description": "The minimum duration (in seconds) to replay the snapshot.",
+                            "optional": true,
+                            "type": "number"
+                        },
+                        {
+                            "name": "clipRect",
+                            "description": "The clip rectangle to apply when replaying the snapshot.",
+                            "optional": true,
+                            "$ref": "DOM.Rect"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "timings",
+                            "description": "The array of paint profiles, one per run.",
+                            "type": "array",
+                            "items": {
+                                "$ref": "PaintProfile"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "name": "releaseSnapshot",
+                    "description": "Releases layer snapshot captured by the back-end.",
+                    "parameters": [
+                        {
+                            "name": "snapshotId",
+                            "description": "The id of the layer snapshot.",
+                            "$ref": "SnapshotId"
+                        }
+                    ]
+                },
+                {
+                    "name": "replaySnapshot",
+                    "description": "Replays the layer snapshot and returns the resulting bitmap.",
+                    "parameters": [
+                        {
+                            "name": "snapshotId",
+                            "description": "The id of the layer snapshot.",
+                            "$ref": "SnapshotId"
+                        },
+                        {
+                            "name": "fromStep",
+                            "description": "The first step to replay from (replay from the very start if not specified).",
+                            "optional": true,
+                            "type": "integer"
+                        },
+                        {
+                            "name": "toStep",
+                            "description": "The last step to replay to (replay till the end if not specified).",
+                            "optional": true,
+                            "type": "integer"
+                        },
+                        {
+                            "name": "scale",
+                            "description": "The scale to apply while replaying (defaults to 1).",
+                            "optional": true,
+                            "type": "number"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "dataURL",
+                            "description": "A data: URL for resulting image.",
+                            "type": "string"
+                        }
+                    ]
+                },
+                {
+                    "name": "snapshotCommandLog",
+                    "description": "Replays the layer snapshot and returns canvas log.",
+                    "parameters": [
+                        {
+                            "name": "snapshotId",
+                            "description": "The id of the layer snapshot.",
+                            "$ref": "SnapshotId"
+                        }
+                    ],
+                    "returns": [
+                        {
+                            "name": "commandLog",
+                            "description": "The array of canvas function calls.",
+                            "type": "array",
+                            "items": {
+                                "type": "object"
+                            }
+                        }
+                    ]
+                }
+            ],
+            "events": [
+                {
+                    "name": "layerPainted",
+                    "parameters": [
+                        {
+                            "name": "layerId",
+                            "description": "The id of the painted layer.",
+                            "$ref": "LayerId"
+                        },
+                        {
+                            "name": "clip",
+                            "description": "Clip rectangle.",
+                            "$ref": "DOM.Rect"
+                        }
+                    ]
+                },
+                {
+                    "name": "layerTreeDidChange",
+                    "parameters": [
+                        {
+                            "name": "layers",
+                            "description": "Layer tree, absent if not in the comspositing mode.",
+                            "optional": true,
+                            "type": "array",
+                            "items": {
+                                "$ref": "Layer"
+                            }
+                        }
+                    ]
+                }
+            ]
+        },
+        {
+            "domain": "Log",
+            "description": "Provides access to log entries.",
+            "dependencies": [
+                "Runtime",
+                "Network"
+            ],
+            "types": [
+                {
+                    "id": "LogEntry",
+                    "description": "Log entry.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "source",
+                            "description": "Log entry source.",
+                            "type": "string",
+                            "enum": [
+                                "xml",
+                                "javascript",
+                                "network",
+                                "storage",
+                                "appcache",
+                                "rendering",
+                                "security",
+                                "deprecation",
+                                "worker",
+                                "violation",
+                                "intervention",
+                                "recommendation",
+                                "other"
+                            ]
+                        },
+                        {
+                            "name": "level",
+                            "description": "Log entry severity.",
+                            "type": "string",
+                            "enum": [
+                                "verbose",
+                                "info",
+                                "warning",
+                                "error"
+                            ]
+                        },
+                        {
+                            "name": "text",
+                            "description": "Logged text.",
+                            "type": "string"
+                        },
+                        {
+                            "name": "timestamp",
+                            "description": "Timestamp when this entry was added.",
+                            "$ref": "Runtime.Timestamp"
+                        },
+                        {
+                            "name": "url",
+                            "description": "URL of the resource if known.",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "lineNumber",
+                            "description": "Line number in the resource.",
+                            "optional": true,
+                            "type": "integer"
+                        },
+                        {
+                            "name": "stackTrace",
+                            "description": "JavaScript stack trace.",
+                            "optional": true,
+                            "$ref": "Runtime.StackTrace"
+                        },
+                        {
+                            "name": "networkRequestId",
+                            "description": "Identifier of the network request associated with this entry.",
+                            "optional": true,
+                            "$ref": "Network.RequestId"
+                        },
+                        {
+                            "name": "workerId",
+                            "description": "Identifier of the worker associated with this entry.",
+                            "optional": true,
+                            "type": "string"
+                        },
+                        {
+                            "name": "args",
+                            "description": "Call arguments.",
+                            "optional": true,
+                            "type": "array",
+                            "items": {
+                                "$ref": "Runtime.RemoteObject"
+                            }
+                        }
+                    ]
+                },
+                {
+                    "id": "ViolationSetting",
+                    "description": "Violation configuration setting.",
+                    "type": "object",
+                    "properties": [
+                        {
+                            "name": "name",
+                            "description": "Violation type.",
+                            "type": "string",
+                            "enum": [
+                                "longTask",
+                                "longLayout",
+                                "blockedEvent",
+                                "blockedParser",
+                                "discouragedAPIUse",
+                                "handler",
+                                "recurringHandler"
+                            ]
+                        },
+                        {
+                            "name": "threshold",
+                            "description": "Time threshold to trigger upon.",
+                            "type": "number"
+                        }
+                    ]
+                }
+            ],
+            "commands": [