diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,97 @@
+[![build](https://github.com/arsalan0c/cdp-hs/actions/workflows/build.yaml/badge.svg)](https://github.com/arsalan0c/cdp-hs/actions/workflows/build.yaml)
+# cdp-hs
+
+A Haskell library for the [Chrome Devtools Protocol (CDP)](https://chromedevtools.github.io/devtools-protocol/), generated from the protocol's definition files.
+
+## Example usage
+
+Ensure Chrome is running with the remote debugging port enabled:
+
+```
+$ chromium --headless --remote-debugging-port=9222 https://wikipedia.com
+```
+
+The following program can be used to print a page to PDF, with Base64 encoded data being read in chunks:
+
+```hs
+{-# LANGUAGE OverloadedStrings   #-}
+
+module Main where
+
+import Data.Maybe
+import Data.Default
+import qualified Data.ByteString.Base64.Lazy as Base64
+import qualified Data.ByteString.Lazy as BL
+import qualified Data.Text as T
+import qualified Data.Text.Lazy as TL
+import qualified Data.Text.Lazy.Encoding as TL
+
+import qualified CDP as CDP
+
+main :: IO ()
+main = do
+    let cfg = def
+    CDP.runClient cfg printPDF
+
+printPDF :: CDP.Handle -> IO ()
+printPDF handle = do
+    -- send the Page.printToPDF command
+    r <- CDP.sendCommandWait handle $ CDP.pPagePrintToPDF
+        { CDP.pPagePrintToPDFTransferMode = Just CDP.PPagePrintToPDFTransferModeReturnAsStream
+        }
+
+    -- obtain stream handle from which to read pdf data
+    let streamHandle = fromJust . CDP.pagePrintToPDFStream $ r
+
+    -- read pdf data 24000 bytes at a time
+    let params = CDP.PIORead streamHandle Nothing $ Just 24000
+    reads <- whileTrue (not . CDP.iOReadEof) $ CDP.sendCommandWait handle params
+    let dat = map decode reads
+    BL.writeFile "mypdf.pdf" $ BL.concat dat
+
+decode :: CDP.IORead -> BL.ByteString
+decode ior = if (CDP.iOReadBase64Encoded ior == Just True)
+    then Base64.decodeLenient lbs
+    else lbs
+  where
+    lbs = TL.encodeUtf8 . TL.fromStrict . CDP.iOReadData $ ior
+
+whileTrue :: Monad m => (a -> Bool) -> m a -> m [a]
+whileTrue f act = do
+    a <- act
+    if f a
+        then pure . (a :) =<< whileTrue f act
+        else pure [a]
+```
+
+## Generating the CDP library
+
+```
+cabal run cdp-gen
+```
+
+## Current state
+
+[Project board](https://github.com/users/arsalan0c/projects/1)
+
+Commands and events for all non-deprecated domains are supported.
+The following session functionalities are supported:
+- creating a session: obtain a session id by using the `pTargetAttachToTarget` function to send a `Target.attachToTarget` command, passing `True` for the flatten argument
+- send a command for a particular session: use the `sendCommandForSession` function with a session id
+- subscribe to events for a particular session: 
+  1. register a handler with a session id 
+  2. send the command to enable events for the domain, with the same session id
+
+## Contributing
+
+PRs are welcome! If you would like to discuss changes or have any feedback, feel free to open an [issue](https://github.com/arsalan0c/cdp-hs/issues).
+
+
+## Acknowledgements
+
+This began as a [Summer of Haskell](https://summer.haskell.org) / [GSoC](https://summerofcode.withgoogle.com) project. Albert Krewinkel ([@tarleb](https://github.com/tarleb)), Jasper Van der Jeugt ([@jaspervdj](https://github.com/jaspervdj)) and Romain Lesur ([@RLesur](https://github.com/rlesur)) provided valuable feedback and support which along with raising the library's quality, has made this all the more enjoyable to work on.
+
+## References
+
+- https://jaspervdj.be/posts/2013-09-01-controlling-chromium-in-haskell.html
+- https://www.jsonrpc.org/specification
diff --git a/cdp.cabal b/cdp.cabal
new file mode 100644
--- /dev/null
+++ b/cdp.cabal
@@ -0,0 +1,318 @@
+cabal-version: 2.2
+
+-- This file has been generated from package.yaml by hpack version 0.34.6.
+--
+-- see: https://github.com/sol/hpack
+
+name:           cdp
+version:        0.0.1.0
+synopsis:       A library for the Chrome Devtools Protocol (CDP)
+description:     Chrome Devtools Protocol: https://chromedevtools.github.io/devtools-protocol/
+                README: <https://github.com/arsalan0c/cdp-hs>
+                Examples: <https://github.com/arsalan0c/cdp-hs/examples> 
+category:       Package.Category
+homepage:       https://github.com/arsalan0c/cdp-hs#readme
+bug-reports:    https://github.com/arsalan0c/cdp-hs/issues
+author:         Arsalan Cheema
+maintainer:     Arsalan Cheema
+license:        BSD-3-Clause
+build-type:     Simple
+extra-doc-files:
+    README.md
+
+source-repository head
+  type: git
+  location: https://github.com/arsalan0c/cdp-hs
+
+library
+  exposed-modules:
+      CDP
+      CDP.Domains
+      CDP.Domains.Accessibility
+      CDP.Domains.Animation
+      CDP.Domains.Audits
+      CDP.Domains.BackgroundService
+      CDP.Domains.BrowserTarget
+      CDP.Domains.CacheStorage
+      CDP.Domains.Cast
+      CDP.Domains.CSS
+      CDP.Domains.Database
+      CDP.Domains.Debugger
+      CDP.Domains.DeviceOrientation
+      CDP.Domains.DOMDebugger
+      CDP.Domains.DOMPageNetworkEmulationSecurity
+      CDP.Domains.DOMSnapshot
+      CDP.Domains.DOMStorage
+      CDP.Domains.EventBreakpoints
+      CDP.Domains.Fetch
+      CDP.Domains.HeadlessExperimental
+      CDP.Domains.HeapProfiler
+      CDP.Domains.IndexedDB
+      CDP.Domains.Input
+      CDP.Domains.Inspector
+      CDP.Domains.IO
+      CDP.Domains.LayerTree
+      CDP.Domains.Log
+      CDP.Domains.Media
+      CDP.Domains.Memory
+      CDP.Domains.Overlay
+      CDP.Domains.Performance
+      CDP.Domains.PerformanceTimeline
+      CDP.Domains.Profiler
+      CDP.Domains.Runtime
+      CDP.Domains.ServiceWorker
+      CDP.Domains.Storage
+      CDP.Domains.SystemInfo
+      CDP.Domains.Tethering
+      CDP.Domains.Tracing
+      CDP.Domains.WebAudio
+      CDP.Domains.WebAuthn
+      CDP.Endpoints
+      CDP.Internal.Utils
+      CDP.Runtime
+      CDP.Definition
+      CDP.Gen.Deprecated
+      CDP.Gen.Program
+      CDP.Gen.Snippets
+      Main
+  other-modules:
+      Paths_cdp
+  autogen-modules:
+      Paths_cdp
+  hs-source-dirs:
+      src
+      gen
+  build-depends:
+      aeson ==1.5.6.0
+    , base ==4.14.3.0
+    , bytestring ==0.10.12.0
+    , containers ==0.6.5.1
+    , data-default ==0.7.1.1
+    , directory ==1.3.6.0
+    , extra ==1.7.9
+    , filepath ==1.4.2.1
+    , http-conduit ==2.3.8
+    , monad-loops ==0.4.3
+    , mtl ==2.2.2
+    , network-uri ==2.6.4.1
+    , process ==1.6.13.2
+    , random ==1.2.0
+    , text ==1.2.4.1
+    , vector ==0.12.3.1
+    , websockets ==0.12.7.3
+  default-language: Haskell2010
+
+executable cdp-example-endpoints
+  main-is: endpoints.hs
+  other-modules:
+      Paths_cdp
+  autogen-modules:
+      Paths_cdp
+  hs-source-dirs:
+      examples
+  build-depends:
+      aeson ==1.5.6.0
+    , base ==4.14.3.0
+    , blaze-html
+    , blaze-markup
+    , bytestring ==0.10.12.0
+    , cdp
+    , containers ==0.6.5.1
+    , data-default ==0.7.1.1
+    , directory ==1.3.6.0
+    , extra ==1.7.9
+    , filepath ==1.4.2.1
+    , http-conduit ==2.3.8
+    , monad-loops ==0.4.3
+    , mtl ==2.2.2
+    , network-uri ==2.6.4.1
+    , process ==1.6.13.2
+    , random ==1.2.0
+    , text ==1.2.4.1
+    , utf8-string
+    , vector ==0.12.3.1
+    , websockets ==0.12.7.3
+  default-language: Haskell2010
+
+executable cdp-example-open-twitter
+  main-is: open-twitter.hs
+  other-modules:
+      Paths_cdp
+  autogen-modules:
+      Paths_cdp
+  hs-source-dirs:
+      examples
+  build-depends:
+      aeson ==1.5.6.0
+    , base ==4.14.3.0
+    , bytestring ==0.10.12.0
+    , cdp
+    , containers ==0.6.5.1
+    , data-default ==0.7.1.1
+    , directory ==1.3.6.0
+    , extra ==1.7.9
+    , filepath ==1.4.2.1
+    , http-conduit ==2.3.8
+    , monad-loops ==0.4.3
+    , mtl ==2.2.2
+    , network-uri ==2.6.4.1
+    , process ==1.6.13.2
+    , random ==1.2.0
+    , text ==1.2.4.1
+    , vector ==0.12.3.1
+    , websockets ==0.12.7.3
+  default-language: Haskell2010
+
+executable cdp-example-print-page
+  main-is: print-page.hs
+  other-modules:
+      Paths_cdp
+  autogen-modules:
+      Paths_cdp
+  hs-source-dirs:
+      examples
+  build-depends:
+      aeson ==1.5.6.0
+    , base ==4.14.3.0
+    , base64-bytestring
+    , bytestring ==0.10.12.0
+    , cdp
+    , containers ==0.6.5.1
+    , data-default ==0.7.1.1
+    , directory ==1.3.6.0
+    , extra ==1.7.9
+    , filepath ==1.4.2.1
+    , http-conduit ==2.3.8
+    , monad-loops ==0.4.3
+    , mtl ==2.2.2
+    , network-uri ==2.6.4.1
+    , process ==1.6.13.2
+    , random ==1.2.0
+    , text ==1.2.4.1
+    , vector ==0.12.3.1
+    , websockets ==0.12.7.3
+  default-language: Haskell2010
+
+executable cdp-example-sessions
+  main-is: sessions.hs
+  other-modules:
+      Paths_cdp
+  autogen-modules:
+      Paths_cdp
+  hs-source-dirs:
+      examples
+  build-depends:
+      aeson ==1.5.6.0
+    , base ==4.14.3.0
+    , bytestring ==0.10.12.0
+    , cdp
+    , containers ==0.6.5.1
+    , data-default ==0.7.1.1
+    , directory ==1.3.6.0
+    , extra ==1.7.9
+    , filepath ==1.4.2.1
+    , http-conduit ==2.3.8
+    , monad-loops ==0.4.3
+    , mtl ==2.2.2
+    , network-uri ==2.6.4.1
+    , process ==1.6.13.2
+    , random ==1.2.0
+    , text ==1.2.4.1
+    , vector ==0.12.3.1
+    , websockets ==0.12.7.3
+  default-language: Haskell2010
+
+executable cdp-example-subscribe
+  main-is: subscribe.hs
+  other-modules:
+      Paths_cdp
+  autogen-modules:
+      Paths_cdp
+  hs-source-dirs:
+      examples
+  build-depends:
+      aeson ==1.5.6.0
+    , base ==4.14.3.0
+    , bytestring ==0.10.12.0
+    , cdp
+    , containers ==0.6.5.1
+    , data-default ==0.7.1.1
+    , directory ==1.3.6.0
+    , extra ==1.7.9
+    , filepath ==1.4.2.1
+    , http-conduit ==2.3.8
+    , monad-loops ==0.4.3
+    , mtl ==2.2.2
+    , network-uri ==2.6.4.1
+    , process ==1.6.13.2
+    , random ==1.2.0
+    , text ==1.2.4.1
+    , vector ==0.12.3.1
+    , websockets ==0.12.7.3
+  default-language: Haskell2010
+
+executable cdp-gen
+  main-is: Main.hs
+  other-modules:
+      CDP.Definition
+      CDP.Gen.Deprecated
+      CDP.Gen.Program
+      CDP.Gen.Snippets
+      Paths_cdp
+  autogen-modules:
+      Paths_cdp
+  hs-source-dirs:
+      gen
+  default-extensions:
+      Strict
+  build-depends:
+      aeson ==1.5.6.0
+    , base ==4.14.3.0
+    , bytestring ==0.10.12.0
+    , containers ==0.6.5.1
+    , data-default ==0.7.1.1
+    , directory ==1.3.6.0
+    , extra ==1.7.9
+    , filepath ==1.4.2.1
+    , http-conduit ==2.3.8
+    , monad-loops ==0.4.3
+    , mtl ==2.2.2
+    , network-uri ==2.6.4.1
+    , process ==1.6.13.2
+    , random ==1.2.0
+    , text ==1.2.4.1
+    , vector ==0.12.3.1
+    , websockets ==0.12.7.3
+  default-language: Haskell2010
+
+test-suite cdp-test
+  type: exitcode-stdio-1.0
+  main-is: Main.hs
+  other-modules:
+      Paths_cdp
+  autogen-modules:
+      Paths_cdp
+  hs-source-dirs:
+      test
+  ghc-options: -Wall -threaded
+  build-depends:
+      aeson ==1.5.6.0
+    , base ==4.14.3.0
+    , bytestring ==0.10.12.0
+    , cdp
+    , containers ==0.6.5.1
+    , data-default ==0.7.1.1
+    , directory ==1.3.6.0
+    , extra ==1.7.9
+    , filepath ==1.4.2.1
+    , hspec
+    , http-conduit ==2.3.8
+    , monad-loops ==0.4.3
+    , mtl ==2.2.2
+    , network-uri ==2.6.4.1
+    , process ==1.6.13.2
+    , random ==1.2.0
+    , text ==1.2.4.1
+    , vector ==0.12.3.1
+    , websockets ==0.12.7.3
+  default-language: Haskell2010
diff --git a/examples/endpoints.hs b/examples/endpoints.hs
new file mode 100644
--- /dev/null
+++ b/examples/endpoints.hs
@@ -0,0 +1,15 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module Main (main) where
+
+import Data.Default
+import qualified Data.ByteString.Lazy.UTF8 as BS
+import qualified Text.Blaze.Html5 as H
+import qualified Text.Blaze.Html.Renderer.Pretty as R
+
+import qualified CDP as CDP
+
+main :: IO ()
+main = do
+    CDP.endpoint def CDP.EPFrontend >>= 
+            print . R.renderHtml . H.toHtml . BS.toString
diff --git a/examples/open-twitter.hs b/examples/open-twitter.hs
new file mode 100644
--- /dev/null
+++ b/examples/open-twitter.hs
@@ -0,0 +1,13 @@
+{-# LANGUAGE OverloadedStrings   #-}
+
+module Main where
+
+import CDP
+import Data.Default (def)
+import Control.Concurrent (threadDelay)
+import Control.Monad (forever)
+
+main :: IO ()
+main = CDP.runClient def $ \handle -> forever $ do
+    sendCommand handle $ pTargetCreateTarget "https://twitter.com/GabriellaG439"
+    threadDelay $ 10 * 1000 * 1000
diff --git a/examples/print-page.hs b/examples/print-page.hs
new file mode 100644
--- /dev/null
+++ b/examples/print-page.hs
@@ -0,0 +1,48 @@
+{-# LANGUAGE OverloadedStrings   #-}
+
+module Main where
+
+import Data.Maybe
+import Data.Default
+import qualified Data.ByteString.Base64.Lazy as Base64
+import qualified Data.ByteString.Lazy as BL
+import qualified Data.Text as T
+import qualified Data.Text.Lazy as TL
+import qualified Data.Text.Lazy.Encoding as TL
+
+import qualified CDP as CDP
+
+main :: IO ()
+main = do
+    let cfg = def
+    CDP.runClient cfg printPDF
+
+printPDF :: CDP.Handle -> IO ()
+printPDF handle = do
+    -- send the Page.printToPDF command
+    r <- CDP.sendCommandWait handle $ CDP.pPagePrintToPDF
+        { CDP.pPagePrintToPDFTransferMode = Just CDP.PPagePrintToPDFTransferModeReturnAsStream
+        }
+
+    -- obtain stream handle from which to read pdf data
+    let streamHandle = fromJust . CDP.pagePrintToPDFStream $ r
+
+    -- read pdf data 24000 bytes at a time
+    let params = CDP.PIORead streamHandle Nothing $ Just 24000
+    reads <- whileTrue (not . CDP.iOReadEof) $ CDP.sendCommandWait handle params
+    let dat = map decode reads
+    BL.writeFile "mypdf.pdf" $ BL.concat dat
+
+decode :: CDP.IORead -> BL.ByteString
+decode ior = if (CDP.iOReadBase64Encoded ior == Just True)
+    then Base64.decodeLenient lbs
+    else lbs
+  where
+    lbs = TL.encodeUtf8 . TL.fromStrict . CDP.iOReadData $ ior
+
+whileTrue :: Monad m => (a -> Bool) -> m a -> m [a]
+whileTrue f act = do
+    a <- act
+    if f a
+        then pure . (a :) =<< whileTrue f act
+        else pure [a]
diff --git a/examples/sessions.hs b/examples/sessions.hs
new file mode 100644
--- /dev/null
+++ b/examples/sessions.hs
@@ -0,0 +1,43 @@
+{-# LANGUAGE OverloadedStrings   #-}
+
+module Main where
+
+import Data.Default
+import Control.Monad (forever)
+import Control.Concurrent (threadDelay)
+import qualified Data.Text as T
+
+import qualified CDP as CDP
+
+main :: IO ()
+main = do
+    CDP.runClient def $ \handle -> do
+        sessionId <- attachTarget handle
+        subPageLoad handle sessionId
+
+-- Attaches to target, returning the session id
+attachTarget :: CDP.Handle -> IO T.Text
+attachTarget handle = do
+    -- get a target id
+    targetInfo <- head . CDP.targetGetTargetsTargetInfos <$> 
+        (CDP.sendCommandWait handle $ CDP.PTargetGetTargets Nothing)
+    let targetId = CDP.targetTargetInfoTargetId targetInfo
+    -- get a session id by attaching to the target
+    CDP.targetAttachToTargetSessionId <$> do
+        CDP.sendCommandWait handle $
+            -- to enable sessions, flatten must be set to True
+            CDP.PTargetAttachToTarget targetId (Just True)
+
+-- | Subscribes to page load events for a given session
+subPageLoad :: CDP.Handle -> T.Text -> IO ()
+subPageLoad handle sessionId = do
+    -- register a handler for the page load event 
+    CDP.subscribeForSession handle sessionId (print . CDP.pageLoadEventFiredTimestamp)
+    -- start receiving events
+    CDP.sendCommandForSessionWait handle sessionId CDP.pPageEnable
+    -- navigate to a page, triggering the page load event
+    CDP.sendCommandForSessionWait handle sessionId $
+        CDP.pPageNavigate "http://haskell.foundation"
+    -- stop the program from terminating, to keep receiving events
+    forever $ do
+        threadDelay 1000
diff --git a/examples/subscribe.hs b/examples/subscribe.hs
new file mode 100644
--- /dev/null
+++ b/examples/subscribe.hs
@@ -0,0 +1,19 @@
+{-# LANGUAGE OverloadedStrings   #-}
+
+module Main (main) where
+
+import qualified CDP as CDP
+import Data.Default (def)
+import Control.Concurrent (threadDelay)
+import Control.Monad (forever)
+import Control.Monad.Fix (mfix)
+
+main :: IO ()
+main = CDP.runClient def $ \handle -> do
+    CDP.sendCommandWait handle CDP.pPageEnable
+    sub1 <- mfix $ \sub -> CDP.subscribe handle $ \e -> do
+        putStrLn . show $ "1: " <> CDP.pageFrameUrl (CDP.pageFrameNavigatedFrame e)
+        CDP.unsubscribe handle sub
+    _ <- CDP.subscribe handle $ \e ->
+        putStrLn . show $ "2: " <> CDP.pageFrameUrl (CDP.pageFrameNavigatedFrame e)
+    forever $ threadDelay 1000
diff --git a/gen/CDP/Definition.hs b/gen/CDP/Definition.hs
new file mode 100644
--- /dev/null
+++ b/gen/CDP/Definition.hs
@@ -0,0 +1,187 @@
+{-# LANGUAGE TemplateHaskell     #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE RecordWildCards     #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE TypeOperators       #-}
+{-# LANGUAGE DeriveGeneric       #-}
+
+module CDP.Definition where
+import           System.Exit        (exitFailure, exitSuccess)
+import           System.IO          (stderr, hPutStrLn)
+import qualified Data.ByteString.Lazy.Char8 as BSL
+import           System.Environment (getArgs)
+import           Control.Monad      (forM_, mzero, join)
+import           Control.Applicative
+import           Data.Aeson(eitherDecode, Value(..), FromJSON(..), ToJSON(..),pairs,(.:), (.:?), (.=), (.!=), object)
+import           Data.Monoid((<>))
+import           Data.Text (Text)
+import qualified GHC.Generics
+
+data Version = Version { 
+    versionMinor :: Text,
+    versionMajor :: Text
+  } deriving (Show,Eq,GHC.Generics.Generic)
+
+
+instance FromJSON Version where
+  parseJSON (Object v) = Version <$> v .:  "minor" <*> v .:  "major"
+  parseJSON _          = mzero
+
+
+data Items = Items { 
+    itemsType :: Maybe Text,
+    itemsRef :: Maybe Text
+  } deriving (Show,Eq,GHC.Generics.Generic)
+
+
+instance FromJSON Items where
+  parseJSON (Object v) = Items <$> v .:? "type" <*> v .:? "$ref"
+  parseJSON _          = mzero
+
+
+data Property = Property {
+    propertyItems :: Maybe Items,
+    propertyExperimental :: Bool,
+    propertyName :: Text,
+    propertyType :: Maybe Text,
+    propertyEnum :: Maybe [Text],
+    propertyOptional :: Bool,
+    propertyRef :: Maybe Text,
+    propertyDescription :: Maybe Text,
+    propertyDeprecated :: Bool
+  } deriving (Show,Eq,GHC.Generics.Generic)
+
+
+instance FromJSON Property where
+  parseJSON (Object v) = Property
+    <$> v .:? "items"
+    <*> v .:? "experimental" .!= False
+    <*> v .:  "name"
+    <*> v .:? "type"
+    <*> v .:? "enum"
+    <*> v .:? "optional" .!= False
+    <*> v .:? "$ref"
+    <*> v .:? "description"
+    <*> v .:? "deprecated" .!= False
+  parseJSON _          = mzero
+
+
+data Command = Command {
+    commandExperimental :: Bool,
+    commandName :: Text,
+    commandReturns :: [Property],
+    commandParameters :: [Property],
+    commandRedirect :: Maybe Text,
+    commandDescription :: Maybe Text,
+    commandDeprecated ::  Bool
+  } deriving (Show,Eq,GHC.Generics.Generic)
+
+
+instance FromJSON Command where
+  parseJSON (Object v) = Command
+    <$> v .:? "experimental" .!= False
+    <*> v .:  "name"
+    <*> v .:? "returns" .!= []
+    <*> v .:? "parameters" .!= []
+    <*> v .:? "redirect"
+    <*> v .:? "description"
+    <*> v .:? "deprecated" .!= False
+  parseJSON _          = mzero
+
+
+data Type = Type {
+    typeItems :: Maybe Items,
+    typeExperimental :: Bool,
+    typeId :: Text,
+    typeType :: Text,
+    typeEnum :: Maybe [Text],
+    typeProperties :: Maybe [Property],
+    typeDescription :: Maybe Text,
+    typeDeprecated :: Bool
+  } deriving (Show,Eq,GHC.Generics.Generic)
+
+
+instance FromJSON Type where
+  parseJSON (Object v) = Type
+    <$> v .:? "items"
+    <*> v .:? "experimental" .!= False
+    <*> v .:  "id"
+    <*> v .:  "type"
+    <*> v .:? "enum"
+    <*> v .:? "properties"
+    <*> v .:? "description"
+    <*> v .:? "deprecated" .!= False
+  parseJSON _          = mzero
+
+
+data Event = Event {
+    eventExperimental :: Bool,
+    eventName :: Text,
+    eventParameters :: [Property],
+    eventDescription :: Maybe Text,
+    eventDeprecated :: Bool
+  } deriving (Show,Eq,GHC.Generics.Generic)
+
+
+instance FromJSON Event where
+  parseJSON (Object v) = Event
+    <$> v .:? "experimental" .!= False
+    <*> v .:  "name"
+    <*> v .:? "parameters" .!= []
+    <*> v .:? "description"
+    <*> v .:? "deprecated" .!= False
+  parseJSON _          = mzero
+
+
+data Domain = Domain {
+    domainCommands :: [Command],
+    domainDomain :: Text,
+    domainDependencies :: [Text],
+    domainExperimental :: Bool,
+    domainTypes :: [Type],
+    domainEvents :: [Event],
+    domainDescription :: Maybe Text,
+    domainDeprecated :: Bool
+  } deriving (Show,Eq,GHC.Generics.Generic)
+
+
+instance FromJSON Domain where
+  parseJSON (Object v) = Domain
+    <$> v .:  "commands"
+    <*> v .:  "domain"
+    <*> v .:? "dependencies" .!= []
+    <*> v .:? "experimental" .!= False
+    <*> v .:? "types" .!= []
+    <*> v .:? "events" .!= []
+    <*> v .:? "description"
+    <*> v .:? "deprecated" .!= False
+  parseJSON _          = mzero
+
+
+data TopLevel = TopLevel { 
+    topLevelVersion :: Version,
+    topLevelDomains :: [Domain]
+  } deriving (Show,Eq,GHC.Generics.Generic)
+
+
+instance FromJSON TopLevel where
+  parseJSON (Object v) = TopLevel <$> v .:  "version" <*> v .:  "domains"
+  parseJSON _          = mzero
+
+
+
+
+-- | Use parser to get TopLevel object
+parse :: FilePath -> IO TopLevel
+parse filename = do
+    input <- BSL.readFile filename
+    case eitherDecode input of
+      Left errTop -> fatal $ case (eitherDecode input :: Either String Value) of
+                           Left  err -> "Invalid JSON file: " ++ filename ++ "\n   " ++ err
+                           Right _   -> "Mismatched JSON value from file: " ++ filename
+                                     ++ "\n" ++ errTop
+      Right r     -> return (r :: TopLevel)
+  where
+    fatal :: String -> IO a
+    fatal msg = do hPutStrLn stderr msg
+                   exitFailure
diff --git a/gen/CDP/Gen/Deprecated.hs b/gen/CDP/Gen/Deprecated.hs
new file mode 100644
--- /dev/null
+++ b/gen/CDP/Gen/Deprecated.hs
@@ -0,0 +1,32 @@
+-- | Module for filtering out deprecated things.
+{-# LANGUAGE RecordWildCards #-}
+module CDP.Gen.Deprecated
+    ( removeDeprecated
+    ) where
+
+import CDP.Definition
+
+removeDeprecated :: TopLevel -> TopLevel
+removeDeprecated topLevel@TopLevel {..} = topLevel
+    { topLevelDomains =
+        map goDomain . filter (not . domainDeprecated) $ topLevelDomains
+    }
+  where
+    goDomain domain@Domain {..} = domain
+        { domainCommands = map goCommand $ filter (not . commandDeprecated) domainCommands
+        , domainTypes    = map goType    $ filter (not . typeDeprecated)    domainTypes
+        , domainEvents   = map goEvent   $ filter (not . eventDeprecated)   domainEvents
+        }
+
+    goCommand command@Command {..} = command
+        { commandReturns    = filter (not . propertyDeprecated) commandReturns
+        , commandParameters = filter (not . propertyDeprecated) commandParameters
+        }
+
+    goType ty@Type {..} = ty
+        { typeProperties = filter (not . propertyDeprecated) <$> typeProperties
+        }
+
+    goEvent event@Event {..} = event
+        { eventParameters = filter (not . propertyDeprecated) eventParameters
+        }
diff --git a/gen/CDP/Gen/Program.hs b/gen/CDP/Gen/Program.hs
new file mode 100644
--- /dev/null
+++ b/gen/CDP/Gen/Program.hs
@@ -0,0 +1,540 @@
+{-# LANGUAGE OverloadedStrings, FlexibleContexts, TupleSections, TypeOperators #-}
+
+module CDP.Gen.Program
+    ( Program (..)
+    , genProgram
+    , genProtocolModule
+
+    , ComponentName (..)
+    ) where
+
+import Control.Arrow
+import Data.List
+import Data.Maybe
+import Data.Char
+import Control.Monad
+import qualified Data.Map as Map
+import qualified Data.Set as Set
+import qualified Data.Graph as Graph
+import qualified Data.Text as T
+
+import qualified CDP.Definition as D
+import qualified CDP.Gen.Snippets as Snippets
+
+----------- Start of program generation ----------- 
+
+data Program = Program
+    { pComponents       :: Map.Map ComponentName T.Text
+    , pComponentImports :: T.Text
+    }
+
+data Context = Context { ctxDomainComponents :: DomainComponents }
+
+genProgram :: [D.Domain] -> Program
+genProgram delts = Program
+    { pComponents        = allComponents ctx $ Map.elems dc
+    , pComponentImports  = T.unlines $ allComponentImports ctx
+    }
+  where
+    ctx    = Context dc
+    dc     = domainComponents delts
+
+----------- Generation of global types / values ----------- 
+
+genProtocolModule :: [ComponentName] -> T.Text -> T.Text
+genProtocolModule names source = T.unlines
+    [ "{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}"
+    , "{-# LANGUAGE ScopedTypeVariables #-}"
+    , "{-# LANGUAGE FlexibleContexts #-}"
+    , "{-# LANGUAGE MultiParamTypeClasses #-}"
+    , "{-# LANGUAGE FlexibleInstances #-}"
+    , "{-# LANGUAGE DeriveGeneric #-}"
+    , ""
+    , protocolModuleHeader names
+    , Snippets.domainImports
+    , source
+    ]
+
+allComponentImports :: Context -> [T.Text]
+allComponentImports = Set.toList . Set.fromList . 
+    concatMap ((\n -> [importDomain False n, importDomain True n]) . unComponentName . cName) . Map.elems . ctxDomainComponents
+
+allComponents :: Context -> [Component] -> Map.Map ComponentName T.Text
+allComponents ctx components = Map.fromList . 
+    map (cName &&& genComponent ctx) $ 
+    components
+
+----------- Generation of domain types / values -----------
+
+genComponent :: Context -> Component -> T.Text
+genComponent ctx component = T.intercalate "\n\n" $
+    [ Snippets.domainLanguageExtensions
+    , formatComponentDescription component
+    , domainModuleHeader cn
+    , Snippets.domainImports
+    , T.unlines $ map (importDomain True) deps
+    , T.unlines $ map (genDomain ctx) delts
+    ]
+  where
+    deps  = Set.toList . Set.fromList . map unComponentName . 
+        map (domainToComponentName ctx) . concatMap snd . Map.elems $ cDomDeps component
+    delts = map fst . Map.elems $ cDomDeps component
+    cn    = unComponentName . cName $ component
+
+genDomain :: Context -> D.Domain -> T.Text
+genDomain ctx domainElt = T.unlines . intercalate [""] $
+    map (genType ctx dn)            (D.domainTypes    domainElt) ++
+    map (genEventReturnType ctx dn) (D.domainEvents   domainElt) ++
+    map (genCommand ctx dn)         (D.domainCommands domainElt)
+  where
+    dn    = domainName domainElt
+
+genType :: Context -> T.Text -> D.Type -> [T.Text]
+genType ctx domainName telt =
+    desc ++
+    (case D.typeEnum telt of
+        Just enumValues -> genTypeEnum ctx tn enumValues
+        Nothing         -> case tytelt of
+            "object" -> case tpeltsM of
+                Nothing ->  [genTypeSynonynm ctx domainName tn]
+                Just tpelts ->
+                    genRecordType ctx domainName tn tpelts ++
+                    genRecordFromJson tn tpelts ++
+                    genRecordToJson tn tpelts
+            ty -> [T.unwords ["type", tn, "=", lty]])
+  where
+    desc     = formatDescription . Just $
+        "Type '" <> domainName <> "." <> D.typeId telt <> "'." <>
+        maybe "" (\x -> "\n" <> x) (D.typeDescription telt)
+    lty      = leftType ctx domainName (Just tytelt) Nothing (D.typeItems telt)
+    tytelt   = D.typeType telt
+    tpeltsM  = D.typeProperties telt
+    tn       = typeNameHS domainName telt 
+
+genTypeEnum :: Context -> T.Text -> [T.Text] -> [T.Text]
+genTypeEnum _ typeEnumName values =
+    [T.unwords ["data", typeEnumName, "=", T.intercalate " | " constructors]] ++
+    indent [derivingOrd] ++
+    genFromJSONInstanceEnum typeEnumName values constructors ++
+    genToJSONInstanceEnum typeEnumName values constructors
+  where
+    constructors = map (tyNameHS typeEnumName) values
+
+genEventReturnType :: Context -> T.Text -> D.Event -> [T.Text]
+genEventReturnType ctx domainName eventElt =
+    desc ++
+    (case evelts of
+        [] -> ["data " <> evrn <> " = " <> evrn] ++ indent [derivingBase]
+        _ -> genRecordType ctx domainName evrn evelts) ++
+    (genRecordFromJson evrn evelts) ++
+    ["instance Event " <> evrn <> " where"] ++
+    indent ["eventName _ = \"" <> eventName domainName eventElt <> "\""]
+  where
+    desc = formatDescription . Just $ "Type of the '" <>
+        (eventName domainName eventElt) <> "' event."
+    evelts = D.eventParameters eventElt
+    evrn = eventNameHS domainName eventElt
+
+genCommand :: Context -> T.Text -> D.Command -> [T.Text]
+genCommand ctx domainName commandElt =
+    formatDescription (D.commandDescription commandElt) ++
+    [""] ++
+    formatDescription (Just $ "Parameters of the '" <> cn <> "' command.") ++
+    genRecordType ctx domainName ptn pelts ++
+    genRecordSmartConstructor ctx domainName ptn pelts ++
+    genRecordToJson ptn pelts ++
+    (if null relts then [] else genRecordType ctx domainName rtn relts) ++
+    (if null relts then [] else genRecordFromJson rtn relts) ++
+    commandInstance
+  where
+    cn   = commandName domainName commandElt 
+    ptn  = commandParamsNameHS domainName commandElt
+    rtn  = commandNameHS domainName commandElt
+
+    pelts = D.commandParameters commandElt
+
+    relts = D.commandReturns commandElt
+
+    commandAssociatedType = if null relts then "()" else rtn
+    commandInstance =
+        ["instance Command " <> ptn <> " where"] ++
+        indent ["type CommandResponse " <> ptn <> " = " <> commandAssociatedType] ++
+        indent ["commandName _ = \"" <> cn <> "\""] ++
+        indent ["fromJSON = const . A.Success . const ()" | (null relts)]
+
+genRecordType :: Context -> T.Text -> T.Text -> [D.Property] -> [T.Text]
+genRecordType ctx domainName recName props =
+    (do
+        p <- props
+        e <- maybeToList $ D.propertyEnum p
+        genTypeEnum ctx (tyNameHS "" (fieldNameHS recName $ D.propertyName p)) e) ++
+    [ "data " <> recName <> " = " <> recName] ++
+    (indent $ case props of
+        [] -> []
+        _ ->
+            ["{"] ++
+            (indent $ do
+                (isLast, prop) <- markLast props
+                let (fn, fty) = propertyHsSig ctx domainName recName prop
+                    comma = if isLast then "" else ","
+                formatDescription (D.propertyDescription prop) ++
+                    [fn <> " :: " <> fty <> comma]) ++
+            ["}"]) ++
+    ["  deriving (Eq, Show)"]
+
+genRecordSmartConstructor :: Context -> T.Text -> T.Text -> [D.Property] -> [T.Text]
+genRecordSmartConstructor ctx domainName recName props =
+    [conName] ++
+    (indent $ do
+        (isFirstParam, (mbDesc, ty)) <- markFirst types
+        let d1 = formatDescription mbDesc
+            d2 
+                | length d1 == 0 = d1
+                | otherwise      = "{-" : d1 ++ ["-}"]
+        d2 ++
+            [(if isFirstParam then ":: " else "-> ") <> ty]) ++
+    [conName] ++
+    indent args ++
+    indent ["= " <> recName] ++
+    (indent . indent $ do
+        prop <- props
+        pure $ if D.propertyOptional prop
+            then "Nothing"
+            else argName prop)
+  where
+    conName = uncapitalizeFirst recName
+    requiredProps = filter (not . D.propertyOptional) props
+    types = (do
+        prop <- requiredProps
+        let (_, ty) = propertyHsSig ctx domainName recName prop
+        pure (D.propertyDescription prop, ty)) ++
+        [ (Nothing, recName) ]
+    args = do
+        prop <- requiredProps
+        guard . not $ D.propertyOptional prop
+        pure $ argName prop
+
+    argName = ("arg_" <>) . fieldNameHS recName . D.propertyName
+
+genRecordFromJson :: T.Text -> [D.Property] -> [T.Text]
+genRecordFromJson recName props =
+    ["instance FromJSON " <> recName <> " where"] ++
+    (indent $ case props of
+        [] -> ["parseJSON _ = pure " <> recName]
+        _  ->
+            ["parseJSON = A.withObject \"" <> recName <> "\" $ \\o -> " <> recName] ++
+            (indent $ do
+                (isFirst, prop) <- markFirst props
+                pure $
+                    (if isFirst then "<$>" else "<*>") <>
+                    " o " <> (if D.propertyOptional prop then "A..:?" else "A..:") <>
+                    " \"" <> D.propertyName prop <> "\""))
+
+genRecordToJson :: T.Text -> [D.Property] -> [T.Text]
+genRecordToJson recName params =
+    ["instance ToJSON " <> recName <> " where"] ++
+    (case params of
+        [] -> ["  toJSON _ = A.Null"]
+        _  ->
+            ["  toJSON p = A.object $ catMaybes ["] ++
+            [
+                "    " <> T.intercalate ",\n    "
+                [ "(\"" <> D.propertyName prop <> "\" A..=) <$> " <>
+                    (if D.propertyOptional prop then "" else "Just ") <>
+                    "(" <> fieldNameHS recName (D.propertyName prop) <> " p)"
+                | prop <- params
+                ]
+            ] ++
+            ["    ]"])
+
+propertyHsSig :: Context -> T.Text -> T.Text -> D.Property -> (T.Text, T.Text)
+propertyHsSig ctx domainName recName prop = case D.propertyEnum prop of
+    Just _  -> (fn, (if D.propertyOptional prop then "Maybe " else "") <> ftn)
+    Nothing -> (fn, ) $ genEltType ctx domainName (D.propertyOptional prop)
+        (D.propertyType prop)
+        (D.propertyRef prop) 
+        (D.propertyItems prop)
+  where
+    ftn = tyNameHS "" fn
+    fn = fieldNameHS recName . D.propertyName $ prop
+
+genTypeSynonynm :: Context -> T.Text -> T.Text -> T.Text
+genTypeSynonynm ctx domainName typeName = T.unwords ["type", typeName, "=", typeCDPToHS ctx domainName "object" Nothing]
+
+----------- Generation rules ----------- 
+----- Docs    -----
+formatComponentDescription :: Component -> T.Text
+formatComponentDescription component = T.unlines $
+    ["{- |"] ++
+    (do
+        (delt, _) <- Map.elems $ cDomDeps component
+        ["= " <> domainName delt] <> [""] ++
+            maybe [] T.lines (D.domainDescription delt)) ++
+    ["-}"]
+
+formatDescription :: Maybe T.Text -> [T.Text]
+formatDescription = maybe [] (indentWith "-- | " "--   " . T.lines)
+
+
+----- Imports -----
+importDomain :: Bool -> T.Text -> T.Text 
+importDomain as' domainName = T.unwords $ 
+    if as' then imp ++ ["as", domainName] else imp
+  where
+    imp = ["import", domainModuleName domainName]
+   
+componentToImport :: [ComponentName] -> [T.Text]
+componentToImport = map (("module " <>) . domainModuleName . unComponentName)
+
+protocolModuleHeader :: [ComponentName] -> T.Text
+protocolModuleHeader names = T.unlines
+    [ mod
+    , "( " <> T.intercalate "\n, " exports
+    , ") where"
+    ]
+  where
+    mod = T.unwords [ "module", protocolModuleName ]
+
+    exports = componentToImport names
+
+protocolModuleName :: T.Text
+protocolModuleName = "CDP.Domains"
+
+domainModuleHeader :: T.Text -> T.Text
+domainModuleHeader domainName = T.unwords ["module", domainModuleName domainName, "(module", domainModuleName domainName <>")", "where"]
+
+domainModuleName :: T.Text -> T.Text
+domainModuleName domainName = T.intercalate "." ["CDP", "Domains", domainName]
+
+domainQualifiedName :: T.Text -> T.Text -> T.Text
+domainQualifiedName domainName n =  T.intercalate "." [domainName, n]
+
+domainName :: D.Domain -> T.Text
+domainName = D.domainDomain
+
+----- JSON -----
+
+genFromJSONInstanceEnum :: T.Text -> [T.Text] -> [T.Text] -> [T.Text]
+genFromJSONInstanceEnum name vals hsVals =
+    ["instance FromJSON " <> name <> " where"] ++
+    (indent $
+        ["parseJSON = A.withText " <> (T.pack . show) name <> " $ \\v -> case v of"] ++
+        (indent $ do
+            (v, hsv) <- zip vals (map ("pure " <>) hsVals) ++ [emptyCase name]
+            pure $ T.pack (show v) <> " -> " <> hsv))
+
+genToJSONInstanceEnum :: T.Text -> [T.Text] -> [T.Text] -> [T.Text]
+genToJSONInstanceEnum name vals hsVals =
+    ["instance ToJSON " <> name <> " where"] ++
+    (indent $
+        ["toJSON v = A.String $ case v of"] ++
+        (indent $ do
+            (v, hsv) <- zip vals hsVals
+            pure $ hsv <> " -> " <> T.pack (show v)))
+
+----- Types -----
+genEltType :: Context -> T.Text -> Bool -> Maybe T.Text -> Maybe T.Text -> Maybe D.Items -> T.Text
+genEltType ctx name isOptional t1 t2 items = (if isOptional then "Maybe " else "") <> (leftType ctx name t1 t2 items)
+
+leftType :: Context -> T.Text -> Maybe T.Text -> Maybe T.Text -> Maybe D.Items -> T.Text
+leftType ctx _ (Just ty1) (Just ty2) _ = error "impossible"
+leftType ctx domain (Just ty) _ itemsElt = typeCDPToHS ctx domain ty itemsElt
+leftType ctx domain _ (Just ty) itemsElt = typeCDPToHS ctx domain ty itemsElt
+leftType ctx _ _ _ _ = error "no type found"
+
+typeCDPToHS :: Context -> T.Text -> T.Text -> Maybe D.Items -> T.Text
+typeCDPToHS ctx _ "object" _ = "[(T.Text, T.Text)]"
+typeCDPToHS ctx domain "array" (Just items) = "[" <> (leftType ctx domain (D.itemsType items) (D.itemsRef items) Nothing) <> "]"
+typeCDPToHS ctx _ ty (Just items) = error . T.unpack $ "non-array type with items: " <> ty
+typeCDPToHS ctx domain ty Nothing = convertType ctx domain ty
+
+convertType :: Context -> T.Text -> T.Text -> T.Text
+convertType _ _ "string"  = "T.Text"
+convertType _ _ "integer" = "Int"
+convertType _ _ "boolean" = "Bool"
+convertType _ _ "number"  = "Double"
+convertType _ _ "()" = "()"
+convertType _ _ "any" = "A.Value"
+convertType _ _ "array" = error "got array conversion"
+convertType _ _ "object" = error "got object type"
+convertType _ _ "" = error "got empty type"
+convertType ctx domain s = case T.splitOn "." s of
+    [otherDomain, ty] -> if cn otherDomain == cn domain
+            then tyNameHS otherDomain ty -- both domains are in the same component, so the type is not qualified
+            else domainQualifiedName (cn otherDomain) (tyNameHS otherDomain ty)
+    _ -> tyNameHS domain s 
+  where
+    cn dn = unComponentName . domainToComponentName ctx $ dn
+
+----- Dependencies -----    
+{- : Domain dependencies specified in the protocol seem inaccurate:
+    https://bugs.chromium.org/p/chromium/issues/detail?id=1354980#c0
+
+    So they are collected by inspecting each domain.
+-}
+
+domainToComponentName :: Context -> T.Text -> ComponentName
+domainToComponentName ctx domainName = cName . (flip (Map.!) domainName) . ctxDomainComponents $ ctx 
+
+newtype ComponentName = ComponentName { unComponentName :: T.Text }
+    deriving (Show, Eq, Ord)
+
+type DomainDependencies = Map.Map T.Text (D.Domain, [T.Text])
+data Component = Component {
+  cName     :: ComponentName
+, cDomDeps  :: DomainDependencies
+}
+
+type DomainComponents = Map.Map T.Text Component
+    -- original domain name, component the domain belongs to
+    -- domain name for each vertex is the modified domain name
+type Vertex = (D.Domain, T.Text, [T.Text]) -- domain, domain name, domain dependencies 
+
+domainComponents :: [D.Domain] -> DomainComponents
+domainComponents delts = Map.fromList . concatMap verticesToDomainComponents $ vsc2
+  where
+    vsc2  = map removeSameComponentDependencies vsc1   
+    vsc1  = map Graph.flattenSCC . Graph.stronglyConnCompR $ g
+    g     = map (\delt -> (delt, domainName delt, deps delt)) delts
+    deps  = Set.toList . domainDependencies
+
+verticesToDomainComponents :: [Vertex] -> [(T.Text, Component)]
+verticesToDomainComponents vs = map (,c) dns
+  where
+    dns = map vertexToDomainName vs 
+    c   = verticesToComponent vs
+
+vertexToDomainName :: Vertex -> T.Text
+vertexToDomainName (_,dn,_) = dn 
+
+verticesToComponent :: [Vertex] -> Component
+verticesToComponent vs = Component cn . Map.fromList . map toComponent $ vs
+  where
+    toComponent (delt,dn,deps) = (dn, (delt, deps))
+    cn = componentName vs
+
+componentName :: [Vertex] -> ComponentName
+componentName [v] = ComponentName $ vertexToDomainName v 
+componentName vs  = ComponentName $ mconcat . map vertexToDomainName $ vs
+
+removeSameComponentDependencies :: [Vertex] -> [Vertex]
+removeSameComponentDependencies vs = map (go vs) vs
+  where
+    go vs (delt, dn, deps) = (delt,dn,) . Set.toList $ 
+        (Set.fromList deps) `Set.difference` dns
+    dns = Set.fromList $ map vertexToDomainName vs
+
+domainDependencies :: D.Domain -> Set.Set T.Text
+domainDependencies delt = removeSelf . Set.fromList . concat $
+    [ concatMap typeDependencies    $ D.domainTypes delt
+    , concatMap commandDependencies $ D.domainCommands delt
+    , concatMap eventDependencies   $ D.domainEvents delt
+    ]
+  where
+    removeSelf = Set.filter (/= dn)
+    dn = domainName delt
+
+typeDependencies :: D.Type -> [T.Text]
+typeDependencies telt = case D.typeEnum telt of 
+    Just _  -> []
+    Nothing -> case D.typeType telt of
+        "array"  -> maybe [] pure . join $ itemDependencies <$> D.typeItems telt
+        "object" -> fromMaybe [] $ catMaybes . map propertyDependencies <$> D.typeProperties telt
+        s -> maybe [] pure $ refTypeToDomain s
+
+commandDependencies :: D.Command -> [T.Text]
+commandDependencies celt = concat
+    [ catMaybes . map propertyDependencies $ D.commandReturns celt
+    , catMaybes . map propertyDependencies $ D.commandParameters celt
+    ]
+
+eventDependencies :: D.Event -> [T.Text]
+eventDependencies evelt =
+    catMaybes . map propertyDependencies $ D.eventParameters evelt
+
+propertyDependencies :: D.Property -> Maybe T.Text
+propertyDependencies pelt = case D.propertyEnum pelt of
+        Just _  -> Nothing
+        Nothing -> case D.propertyRef pelt of
+            Just r  -> refTypeToDomain r
+            Nothing -> case D.propertyType pelt of
+                Just "object" -> Nothing
+                Just "array"  -> itemDependencies =<< D.propertyItems pelt
+                Just s -> refTypeToDomain s
+                _      -> Nothing
+
+itemDependencies :: D.Items -> Maybe T.Text
+itemDependencies itelt = refTypeToDomain =<< D.itemsRef itelt
+
+----- Names -----
+eventName   :: T.Text -> D.Event -> T.Text
+eventName   domainName ev = (domainName <>) . ("." <>) . D.eventName $ ev
+eventNameHS :: T.Text -> D.Event -> T.Text
+eventNameHS domainName ev = tyNameHS domainName (D.eventName ev)
+
+commandName   :: T.Text -> D.Command -> T.Text
+commandName domainName c = (domainName <>) . ("." <>) . D.commandName $ c
+commandNameHS :: T.Text -> D.Command -> T.Text
+commandNameHS domainName c = tyNameHS domainName (D.commandName c)
+commandParamsNameHS :: T.Text -> D.Command -> T.Text
+commandParamsNameHS domainName c = paramsTypePrefix $ commandNameHS domainName c
+
+typeNameHS :: T.Text -> D.Type -> T.Text
+typeNameHS domainName t = tyNameHS domainName (D.typeId t)
+
+tyNameHS :: T.Text -> T.Text -> T.Text
+tyNameHS prefix tyName =
+    capitalizeFirst prefix <> capitalizeFirst (hyphensToCapitalize tyName)
+
+fieldNameHS :: T.Text -> T.Text -> T.Text
+fieldNameHS tyName fieldName = uncapitalizeFirst tyName <> capitalizeFirst fieldName
+
+paramsTypePrefix :: T.Text -> T.Text
+paramsTypePrefix = ("P" <>)
+
+refTypeToDomain :: T.Text -> Maybe T.Text
+refTypeToDomain r = case T.splitOn "." r of
+    [domain, _] -> Just domain
+    _           -> Nothing
+
+-----
+emptyCase :: T.Text -> (T.Text, T.Text)
+emptyCase name = ("_", T.unwords ["fail", (T.pack . show) $ "failed to parse " <> name])
+
+derivingBase    :: T.Text
+derivingBase    = "deriving (Eq, Show, Read)"
+derivingOrd     :: T.Text
+derivingOrd     = "deriving (Ord, Eq, Show, Read)"
+
+-----------  Utilities ----------- 
+
+indent :: [T.Text] -> [T.Text]
+indent = indentWith "  " "  "
+
+indentWith :: T.Text -> T.Text -> [T.Text] -> [T.Text]
+indentWith _         _          []       = []
+indentWith firstLine otherLines (x : xs) =
+    (firstLine <> x) : map (otherLines <>) xs
+
+capitalizeFirst :: T.Text -> T.Text
+capitalizeFirst t = maybe t (\(first, rest) -> T.singleton (toUpper first) `T.append` rest) . T.uncons $ t
+
+uncapitalizeFirst :: T.Text -> T.Text
+uncapitalizeFirst t = maybe t (\(first, rest) -> T.singleton (toLower first) `T.append` rest) . T.uncons $ t
+
+markFirst :: [a] -> [(Bool, a)]
+markFirst = zip (True : repeat False)
+
+markLast :: [a] -> [(Bool, a)]
+markLast []          = []
+markLast (x : [])    = [(True, x)]
+markLast (x : y : z) = (False, x) : markLast (y : z)
+
+-- | Changes things like "a-rate" to "aRate"
+hyphensToCapitalize :: T.Text -> T.Text
+hyphensToCapitalize txt
+    | T.null after = before
+    | otherwise    =
+        before <> capitalizeFirst (hyphensToCapitalize (T.drop 1 after))
+  where
+    (before, after) = T.break (== '-') txt
diff --git a/gen/CDP/Gen/Snippets.hs b/gen/CDP/Gen/Snippets.hs
new file mode 100644
--- /dev/null
+++ b/gen/CDP/Gen/Snippets.hs
@@ -0,0 +1,47 @@
+{-# LANGUAGE OverloadedStrings #-}
+module CDP.Gen.Snippets where
+
+import qualified Data.Text as T
+
+domainLanguageExtensions :: T.Text
+domainLanguageExtensions = T.unlines
+    [ "{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}"
+    , "{-# LANGUAGE ScopedTypeVariables #-}"
+    , "{-# LANGUAGE FlexibleContexts #-}"
+    , "{-# LANGUAGE MultiParamTypeClasses #-}"
+    , "{-# LANGUAGE FlexibleInstances #-}"
+    , "{-# LANGUAGE DeriveGeneric #-}"
+    , "{-# LANGUAGE TypeFamilies #-}"
+    ]
+
+domainImports :: T.Text
+domainImports = T.unlines
+    [ "import           Control.Applicative  ((<$>))"
+    , "import           Control.Monad"
+    , "import           Control.Monad.Loops"
+    , "import           Control.Monad.Trans  (liftIO)"
+    , "import qualified Data.Map             as M"
+    , "import           Data.Maybe          "
+    , "import Data.Functor.Identity"
+    , "import Data.String"
+    , "import qualified Data.Text as T"
+    , "import qualified Data.List as List"
+    , "import qualified Data.Text.IO         as TI"
+    , "import qualified Data.Vector          as V"
+    , "import Data.Aeson.Types (Parser(..))"
+    , "import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))"
+    , "import qualified Data.Aeson           as A"
+    , "import qualified Network.HTTP.Simple as Http"
+    , "import qualified Network.URI          as Uri"
+    , "import qualified Network.WebSockets as WS"
+    , "import Control.Concurrent"
+    , "import qualified Data.ByteString.Lazy as BS"
+    , "import qualified Data.Map as Map"
+    , "import Data.Proxy"
+    , "import System.Random"
+    , "import GHC.Generics"
+    , "import Data.Char"
+    , "import Data.Default"
+    , ""
+    , "import CDP.Internal.Utils"
+    ]
diff --git a/gen/Main.hs b/gen/Main.hs
new file mode 100644
--- /dev/null
+++ b/gen/Main.hs
@@ -0,0 +1,41 @@
+{-# LANGUAGE OverloadedStrings   #-}
+
+module Main where
+
+import Data.Foldable (for_)
+import qualified Data.Text as T
+import qualified Data.Text.IO as T
+import qualified Data.Map as Map
+import qualified System.FilePath as FP
+import qualified System.Directory as Dir
+import qualified System.IO as IO
+
+import qualified CDP.Definition as D
+import qualified CDP.Gen.Program as GP
+import CDP.Gen.Deprecated (removeDeprecated)
+
+main :: IO ()
+main = do
+    domains <- fmap concat . mapM (fmap D.topLevelDomains . fmap removeDeprecated . D.parse) $
+        [ browserDefinitionPath
+        , jsDefinitionPath 
+        ] 
+
+    let program = GP.genProgram domains
+
+    for_ (Map.toList . GP.pComponents $ program) $ \(dn,d) -> do
+        let path = domainPath . T.unpack . GP.unComponentName $ dn
+        IO.hPutStrLn IO.stderr $ "Writing domain to " ++ path ++ "..."
+        T.writeFile path d
+
+    let protocol = GP.genProtocolModule (Map.keys . GP.pComponents $ program) $
+          GP.pComponentImports program
+
+    IO.hPutStrLn IO.stderr $ "Writing protocol to " ++ protocolModulePath ++ "..."
+    T.writeFile protocolModulePath protocol
+  where
+    domainPath dn         = domainDir FP.</> FP.addExtension dn "hs"
+    domainDir             = "src/CDP/Domains"
+    protocolModulePath    = "src/CDP/Domains.hs"
+    jsDefinitionPath       = "devtools-protocol/json/js_protocol.json"
+    browserDefinitionPath  = "devtools-protocol/json/browser_protocol.json"
diff --git a/src/CDP.hs b/src/CDP.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP.hs
@@ -0,0 +1,50 @@
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+module CDP
+    ( Error             (..)
+    , ProtocolError     (..)
+    , EPBrowserVersion  (..)
+    , EPAllTargets      (..)
+    , EPCurrentProtocol (..)
+    , EPOpenNewTab      (..)
+    , EPActivateTarget  (..)
+    , EPCloseTarget     (..)
+    , EPFrontend        (..)
+    , Endpoint
+    , EndpointResponse
+    , SomeEndpoint      (..)
+    , BrowserVersion    (..)
+    , TargetInfo        (..)
+    , TargetId
+    , parseUri
+    , fromSomeEndpoint
+    , endpoint
+    , connectToTab
+
+    , ClientApp
+    , Handle
+    , Config(..)
+    , runClient
+
+    , Subscription
+    , subscribe
+    , subscribeForSession
+    , unsubscribe
+
+    , Command (..)
+    , SomeCommand (..)
+    , Promise (..)
+    , fromSomeCommand
+    , readPromise
+    , sendCommand
+    , sendCommandForSession
+    , sendCommandWait
+    , sendCommandForSessionWait
+
+    , module CDP.Domains
+    ) where
+
+import Data.Proxy (Proxy)
+
+import CDP.Domains
+import CDP.Runtime
diff --git a/src/CDP/Domains.hs b/src/CDP/Domains.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains.hs
@@ -0,0 +1,157 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+
+module CDP.Domains
+( module CDP.Domains.Accessibility
+, module CDP.Domains.Animation
+, module CDP.Domains.Audits
+, module CDP.Domains.BackgroundService
+, module CDP.Domains.BrowserTarget
+, module CDP.Domains.CSS
+, module CDP.Domains.CacheStorage
+, module CDP.Domains.Cast
+, module CDP.Domains.DOMDebugger
+, module CDP.Domains.DOMPageNetworkEmulationSecurity
+, module CDP.Domains.DOMSnapshot
+, module CDP.Domains.DOMStorage
+, module CDP.Domains.Database
+, module CDP.Domains.Debugger
+, module CDP.Domains.DeviceOrientation
+, module CDP.Domains.EventBreakpoints
+, module CDP.Domains.Fetch
+, module CDP.Domains.HeadlessExperimental
+, module CDP.Domains.HeapProfiler
+, module CDP.Domains.IO
+, module CDP.Domains.IndexedDB
+, module CDP.Domains.Input
+, module CDP.Domains.Inspector
+, module CDP.Domains.LayerTree
+, module CDP.Domains.Log
+, module CDP.Domains.Media
+, module CDP.Domains.Memory
+, module CDP.Domains.Overlay
+, module CDP.Domains.Performance
+, module CDP.Domains.PerformanceTimeline
+, module CDP.Domains.Profiler
+, module CDP.Domains.Runtime
+, module CDP.Domains.ServiceWorker
+, module CDP.Domains.Storage
+, module CDP.Domains.SystemInfo
+, module CDP.Domains.Tethering
+, module CDP.Domains.Tracing
+, module CDP.Domains.WebAudio
+, module CDP.Domains.WebAuthn
+) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+import CDP.Domains.Accessibility
+import CDP.Domains.Accessibility as Accessibility
+import CDP.Domains.Animation
+import CDP.Domains.Animation as Animation
+import CDP.Domains.Audits
+import CDP.Domains.Audits as Audits
+import CDP.Domains.BackgroundService
+import CDP.Domains.BackgroundService as BackgroundService
+import CDP.Domains.BrowserTarget
+import CDP.Domains.BrowserTarget as BrowserTarget
+import CDP.Domains.CSS
+import CDP.Domains.CSS as CSS
+import CDP.Domains.CacheStorage
+import CDP.Domains.CacheStorage as CacheStorage
+import CDP.Domains.Cast
+import CDP.Domains.Cast as Cast
+import CDP.Domains.DOMDebugger
+import CDP.Domains.DOMDebugger as DOMDebugger
+import CDP.Domains.DOMPageNetworkEmulationSecurity
+import CDP.Domains.DOMPageNetworkEmulationSecurity as DOMPageNetworkEmulationSecurity
+import CDP.Domains.DOMSnapshot
+import CDP.Domains.DOMSnapshot as DOMSnapshot
+import CDP.Domains.DOMStorage
+import CDP.Domains.DOMStorage as DOMStorage
+import CDP.Domains.Database
+import CDP.Domains.Database as Database
+import CDP.Domains.Debugger
+import CDP.Domains.Debugger as Debugger
+import CDP.Domains.DeviceOrientation
+import CDP.Domains.DeviceOrientation as DeviceOrientation
+import CDP.Domains.EventBreakpoints
+import CDP.Domains.EventBreakpoints as EventBreakpoints
+import CDP.Domains.Fetch
+import CDP.Domains.Fetch as Fetch
+import CDP.Domains.HeadlessExperimental
+import CDP.Domains.HeadlessExperimental as HeadlessExperimental
+import CDP.Domains.HeapProfiler
+import CDP.Domains.HeapProfiler as HeapProfiler
+import CDP.Domains.IO
+import CDP.Domains.IO as IO
+import CDP.Domains.IndexedDB
+import CDP.Domains.IndexedDB as IndexedDB
+import CDP.Domains.Input
+import CDP.Domains.Input as Input
+import CDP.Domains.Inspector
+import CDP.Domains.Inspector as Inspector
+import CDP.Domains.LayerTree
+import CDP.Domains.LayerTree as LayerTree
+import CDP.Domains.Log
+import CDP.Domains.Log as Log
+import CDP.Domains.Media
+import CDP.Domains.Media as Media
+import CDP.Domains.Memory
+import CDP.Domains.Memory as Memory
+import CDP.Domains.Overlay
+import CDP.Domains.Overlay as Overlay
+import CDP.Domains.Performance
+import CDP.Domains.Performance as Performance
+import CDP.Domains.PerformanceTimeline
+import CDP.Domains.PerformanceTimeline as PerformanceTimeline
+import CDP.Domains.Profiler
+import CDP.Domains.Profiler as Profiler
+import CDP.Domains.Runtime
+import CDP.Domains.Runtime as Runtime
+import CDP.Domains.ServiceWorker
+import CDP.Domains.ServiceWorker as ServiceWorker
+import CDP.Domains.Storage
+import CDP.Domains.Storage as Storage
+import CDP.Domains.SystemInfo
+import CDP.Domains.SystemInfo as SystemInfo
+import CDP.Domains.Tethering
+import CDP.Domains.Tethering as Tethering
+import CDP.Domains.Tracing
+import CDP.Domains.Tracing as Tracing
+import CDP.Domains.WebAudio
+import CDP.Domains.WebAudio as WebAudio
+import CDP.Domains.WebAuthn
+import CDP.Domains.WebAuthn as WebAuthn
+
diff --git a/src/CDP/Domains/Accessibility.hs b/src/CDP/Domains/Accessibility.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains/Accessibility.hs
@@ -0,0 +1,725 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+
+
+{- |
+= Accessibility
+
+-}
+
+
+module CDP.Domains.Accessibility (module CDP.Domains.Accessibility) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+
+import CDP.Domains.DOMPageNetworkEmulationSecurity as DOMPageNetworkEmulationSecurity
+import CDP.Domains.Runtime as Runtime
+
+
+-- | Type 'Accessibility.AXNodeId'.
+--   Unique accessibility node identifier.
+type AccessibilityAXNodeId = T.Text
+
+-- | Type 'Accessibility.AXValueType'.
+--   Enum of possible property types.
+data AccessibilityAXValueType = AccessibilityAXValueTypeBoolean | AccessibilityAXValueTypeTristate | AccessibilityAXValueTypeBooleanOrUndefined | AccessibilityAXValueTypeIdref | AccessibilityAXValueTypeIdrefList | AccessibilityAXValueTypeInteger | AccessibilityAXValueTypeNode | AccessibilityAXValueTypeNodeList | AccessibilityAXValueTypeNumber | AccessibilityAXValueTypeString | AccessibilityAXValueTypeComputedString | AccessibilityAXValueTypeToken | AccessibilityAXValueTypeTokenList | AccessibilityAXValueTypeDomRelation | AccessibilityAXValueTypeRole | AccessibilityAXValueTypeInternalRole | AccessibilityAXValueTypeValueUndefined
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON AccessibilityAXValueType where
+  parseJSON = A.withText "AccessibilityAXValueType" $ \v -> case v of
+    "boolean" -> pure AccessibilityAXValueTypeBoolean
+    "tristate" -> pure AccessibilityAXValueTypeTristate
+    "booleanOrUndefined" -> pure AccessibilityAXValueTypeBooleanOrUndefined
+    "idref" -> pure AccessibilityAXValueTypeIdref
+    "idrefList" -> pure AccessibilityAXValueTypeIdrefList
+    "integer" -> pure AccessibilityAXValueTypeInteger
+    "node" -> pure AccessibilityAXValueTypeNode
+    "nodeList" -> pure AccessibilityAXValueTypeNodeList
+    "number" -> pure AccessibilityAXValueTypeNumber
+    "string" -> pure AccessibilityAXValueTypeString
+    "computedString" -> pure AccessibilityAXValueTypeComputedString
+    "token" -> pure AccessibilityAXValueTypeToken
+    "tokenList" -> pure AccessibilityAXValueTypeTokenList
+    "domRelation" -> pure AccessibilityAXValueTypeDomRelation
+    "role" -> pure AccessibilityAXValueTypeRole
+    "internalRole" -> pure AccessibilityAXValueTypeInternalRole
+    "valueUndefined" -> pure AccessibilityAXValueTypeValueUndefined
+    "_" -> fail "failed to parse AccessibilityAXValueType"
+instance ToJSON AccessibilityAXValueType where
+  toJSON v = A.String $ case v of
+    AccessibilityAXValueTypeBoolean -> "boolean"
+    AccessibilityAXValueTypeTristate -> "tristate"
+    AccessibilityAXValueTypeBooleanOrUndefined -> "booleanOrUndefined"
+    AccessibilityAXValueTypeIdref -> "idref"
+    AccessibilityAXValueTypeIdrefList -> "idrefList"
+    AccessibilityAXValueTypeInteger -> "integer"
+    AccessibilityAXValueTypeNode -> "node"
+    AccessibilityAXValueTypeNodeList -> "nodeList"
+    AccessibilityAXValueTypeNumber -> "number"
+    AccessibilityAXValueTypeString -> "string"
+    AccessibilityAXValueTypeComputedString -> "computedString"
+    AccessibilityAXValueTypeToken -> "token"
+    AccessibilityAXValueTypeTokenList -> "tokenList"
+    AccessibilityAXValueTypeDomRelation -> "domRelation"
+    AccessibilityAXValueTypeRole -> "role"
+    AccessibilityAXValueTypeInternalRole -> "internalRole"
+    AccessibilityAXValueTypeValueUndefined -> "valueUndefined"
+
+-- | Type 'Accessibility.AXValueSourceType'.
+--   Enum of possible property sources.
+data AccessibilityAXValueSourceType = AccessibilityAXValueSourceTypeAttribute | AccessibilityAXValueSourceTypeImplicit | AccessibilityAXValueSourceTypeStyle | AccessibilityAXValueSourceTypeContents | AccessibilityAXValueSourceTypePlaceholder | AccessibilityAXValueSourceTypeRelatedElement
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON AccessibilityAXValueSourceType where
+  parseJSON = A.withText "AccessibilityAXValueSourceType" $ \v -> case v of
+    "attribute" -> pure AccessibilityAXValueSourceTypeAttribute
+    "implicit" -> pure AccessibilityAXValueSourceTypeImplicit
+    "style" -> pure AccessibilityAXValueSourceTypeStyle
+    "contents" -> pure AccessibilityAXValueSourceTypeContents
+    "placeholder" -> pure AccessibilityAXValueSourceTypePlaceholder
+    "relatedElement" -> pure AccessibilityAXValueSourceTypeRelatedElement
+    "_" -> fail "failed to parse AccessibilityAXValueSourceType"
+instance ToJSON AccessibilityAXValueSourceType where
+  toJSON v = A.String $ case v of
+    AccessibilityAXValueSourceTypeAttribute -> "attribute"
+    AccessibilityAXValueSourceTypeImplicit -> "implicit"
+    AccessibilityAXValueSourceTypeStyle -> "style"
+    AccessibilityAXValueSourceTypeContents -> "contents"
+    AccessibilityAXValueSourceTypePlaceholder -> "placeholder"
+    AccessibilityAXValueSourceTypeRelatedElement -> "relatedElement"
+
+-- | Type 'Accessibility.AXValueNativeSourceType'.
+--   Enum of possible native property sources (as a subtype of a particular AXValueSourceType).
+data AccessibilityAXValueNativeSourceType = AccessibilityAXValueNativeSourceTypeDescription | AccessibilityAXValueNativeSourceTypeFigcaption | AccessibilityAXValueNativeSourceTypeLabel | AccessibilityAXValueNativeSourceTypeLabelfor | AccessibilityAXValueNativeSourceTypeLabelwrapped | AccessibilityAXValueNativeSourceTypeLegend | AccessibilityAXValueNativeSourceTypeRubyannotation | AccessibilityAXValueNativeSourceTypeTablecaption | AccessibilityAXValueNativeSourceTypeTitle | AccessibilityAXValueNativeSourceTypeOther
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON AccessibilityAXValueNativeSourceType where
+  parseJSON = A.withText "AccessibilityAXValueNativeSourceType" $ \v -> case v of
+    "description" -> pure AccessibilityAXValueNativeSourceTypeDescription
+    "figcaption" -> pure AccessibilityAXValueNativeSourceTypeFigcaption
+    "label" -> pure AccessibilityAXValueNativeSourceTypeLabel
+    "labelfor" -> pure AccessibilityAXValueNativeSourceTypeLabelfor
+    "labelwrapped" -> pure AccessibilityAXValueNativeSourceTypeLabelwrapped
+    "legend" -> pure AccessibilityAXValueNativeSourceTypeLegend
+    "rubyannotation" -> pure AccessibilityAXValueNativeSourceTypeRubyannotation
+    "tablecaption" -> pure AccessibilityAXValueNativeSourceTypeTablecaption
+    "title" -> pure AccessibilityAXValueNativeSourceTypeTitle
+    "other" -> pure AccessibilityAXValueNativeSourceTypeOther
+    "_" -> fail "failed to parse AccessibilityAXValueNativeSourceType"
+instance ToJSON AccessibilityAXValueNativeSourceType where
+  toJSON v = A.String $ case v of
+    AccessibilityAXValueNativeSourceTypeDescription -> "description"
+    AccessibilityAXValueNativeSourceTypeFigcaption -> "figcaption"
+    AccessibilityAXValueNativeSourceTypeLabel -> "label"
+    AccessibilityAXValueNativeSourceTypeLabelfor -> "labelfor"
+    AccessibilityAXValueNativeSourceTypeLabelwrapped -> "labelwrapped"
+    AccessibilityAXValueNativeSourceTypeLegend -> "legend"
+    AccessibilityAXValueNativeSourceTypeRubyannotation -> "rubyannotation"
+    AccessibilityAXValueNativeSourceTypeTablecaption -> "tablecaption"
+    AccessibilityAXValueNativeSourceTypeTitle -> "title"
+    AccessibilityAXValueNativeSourceTypeOther -> "other"
+
+-- | Type 'Accessibility.AXValueSource'.
+--   A single source for a computed AX property.
+data AccessibilityAXValueSource = AccessibilityAXValueSource
+  {
+    -- | What type of source this is.
+    accessibilityAXValueSourceType :: AccessibilityAXValueSourceType,
+    -- | The value of this property source.
+    accessibilityAXValueSourceValue :: Maybe AccessibilityAXValue,
+    -- | The name of the relevant attribute, if any.
+    accessibilityAXValueSourceAttribute :: Maybe T.Text,
+    -- | The value of the relevant attribute, if any.
+    accessibilityAXValueSourceAttributeValue :: Maybe AccessibilityAXValue,
+    -- | Whether this source is superseded by a higher priority source.
+    accessibilityAXValueSourceSuperseded :: Maybe Bool,
+    -- | The native markup source for this value, e.g. a <label> element.
+    accessibilityAXValueSourceNativeSource :: Maybe AccessibilityAXValueNativeSourceType,
+    -- | The value, such as a node or node list, of the native source.
+    accessibilityAXValueSourceNativeSourceValue :: Maybe AccessibilityAXValue,
+    -- | Whether the value for this property is invalid.
+    accessibilityAXValueSourceInvalid :: Maybe Bool,
+    -- | Reason for the value being invalid, if it is.
+    accessibilityAXValueSourceInvalidReason :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON AccessibilityAXValueSource where
+  parseJSON = A.withObject "AccessibilityAXValueSource" $ \o -> AccessibilityAXValueSource
+    <$> o A..: "type"
+    <*> o A..:? "value"
+    <*> o A..:? "attribute"
+    <*> o A..:? "attributeValue"
+    <*> o A..:? "superseded"
+    <*> o A..:? "nativeSource"
+    <*> o A..:? "nativeSourceValue"
+    <*> o A..:? "invalid"
+    <*> o A..:? "invalidReason"
+instance ToJSON AccessibilityAXValueSource where
+  toJSON p = A.object $ catMaybes [
+    ("type" A..=) <$> Just (accessibilityAXValueSourceType p),
+    ("value" A..=) <$> (accessibilityAXValueSourceValue p),
+    ("attribute" A..=) <$> (accessibilityAXValueSourceAttribute p),
+    ("attributeValue" A..=) <$> (accessibilityAXValueSourceAttributeValue p),
+    ("superseded" A..=) <$> (accessibilityAXValueSourceSuperseded p),
+    ("nativeSource" A..=) <$> (accessibilityAXValueSourceNativeSource p),
+    ("nativeSourceValue" A..=) <$> (accessibilityAXValueSourceNativeSourceValue p),
+    ("invalid" A..=) <$> (accessibilityAXValueSourceInvalid p),
+    ("invalidReason" A..=) <$> (accessibilityAXValueSourceInvalidReason p)
+    ]
+
+-- | Type 'Accessibility.AXRelatedNode'.
+data AccessibilityAXRelatedNode = AccessibilityAXRelatedNode
+  {
+    -- | The BackendNodeId of the related DOM node.
+    accessibilityAXRelatedNodeBackendDOMNodeId :: DOMPageNetworkEmulationSecurity.DOMBackendNodeId,
+    -- | The IDRef value provided, if any.
+    accessibilityAXRelatedNodeIdref :: Maybe T.Text,
+    -- | The text alternative of this node in the current context.
+    accessibilityAXRelatedNodeText :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON AccessibilityAXRelatedNode where
+  parseJSON = A.withObject "AccessibilityAXRelatedNode" $ \o -> AccessibilityAXRelatedNode
+    <$> o A..: "backendDOMNodeId"
+    <*> o A..:? "idref"
+    <*> o A..:? "text"
+instance ToJSON AccessibilityAXRelatedNode where
+  toJSON p = A.object $ catMaybes [
+    ("backendDOMNodeId" A..=) <$> Just (accessibilityAXRelatedNodeBackendDOMNodeId p),
+    ("idref" A..=) <$> (accessibilityAXRelatedNodeIdref p),
+    ("text" A..=) <$> (accessibilityAXRelatedNodeText p)
+    ]
+
+-- | Type 'Accessibility.AXProperty'.
+data AccessibilityAXProperty = AccessibilityAXProperty
+  {
+    -- | The name of this property.
+    accessibilityAXPropertyName :: AccessibilityAXPropertyName,
+    -- | The value of this property.
+    accessibilityAXPropertyValue :: AccessibilityAXValue
+  }
+  deriving (Eq, Show)
+instance FromJSON AccessibilityAXProperty where
+  parseJSON = A.withObject "AccessibilityAXProperty" $ \o -> AccessibilityAXProperty
+    <$> o A..: "name"
+    <*> o A..: "value"
+instance ToJSON AccessibilityAXProperty where
+  toJSON p = A.object $ catMaybes [
+    ("name" A..=) <$> Just (accessibilityAXPropertyName p),
+    ("value" A..=) <$> Just (accessibilityAXPropertyValue p)
+    ]
+
+-- | Type 'Accessibility.AXValue'.
+--   A single computed AX property.
+data AccessibilityAXValue = AccessibilityAXValue
+  {
+    -- | The type of this value.
+    accessibilityAXValueType :: AccessibilityAXValueType,
+    -- | The computed value of this property.
+    accessibilityAXValueValue :: Maybe A.Value,
+    -- | One or more related nodes, if applicable.
+    accessibilityAXValueRelatedNodes :: Maybe [AccessibilityAXRelatedNode],
+    -- | The sources which contributed to the computation of this property.
+    accessibilityAXValueSources :: Maybe [AccessibilityAXValueSource]
+  }
+  deriving (Eq, Show)
+instance FromJSON AccessibilityAXValue where
+  parseJSON = A.withObject "AccessibilityAXValue" $ \o -> AccessibilityAXValue
+    <$> o A..: "type"
+    <*> o A..:? "value"
+    <*> o A..:? "relatedNodes"
+    <*> o A..:? "sources"
+instance ToJSON AccessibilityAXValue where
+  toJSON p = A.object $ catMaybes [
+    ("type" A..=) <$> Just (accessibilityAXValueType p),
+    ("value" A..=) <$> (accessibilityAXValueValue p),
+    ("relatedNodes" A..=) <$> (accessibilityAXValueRelatedNodes p),
+    ("sources" A..=) <$> (accessibilityAXValueSources p)
+    ]
+
+-- | Type 'Accessibility.AXPropertyName'.
+--   Values of AXProperty name:
+--   - from 'busy' to 'roledescription': states which apply to every AX node
+--   - from 'live' to 'root': attributes which apply to nodes in live regions
+--   - from 'autocomplete' to 'valuetext': attributes which apply to widgets
+--   - from 'checked' to 'selected': states which apply to widgets
+--   - from 'activedescendant' to 'owns' - relationships between elements other than parent/child/sibling.
+data AccessibilityAXPropertyName = AccessibilityAXPropertyNameBusy | AccessibilityAXPropertyNameDisabled | AccessibilityAXPropertyNameEditable | AccessibilityAXPropertyNameFocusable | AccessibilityAXPropertyNameFocused | AccessibilityAXPropertyNameHidden | AccessibilityAXPropertyNameHiddenRoot | AccessibilityAXPropertyNameInvalid | AccessibilityAXPropertyNameKeyshortcuts | AccessibilityAXPropertyNameSettable | AccessibilityAXPropertyNameRoledescription | AccessibilityAXPropertyNameLive | AccessibilityAXPropertyNameAtomic | AccessibilityAXPropertyNameRelevant | AccessibilityAXPropertyNameRoot | AccessibilityAXPropertyNameAutocomplete | AccessibilityAXPropertyNameHasPopup | AccessibilityAXPropertyNameLevel | AccessibilityAXPropertyNameMultiselectable | AccessibilityAXPropertyNameOrientation | AccessibilityAXPropertyNameMultiline | AccessibilityAXPropertyNameReadonly | AccessibilityAXPropertyNameRequired | AccessibilityAXPropertyNameValuemin | AccessibilityAXPropertyNameValuemax | AccessibilityAXPropertyNameValuetext | AccessibilityAXPropertyNameChecked | AccessibilityAXPropertyNameExpanded | AccessibilityAXPropertyNameModal | AccessibilityAXPropertyNamePressed | AccessibilityAXPropertyNameSelected | AccessibilityAXPropertyNameActivedescendant | AccessibilityAXPropertyNameControls | AccessibilityAXPropertyNameDescribedby | AccessibilityAXPropertyNameDetails | AccessibilityAXPropertyNameErrormessage | AccessibilityAXPropertyNameFlowto | AccessibilityAXPropertyNameLabelledby | AccessibilityAXPropertyNameOwns
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON AccessibilityAXPropertyName where
+  parseJSON = A.withText "AccessibilityAXPropertyName" $ \v -> case v of
+    "busy" -> pure AccessibilityAXPropertyNameBusy
+    "disabled" -> pure AccessibilityAXPropertyNameDisabled
+    "editable" -> pure AccessibilityAXPropertyNameEditable
+    "focusable" -> pure AccessibilityAXPropertyNameFocusable
+    "focused" -> pure AccessibilityAXPropertyNameFocused
+    "hidden" -> pure AccessibilityAXPropertyNameHidden
+    "hiddenRoot" -> pure AccessibilityAXPropertyNameHiddenRoot
+    "invalid" -> pure AccessibilityAXPropertyNameInvalid
+    "keyshortcuts" -> pure AccessibilityAXPropertyNameKeyshortcuts
+    "settable" -> pure AccessibilityAXPropertyNameSettable
+    "roledescription" -> pure AccessibilityAXPropertyNameRoledescription
+    "live" -> pure AccessibilityAXPropertyNameLive
+    "atomic" -> pure AccessibilityAXPropertyNameAtomic
+    "relevant" -> pure AccessibilityAXPropertyNameRelevant
+    "root" -> pure AccessibilityAXPropertyNameRoot
+    "autocomplete" -> pure AccessibilityAXPropertyNameAutocomplete
+    "hasPopup" -> pure AccessibilityAXPropertyNameHasPopup
+    "level" -> pure AccessibilityAXPropertyNameLevel
+    "multiselectable" -> pure AccessibilityAXPropertyNameMultiselectable
+    "orientation" -> pure AccessibilityAXPropertyNameOrientation
+    "multiline" -> pure AccessibilityAXPropertyNameMultiline
+    "readonly" -> pure AccessibilityAXPropertyNameReadonly
+    "required" -> pure AccessibilityAXPropertyNameRequired
+    "valuemin" -> pure AccessibilityAXPropertyNameValuemin
+    "valuemax" -> pure AccessibilityAXPropertyNameValuemax
+    "valuetext" -> pure AccessibilityAXPropertyNameValuetext
+    "checked" -> pure AccessibilityAXPropertyNameChecked
+    "expanded" -> pure AccessibilityAXPropertyNameExpanded
+    "modal" -> pure AccessibilityAXPropertyNameModal
+    "pressed" -> pure AccessibilityAXPropertyNamePressed
+    "selected" -> pure AccessibilityAXPropertyNameSelected
+    "activedescendant" -> pure AccessibilityAXPropertyNameActivedescendant
+    "controls" -> pure AccessibilityAXPropertyNameControls
+    "describedby" -> pure AccessibilityAXPropertyNameDescribedby
+    "details" -> pure AccessibilityAXPropertyNameDetails
+    "errormessage" -> pure AccessibilityAXPropertyNameErrormessage
+    "flowto" -> pure AccessibilityAXPropertyNameFlowto
+    "labelledby" -> pure AccessibilityAXPropertyNameLabelledby
+    "owns" -> pure AccessibilityAXPropertyNameOwns
+    "_" -> fail "failed to parse AccessibilityAXPropertyName"
+instance ToJSON AccessibilityAXPropertyName where
+  toJSON v = A.String $ case v of
+    AccessibilityAXPropertyNameBusy -> "busy"
+    AccessibilityAXPropertyNameDisabled -> "disabled"
+    AccessibilityAXPropertyNameEditable -> "editable"
+    AccessibilityAXPropertyNameFocusable -> "focusable"
+    AccessibilityAXPropertyNameFocused -> "focused"
+    AccessibilityAXPropertyNameHidden -> "hidden"
+    AccessibilityAXPropertyNameHiddenRoot -> "hiddenRoot"
+    AccessibilityAXPropertyNameInvalid -> "invalid"
+    AccessibilityAXPropertyNameKeyshortcuts -> "keyshortcuts"
+    AccessibilityAXPropertyNameSettable -> "settable"
+    AccessibilityAXPropertyNameRoledescription -> "roledescription"
+    AccessibilityAXPropertyNameLive -> "live"
+    AccessibilityAXPropertyNameAtomic -> "atomic"
+    AccessibilityAXPropertyNameRelevant -> "relevant"
+    AccessibilityAXPropertyNameRoot -> "root"
+    AccessibilityAXPropertyNameAutocomplete -> "autocomplete"
+    AccessibilityAXPropertyNameHasPopup -> "hasPopup"
+    AccessibilityAXPropertyNameLevel -> "level"
+    AccessibilityAXPropertyNameMultiselectable -> "multiselectable"
+    AccessibilityAXPropertyNameOrientation -> "orientation"
+    AccessibilityAXPropertyNameMultiline -> "multiline"
+    AccessibilityAXPropertyNameReadonly -> "readonly"
+    AccessibilityAXPropertyNameRequired -> "required"
+    AccessibilityAXPropertyNameValuemin -> "valuemin"
+    AccessibilityAXPropertyNameValuemax -> "valuemax"
+    AccessibilityAXPropertyNameValuetext -> "valuetext"
+    AccessibilityAXPropertyNameChecked -> "checked"
+    AccessibilityAXPropertyNameExpanded -> "expanded"
+    AccessibilityAXPropertyNameModal -> "modal"
+    AccessibilityAXPropertyNamePressed -> "pressed"
+    AccessibilityAXPropertyNameSelected -> "selected"
+    AccessibilityAXPropertyNameActivedescendant -> "activedescendant"
+    AccessibilityAXPropertyNameControls -> "controls"
+    AccessibilityAXPropertyNameDescribedby -> "describedby"
+    AccessibilityAXPropertyNameDetails -> "details"
+    AccessibilityAXPropertyNameErrormessage -> "errormessage"
+    AccessibilityAXPropertyNameFlowto -> "flowto"
+    AccessibilityAXPropertyNameLabelledby -> "labelledby"
+    AccessibilityAXPropertyNameOwns -> "owns"
+
+-- | Type 'Accessibility.AXNode'.
+--   A node in the accessibility tree.
+data AccessibilityAXNode = AccessibilityAXNode
+  {
+    -- | Unique identifier for this node.
+    accessibilityAXNodeNodeId :: AccessibilityAXNodeId,
+    -- | Whether this node is ignored for accessibility
+    accessibilityAXNodeIgnored :: Bool,
+    -- | Collection of reasons why this node is hidden.
+    accessibilityAXNodeIgnoredReasons :: Maybe [AccessibilityAXProperty],
+    -- | This `Node`'s role, whether explicit or implicit.
+    accessibilityAXNodeRole :: Maybe AccessibilityAXValue,
+    -- | This `Node`'s Chrome raw role.
+    accessibilityAXNodeChromeRole :: Maybe AccessibilityAXValue,
+    -- | The accessible name for this `Node`.
+    accessibilityAXNodeName :: Maybe AccessibilityAXValue,
+    -- | The accessible description for this `Node`.
+    accessibilityAXNodeDescription :: Maybe AccessibilityAXValue,
+    -- | The value for this `Node`.
+    accessibilityAXNodeValue :: Maybe AccessibilityAXValue,
+    -- | All other properties
+    accessibilityAXNodeProperties :: Maybe [AccessibilityAXProperty],
+    -- | ID for this node's parent.
+    accessibilityAXNodeParentId :: Maybe AccessibilityAXNodeId,
+    -- | IDs for each of this node's child nodes.
+    accessibilityAXNodeChildIds :: Maybe [AccessibilityAXNodeId],
+    -- | The backend ID for the associated DOM node, if any.
+    accessibilityAXNodeBackendDOMNodeId :: Maybe DOMPageNetworkEmulationSecurity.DOMBackendNodeId,
+    -- | The frame ID for the frame associated with this nodes document.
+    accessibilityAXNodeFrameId :: Maybe DOMPageNetworkEmulationSecurity.PageFrameId
+  }
+  deriving (Eq, Show)
+instance FromJSON AccessibilityAXNode where
+  parseJSON = A.withObject "AccessibilityAXNode" $ \o -> AccessibilityAXNode
+    <$> o A..: "nodeId"
+    <*> o A..: "ignored"
+    <*> o A..:? "ignoredReasons"
+    <*> o A..:? "role"
+    <*> o A..:? "chromeRole"
+    <*> o A..:? "name"
+    <*> o A..:? "description"
+    <*> o A..:? "value"
+    <*> o A..:? "properties"
+    <*> o A..:? "parentId"
+    <*> o A..:? "childIds"
+    <*> o A..:? "backendDOMNodeId"
+    <*> o A..:? "frameId"
+instance ToJSON AccessibilityAXNode where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> Just (accessibilityAXNodeNodeId p),
+    ("ignored" A..=) <$> Just (accessibilityAXNodeIgnored p),
+    ("ignoredReasons" A..=) <$> (accessibilityAXNodeIgnoredReasons p),
+    ("role" A..=) <$> (accessibilityAXNodeRole p),
+    ("chromeRole" A..=) <$> (accessibilityAXNodeChromeRole p),
+    ("name" A..=) <$> (accessibilityAXNodeName p),
+    ("description" A..=) <$> (accessibilityAXNodeDescription p),
+    ("value" A..=) <$> (accessibilityAXNodeValue p),
+    ("properties" A..=) <$> (accessibilityAXNodeProperties p),
+    ("parentId" A..=) <$> (accessibilityAXNodeParentId p),
+    ("childIds" A..=) <$> (accessibilityAXNodeChildIds p),
+    ("backendDOMNodeId" A..=) <$> (accessibilityAXNodeBackendDOMNodeId p),
+    ("frameId" A..=) <$> (accessibilityAXNodeFrameId p)
+    ]
+
+-- | Type of the 'Accessibility.loadComplete' event.
+data AccessibilityLoadComplete = AccessibilityLoadComplete
+  {
+    -- | New document root node.
+    accessibilityLoadCompleteRoot :: AccessibilityAXNode
+  }
+  deriving (Eq, Show)
+instance FromJSON AccessibilityLoadComplete where
+  parseJSON = A.withObject "AccessibilityLoadComplete" $ \o -> AccessibilityLoadComplete
+    <$> o A..: "root"
+instance Event AccessibilityLoadComplete where
+  eventName _ = "Accessibility.loadComplete"
+
+-- | Type of the 'Accessibility.nodesUpdated' event.
+data AccessibilityNodesUpdated = AccessibilityNodesUpdated
+  {
+    -- | Updated node data.
+    accessibilityNodesUpdatedNodes :: [AccessibilityAXNode]
+  }
+  deriving (Eq, Show)
+instance FromJSON AccessibilityNodesUpdated where
+  parseJSON = A.withObject "AccessibilityNodesUpdated" $ \o -> AccessibilityNodesUpdated
+    <$> o A..: "nodes"
+instance Event AccessibilityNodesUpdated where
+  eventName _ = "Accessibility.nodesUpdated"
+
+-- | Disables the accessibility domain.
+
+-- | Parameters of the 'Accessibility.disable' command.
+data PAccessibilityDisable = PAccessibilityDisable
+  deriving (Eq, Show)
+pAccessibilityDisable
+  :: PAccessibilityDisable
+pAccessibilityDisable
+  = PAccessibilityDisable
+instance ToJSON PAccessibilityDisable where
+  toJSON _ = A.Null
+instance Command PAccessibilityDisable where
+  type CommandResponse PAccessibilityDisable = ()
+  commandName _ = "Accessibility.disable"
+  fromJSON = const . A.Success . const ()
+
+-- | Enables the accessibility domain which causes `AXNodeId`s to remain consistent between method calls.
+--   This turns on accessibility for the page, which can impact performance until accessibility is disabled.
+
+-- | Parameters of the 'Accessibility.enable' command.
+data PAccessibilityEnable = PAccessibilityEnable
+  deriving (Eq, Show)
+pAccessibilityEnable
+  :: PAccessibilityEnable
+pAccessibilityEnable
+  = PAccessibilityEnable
+instance ToJSON PAccessibilityEnable where
+  toJSON _ = A.Null
+instance Command PAccessibilityEnable where
+  type CommandResponse PAccessibilityEnable = ()
+  commandName _ = "Accessibility.enable"
+  fromJSON = const . A.Success . const ()
+
+-- | Fetches the accessibility node and partial accessibility tree for this DOM node, if it exists.
+
+-- | Parameters of the 'Accessibility.getPartialAXTree' command.
+data PAccessibilityGetPartialAXTree = PAccessibilityGetPartialAXTree
+  {
+    -- | Identifier of the node to get the partial accessibility tree for.
+    pAccessibilityGetPartialAXTreeNodeId :: Maybe DOMPageNetworkEmulationSecurity.DOMNodeId,
+    -- | Identifier of the backend node to get the partial accessibility tree for.
+    pAccessibilityGetPartialAXTreeBackendNodeId :: Maybe DOMPageNetworkEmulationSecurity.DOMBackendNodeId,
+    -- | JavaScript object id of the node wrapper to get the partial accessibility tree for.
+    pAccessibilityGetPartialAXTreeObjectId :: Maybe Runtime.RuntimeRemoteObjectId,
+    -- | Whether to fetch this nodes ancestors, siblings and children. Defaults to true.
+    pAccessibilityGetPartialAXTreeFetchRelatives :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pAccessibilityGetPartialAXTree
+  :: PAccessibilityGetPartialAXTree
+pAccessibilityGetPartialAXTree
+  = PAccessibilityGetPartialAXTree
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PAccessibilityGetPartialAXTree where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> (pAccessibilityGetPartialAXTreeNodeId p),
+    ("backendNodeId" A..=) <$> (pAccessibilityGetPartialAXTreeBackendNodeId p),
+    ("objectId" A..=) <$> (pAccessibilityGetPartialAXTreeObjectId p),
+    ("fetchRelatives" A..=) <$> (pAccessibilityGetPartialAXTreeFetchRelatives p)
+    ]
+data AccessibilityGetPartialAXTree = AccessibilityGetPartialAXTree
+  {
+    -- | The `Accessibility.AXNode` for this DOM node, if it exists, plus its ancestors, siblings and
+    --   children, if requested.
+    accessibilityGetPartialAXTreeNodes :: [AccessibilityAXNode]
+  }
+  deriving (Eq, Show)
+instance FromJSON AccessibilityGetPartialAXTree where
+  parseJSON = A.withObject "AccessibilityGetPartialAXTree" $ \o -> AccessibilityGetPartialAXTree
+    <$> o A..: "nodes"
+instance Command PAccessibilityGetPartialAXTree where
+  type CommandResponse PAccessibilityGetPartialAXTree = AccessibilityGetPartialAXTree
+  commandName _ = "Accessibility.getPartialAXTree"
+
+-- | Fetches the entire accessibility tree for the root Document
+
+-- | Parameters of the 'Accessibility.getFullAXTree' command.
+data PAccessibilityGetFullAXTree = PAccessibilityGetFullAXTree
+  {
+    -- | The maximum depth at which descendants of the root node should be retrieved.
+    --   If omitted, the full tree is returned.
+    pAccessibilityGetFullAXTreeDepth :: Maybe Int,
+    -- | The frame for whose document the AX tree should be retrieved.
+    --   If omited, the root frame is used.
+    pAccessibilityGetFullAXTreeFrameId :: Maybe DOMPageNetworkEmulationSecurity.PageFrameId
+  }
+  deriving (Eq, Show)
+pAccessibilityGetFullAXTree
+  :: PAccessibilityGetFullAXTree
+pAccessibilityGetFullAXTree
+  = PAccessibilityGetFullAXTree
+    Nothing
+    Nothing
+instance ToJSON PAccessibilityGetFullAXTree where
+  toJSON p = A.object $ catMaybes [
+    ("depth" A..=) <$> (pAccessibilityGetFullAXTreeDepth p),
+    ("frameId" A..=) <$> (pAccessibilityGetFullAXTreeFrameId p)
+    ]
+data AccessibilityGetFullAXTree = AccessibilityGetFullAXTree
+  {
+    accessibilityGetFullAXTreeNodes :: [AccessibilityAXNode]
+  }
+  deriving (Eq, Show)
+instance FromJSON AccessibilityGetFullAXTree where
+  parseJSON = A.withObject "AccessibilityGetFullAXTree" $ \o -> AccessibilityGetFullAXTree
+    <$> o A..: "nodes"
+instance Command PAccessibilityGetFullAXTree where
+  type CommandResponse PAccessibilityGetFullAXTree = AccessibilityGetFullAXTree
+  commandName _ = "Accessibility.getFullAXTree"
+
+-- | Fetches the root node.
+--   Requires `enable()` to have been called previously.
+
+-- | Parameters of the 'Accessibility.getRootAXNode' command.
+data PAccessibilityGetRootAXNode = PAccessibilityGetRootAXNode
+  {
+    -- | The frame in whose document the node resides.
+    --   If omitted, the root frame is used.
+    pAccessibilityGetRootAXNodeFrameId :: Maybe DOMPageNetworkEmulationSecurity.PageFrameId
+  }
+  deriving (Eq, Show)
+pAccessibilityGetRootAXNode
+  :: PAccessibilityGetRootAXNode
+pAccessibilityGetRootAXNode
+  = PAccessibilityGetRootAXNode
+    Nothing
+instance ToJSON PAccessibilityGetRootAXNode where
+  toJSON p = A.object $ catMaybes [
+    ("frameId" A..=) <$> (pAccessibilityGetRootAXNodeFrameId p)
+    ]
+data AccessibilityGetRootAXNode = AccessibilityGetRootAXNode
+  {
+    accessibilityGetRootAXNodeNode :: AccessibilityAXNode
+  }
+  deriving (Eq, Show)
+instance FromJSON AccessibilityGetRootAXNode where
+  parseJSON = A.withObject "AccessibilityGetRootAXNode" $ \o -> AccessibilityGetRootAXNode
+    <$> o A..: "node"
+instance Command PAccessibilityGetRootAXNode where
+  type CommandResponse PAccessibilityGetRootAXNode = AccessibilityGetRootAXNode
+  commandName _ = "Accessibility.getRootAXNode"
+
+-- | Fetches a node and all ancestors up to and including the root.
+--   Requires `enable()` to have been called previously.
+
+-- | Parameters of the 'Accessibility.getAXNodeAndAncestors' command.
+data PAccessibilityGetAXNodeAndAncestors = PAccessibilityGetAXNodeAndAncestors
+  {
+    -- | Identifier of the node to get.
+    pAccessibilityGetAXNodeAndAncestorsNodeId :: Maybe DOMPageNetworkEmulationSecurity.DOMNodeId,
+    -- | Identifier of the backend node to get.
+    pAccessibilityGetAXNodeAndAncestorsBackendNodeId :: Maybe DOMPageNetworkEmulationSecurity.DOMBackendNodeId,
+    -- | JavaScript object id of the node wrapper to get.
+    pAccessibilityGetAXNodeAndAncestorsObjectId :: Maybe Runtime.RuntimeRemoteObjectId
+  }
+  deriving (Eq, Show)
+pAccessibilityGetAXNodeAndAncestors
+  :: PAccessibilityGetAXNodeAndAncestors
+pAccessibilityGetAXNodeAndAncestors
+  = PAccessibilityGetAXNodeAndAncestors
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PAccessibilityGetAXNodeAndAncestors where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> (pAccessibilityGetAXNodeAndAncestorsNodeId p),
+    ("backendNodeId" A..=) <$> (pAccessibilityGetAXNodeAndAncestorsBackendNodeId p),
+    ("objectId" A..=) <$> (pAccessibilityGetAXNodeAndAncestorsObjectId p)
+    ]
+data AccessibilityGetAXNodeAndAncestors = AccessibilityGetAXNodeAndAncestors
+  {
+    accessibilityGetAXNodeAndAncestorsNodes :: [AccessibilityAXNode]
+  }
+  deriving (Eq, Show)
+instance FromJSON AccessibilityGetAXNodeAndAncestors where
+  parseJSON = A.withObject "AccessibilityGetAXNodeAndAncestors" $ \o -> AccessibilityGetAXNodeAndAncestors
+    <$> o A..: "nodes"
+instance Command PAccessibilityGetAXNodeAndAncestors where
+  type CommandResponse PAccessibilityGetAXNodeAndAncestors = AccessibilityGetAXNodeAndAncestors
+  commandName _ = "Accessibility.getAXNodeAndAncestors"
+
+-- | Fetches a particular accessibility node by AXNodeId.
+--   Requires `enable()` to have been called previously.
+
+-- | Parameters of the 'Accessibility.getChildAXNodes' command.
+data PAccessibilityGetChildAXNodes = PAccessibilityGetChildAXNodes
+  {
+    pAccessibilityGetChildAXNodesId :: AccessibilityAXNodeId,
+    -- | The frame in whose document the node resides.
+    --   If omitted, the root frame is used.
+    pAccessibilityGetChildAXNodesFrameId :: Maybe DOMPageNetworkEmulationSecurity.PageFrameId
+  }
+  deriving (Eq, Show)
+pAccessibilityGetChildAXNodes
+  :: AccessibilityAXNodeId
+  -> PAccessibilityGetChildAXNodes
+pAccessibilityGetChildAXNodes
+  arg_pAccessibilityGetChildAXNodesId
+  = PAccessibilityGetChildAXNodes
+    arg_pAccessibilityGetChildAXNodesId
+    Nothing
+instance ToJSON PAccessibilityGetChildAXNodes where
+  toJSON p = A.object $ catMaybes [
+    ("id" A..=) <$> Just (pAccessibilityGetChildAXNodesId p),
+    ("frameId" A..=) <$> (pAccessibilityGetChildAXNodesFrameId p)
+    ]
+data AccessibilityGetChildAXNodes = AccessibilityGetChildAXNodes
+  {
+    accessibilityGetChildAXNodesNodes :: [AccessibilityAXNode]
+  }
+  deriving (Eq, Show)
+instance FromJSON AccessibilityGetChildAXNodes where
+  parseJSON = A.withObject "AccessibilityGetChildAXNodes" $ \o -> AccessibilityGetChildAXNodes
+    <$> o A..: "nodes"
+instance Command PAccessibilityGetChildAXNodes where
+  type CommandResponse PAccessibilityGetChildAXNodes = AccessibilityGetChildAXNodes
+  commandName _ = "Accessibility.getChildAXNodes"
+
+-- | Query a DOM node's accessibility subtree for accessible name and role.
+--   This command computes the name and role for all nodes in the subtree, including those that are
+--   ignored for accessibility, and returns those that mactch the specified name and role. If no DOM
+--   node is specified, or the DOM node does not exist, the command returns an error. If neither
+--   `accessibleName` or `role` is specified, it returns all the accessibility nodes in the subtree.
+
+-- | Parameters of the 'Accessibility.queryAXTree' command.
+data PAccessibilityQueryAXTree = PAccessibilityQueryAXTree
+  {
+    -- | Identifier of the node for the root to query.
+    pAccessibilityQueryAXTreeNodeId :: Maybe DOMPageNetworkEmulationSecurity.DOMNodeId,
+    -- | Identifier of the backend node for the root to query.
+    pAccessibilityQueryAXTreeBackendNodeId :: Maybe DOMPageNetworkEmulationSecurity.DOMBackendNodeId,
+    -- | JavaScript object id of the node wrapper for the root to query.
+    pAccessibilityQueryAXTreeObjectId :: Maybe Runtime.RuntimeRemoteObjectId,
+    -- | Find nodes with this computed name.
+    pAccessibilityQueryAXTreeAccessibleName :: Maybe T.Text,
+    -- | Find nodes with this computed role.
+    pAccessibilityQueryAXTreeRole :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+pAccessibilityQueryAXTree
+  :: PAccessibilityQueryAXTree
+pAccessibilityQueryAXTree
+  = PAccessibilityQueryAXTree
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PAccessibilityQueryAXTree where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> (pAccessibilityQueryAXTreeNodeId p),
+    ("backendNodeId" A..=) <$> (pAccessibilityQueryAXTreeBackendNodeId p),
+    ("objectId" A..=) <$> (pAccessibilityQueryAXTreeObjectId p),
+    ("accessibleName" A..=) <$> (pAccessibilityQueryAXTreeAccessibleName p),
+    ("role" A..=) <$> (pAccessibilityQueryAXTreeRole p)
+    ]
+data AccessibilityQueryAXTree = AccessibilityQueryAXTree
+  {
+    -- | A list of `Accessibility.AXNode` matching the specified attributes,
+    --   including nodes that are ignored for accessibility.
+    accessibilityQueryAXTreeNodes :: [AccessibilityAXNode]
+  }
+  deriving (Eq, Show)
+instance FromJSON AccessibilityQueryAXTree where
+  parseJSON = A.withObject "AccessibilityQueryAXTree" $ \o -> AccessibilityQueryAXTree
+    <$> o A..: "nodes"
+instance Command PAccessibilityQueryAXTree where
+  type CommandResponse PAccessibilityQueryAXTree = AccessibilityQueryAXTree
+  commandName _ = "Accessibility.queryAXTree"
+
diff --git a/src/CDP/Domains/Animation.hs b/src/CDP/Domains/Animation.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains/Animation.hs
@@ -0,0 +1,552 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+
+
+{- |
+= Animation
+
+-}
+
+
+module CDP.Domains.Animation (module CDP.Domains.Animation) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+
+import CDP.Domains.DOMPageNetworkEmulationSecurity as DOMPageNetworkEmulationSecurity
+import CDP.Domains.Runtime as Runtime
+
+
+-- | Type 'Animation.Animation'.
+--   Animation instance.
+data AnimationAnimationType = AnimationAnimationTypeCSSTransition | AnimationAnimationTypeCSSAnimation | AnimationAnimationTypeWebAnimation
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON AnimationAnimationType where
+  parseJSON = A.withText "AnimationAnimationType" $ \v -> case v of
+    "CSSTransition" -> pure AnimationAnimationTypeCSSTransition
+    "CSSAnimation" -> pure AnimationAnimationTypeCSSAnimation
+    "WebAnimation" -> pure AnimationAnimationTypeWebAnimation
+    "_" -> fail "failed to parse AnimationAnimationType"
+instance ToJSON AnimationAnimationType where
+  toJSON v = A.String $ case v of
+    AnimationAnimationTypeCSSTransition -> "CSSTransition"
+    AnimationAnimationTypeCSSAnimation -> "CSSAnimation"
+    AnimationAnimationTypeWebAnimation -> "WebAnimation"
+data AnimationAnimation = AnimationAnimation
+  {
+    -- | `Animation`'s id.
+    animationAnimationId :: T.Text,
+    -- | `Animation`'s name.
+    animationAnimationName :: T.Text,
+    -- | `Animation`'s internal paused state.
+    animationAnimationPausedState :: Bool,
+    -- | `Animation`'s play state.
+    animationAnimationPlayState :: T.Text,
+    -- | `Animation`'s playback rate.
+    animationAnimationPlaybackRate :: Double,
+    -- | `Animation`'s start time.
+    animationAnimationStartTime :: Double,
+    -- | `Animation`'s current time.
+    animationAnimationCurrentTime :: Double,
+    -- | Animation type of `Animation`.
+    animationAnimationType :: AnimationAnimationType,
+    -- | `Animation`'s source animation node.
+    animationAnimationSource :: Maybe AnimationAnimationEffect,
+    -- | A unique ID for `Animation` representing the sources that triggered this CSS
+    --   animation/transition.
+    animationAnimationCssId :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON AnimationAnimation where
+  parseJSON = A.withObject "AnimationAnimation" $ \o -> AnimationAnimation
+    <$> o A..: "id"
+    <*> o A..: "name"
+    <*> o A..: "pausedState"
+    <*> o A..: "playState"
+    <*> o A..: "playbackRate"
+    <*> o A..: "startTime"
+    <*> o A..: "currentTime"
+    <*> o A..: "type"
+    <*> o A..:? "source"
+    <*> o A..:? "cssId"
+instance ToJSON AnimationAnimation where
+  toJSON p = A.object $ catMaybes [
+    ("id" A..=) <$> Just (animationAnimationId p),
+    ("name" A..=) <$> Just (animationAnimationName p),
+    ("pausedState" A..=) <$> Just (animationAnimationPausedState p),
+    ("playState" A..=) <$> Just (animationAnimationPlayState p),
+    ("playbackRate" A..=) <$> Just (animationAnimationPlaybackRate p),
+    ("startTime" A..=) <$> Just (animationAnimationStartTime p),
+    ("currentTime" A..=) <$> Just (animationAnimationCurrentTime p),
+    ("type" A..=) <$> Just (animationAnimationType p),
+    ("source" A..=) <$> (animationAnimationSource p),
+    ("cssId" A..=) <$> (animationAnimationCssId p)
+    ]
+
+-- | Type 'Animation.AnimationEffect'.
+--   AnimationEffect instance
+data AnimationAnimationEffect = AnimationAnimationEffect
+  {
+    -- | `AnimationEffect`'s delay.
+    animationAnimationEffectDelay :: Double,
+    -- | `AnimationEffect`'s end delay.
+    animationAnimationEffectEndDelay :: Double,
+    -- | `AnimationEffect`'s iteration start.
+    animationAnimationEffectIterationStart :: Double,
+    -- | `AnimationEffect`'s iterations.
+    animationAnimationEffectIterations :: Double,
+    -- | `AnimationEffect`'s iteration duration.
+    animationAnimationEffectDuration :: Double,
+    -- | `AnimationEffect`'s playback direction.
+    animationAnimationEffectDirection :: T.Text,
+    -- | `AnimationEffect`'s fill mode.
+    animationAnimationEffectFill :: T.Text,
+    -- | `AnimationEffect`'s target node.
+    animationAnimationEffectBackendNodeId :: Maybe DOMPageNetworkEmulationSecurity.DOMBackendNodeId,
+    -- | `AnimationEffect`'s keyframes.
+    animationAnimationEffectKeyframesRule :: Maybe AnimationKeyframesRule,
+    -- | `AnimationEffect`'s timing function.
+    animationAnimationEffectEasing :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON AnimationAnimationEffect where
+  parseJSON = A.withObject "AnimationAnimationEffect" $ \o -> AnimationAnimationEffect
+    <$> o A..: "delay"
+    <*> o A..: "endDelay"
+    <*> o A..: "iterationStart"
+    <*> o A..: "iterations"
+    <*> o A..: "duration"
+    <*> o A..: "direction"
+    <*> o A..: "fill"
+    <*> o A..:? "backendNodeId"
+    <*> o A..:? "keyframesRule"
+    <*> o A..: "easing"
+instance ToJSON AnimationAnimationEffect where
+  toJSON p = A.object $ catMaybes [
+    ("delay" A..=) <$> Just (animationAnimationEffectDelay p),
+    ("endDelay" A..=) <$> Just (animationAnimationEffectEndDelay p),
+    ("iterationStart" A..=) <$> Just (animationAnimationEffectIterationStart p),
+    ("iterations" A..=) <$> Just (animationAnimationEffectIterations p),
+    ("duration" A..=) <$> Just (animationAnimationEffectDuration p),
+    ("direction" A..=) <$> Just (animationAnimationEffectDirection p),
+    ("fill" A..=) <$> Just (animationAnimationEffectFill p),
+    ("backendNodeId" A..=) <$> (animationAnimationEffectBackendNodeId p),
+    ("keyframesRule" A..=) <$> (animationAnimationEffectKeyframesRule p),
+    ("easing" A..=) <$> Just (animationAnimationEffectEasing p)
+    ]
+
+-- | Type 'Animation.KeyframesRule'.
+--   Keyframes Rule
+data AnimationKeyframesRule = AnimationKeyframesRule
+  {
+    -- | CSS keyframed animation's name.
+    animationKeyframesRuleName :: Maybe T.Text,
+    -- | List of animation keyframes.
+    animationKeyframesRuleKeyframes :: [AnimationKeyframeStyle]
+  }
+  deriving (Eq, Show)
+instance FromJSON AnimationKeyframesRule where
+  parseJSON = A.withObject "AnimationKeyframesRule" $ \o -> AnimationKeyframesRule
+    <$> o A..:? "name"
+    <*> o A..: "keyframes"
+instance ToJSON AnimationKeyframesRule where
+  toJSON p = A.object $ catMaybes [
+    ("name" A..=) <$> (animationKeyframesRuleName p),
+    ("keyframes" A..=) <$> Just (animationKeyframesRuleKeyframes p)
+    ]
+
+-- | Type 'Animation.KeyframeStyle'.
+--   Keyframe Style
+data AnimationKeyframeStyle = AnimationKeyframeStyle
+  {
+    -- | Keyframe's time offset.
+    animationKeyframeStyleOffset :: T.Text,
+    -- | `AnimationEffect`'s timing function.
+    animationKeyframeStyleEasing :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON AnimationKeyframeStyle where
+  parseJSON = A.withObject "AnimationKeyframeStyle" $ \o -> AnimationKeyframeStyle
+    <$> o A..: "offset"
+    <*> o A..: "easing"
+instance ToJSON AnimationKeyframeStyle where
+  toJSON p = A.object $ catMaybes [
+    ("offset" A..=) <$> Just (animationKeyframeStyleOffset p),
+    ("easing" A..=) <$> Just (animationKeyframeStyleEasing p)
+    ]
+
+-- | Type of the 'Animation.animationCanceled' event.
+data AnimationAnimationCanceled = AnimationAnimationCanceled
+  {
+    -- | Id of the animation that was cancelled.
+    animationAnimationCanceledId :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON AnimationAnimationCanceled where
+  parseJSON = A.withObject "AnimationAnimationCanceled" $ \o -> AnimationAnimationCanceled
+    <$> o A..: "id"
+instance Event AnimationAnimationCanceled where
+  eventName _ = "Animation.animationCanceled"
+
+-- | Type of the 'Animation.animationCreated' event.
+data AnimationAnimationCreated = AnimationAnimationCreated
+  {
+    -- | Id of the animation that was created.
+    animationAnimationCreatedId :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON AnimationAnimationCreated where
+  parseJSON = A.withObject "AnimationAnimationCreated" $ \o -> AnimationAnimationCreated
+    <$> o A..: "id"
+instance Event AnimationAnimationCreated where
+  eventName _ = "Animation.animationCreated"
+
+-- | Type of the 'Animation.animationStarted' event.
+data AnimationAnimationStarted = AnimationAnimationStarted
+  {
+    -- | Animation that was started.
+    animationAnimationStartedAnimation :: AnimationAnimation
+  }
+  deriving (Eq, Show)
+instance FromJSON AnimationAnimationStarted where
+  parseJSON = A.withObject "AnimationAnimationStarted" $ \o -> AnimationAnimationStarted
+    <$> o A..: "animation"
+instance Event AnimationAnimationStarted where
+  eventName _ = "Animation.animationStarted"
+
+-- | Disables animation domain notifications.
+
+-- | Parameters of the 'Animation.disable' command.
+data PAnimationDisable = PAnimationDisable
+  deriving (Eq, Show)
+pAnimationDisable
+  :: PAnimationDisable
+pAnimationDisable
+  = PAnimationDisable
+instance ToJSON PAnimationDisable where
+  toJSON _ = A.Null
+instance Command PAnimationDisable where
+  type CommandResponse PAnimationDisable = ()
+  commandName _ = "Animation.disable"
+  fromJSON = const . A.Success . const ()
+
+-- | Enables animation domain notifications.
+
+-- | Parameters of the 'Animation.enable' command.
+data PAnimationEnable = PAnimationEnable
+  deriving (Eq, Show)
+pAnimationEnable
+  :: PAnimationEnable
+pAnimationEnable
+  = PAnimationEnable
+instance ToJSON PAnimationEnable where
+  toJSON _ = A.Null
+instance Command PAnimationEnable where
+  type CommandResponse PAnimationEnable = ()
+  commandName _ = "Animation.enable"
+  fromJSON = const . A.Success . const ()
+
+-- | Returns the current time of the an animation.
+
+-- | Parameters of the 'Animation.getCurrentTime' command.
+data PAnimationGetCurrentTime = PAnimationGetCurrentTime
+  {
+    -- | Id of animation.
+    pAnimationGetCurrentTimeId :: T.Text
+  }
+  deriving (Eq, Show)
+pAnimationGetCurrentTime
+  {-
+  -- | Id of animation.
+  -}
+  :: T.Text
+  -> PAnimationGetCurrentTime
+pAnimationGetCurrentTime
+  arg_pAnimationGetCurrentTimeId
+  = PAnimationGetCurrentTime
+    arg_pAnimationGetCurrentTimeId
+instance ToJSON PAnimationGetCurrentTime where
+  toJSON p = A.object $ catMaybes [
+    ("id" A..=) <$> Just (pAnimationGetCurrentTimeId p)
+    ]
+data AnimationGetCurrentTime = AnimationGetCurrentTime
+  {
+    -- | Current time of the page.
+    animationGetCurrentTimeCurrentTime :: Double
+  }
+  deriving (Eq, Show)
+instance FromJSON AnimationGetCurrentTime where
+  parseJSON = A.withObject "AnimationGetCurrentTime" $ \o -> AnimationGetCurrentTime
+    <$> o A..: "currentTime"
+instance Command PAnimationGetCurrentTime where
+  type CommandResponse PAnimationGetCurrentTime = AnimationGetCurrentTime
+  commandName _ = "Animation.getCurrentTime"
+
+-- | Gets the playback rate of the document timeline.
+
+-- | Parameters of the 'Animation.getPlaybackRate' command.
+data PAnimationGetPlaybackRate = PAnimationGetPlaybackRate
+  deriving (Eq, Show)
+pAnimationGetPlaybackRate
+  :: PAnimationGetPlaybackRate
+pAnimationGetPlaybackRate
+  = PAnimationGetPlaybackRate
+instance ToJSON PAnimationGetPlaybackRate where
+  toJSON _ = A.Null
+data AnimationGetPlaybackRate = AnimationGetPlaybackRate
+  {
+    -- | Playback rate for animations on page.
+    animationGetPlaybackRatePlaybackRate :: Double
+  }
+  deriving (Eq, Show)
+instance FromJSON AnimationGetPlaybackRate where
+  parseJSON = A.withObject "AnimationGetPlaybackRate" $ \o -> AnimationGetPlaybackRate
+    <$> o A..: "playbackRate"
+instance Command PAnimationGetPlaybackRate where
+  type CommandResponse PAnimationGetPlaybackRate = AnimationGetPlaybackRate
+  commandName _ = "Animation.getPlaybackRate"
+
+-- | Releases a set of animations to no longer be manipulated.
+
+-- | Parameters of the 'Animation.releaseAnimations' command.
+data PAnimationReleaseAnimations = PAnimationReleaseAnimations
+  {
+    -- | List of animation ids to seek.
+    pAnimationReleaseAnimationsAnimations :: [T.Text]
+  }
+  deriving (Eq, Show)
+pAnimationReleaseAnimations
+  {-
+  -- | List of animation ids to seek.
+  -}
+  :: [T.Text]
+  -> PAnimationReleaseAnimations
+pAnimationReleaseAnimations
+  arg_pAnimationReleaseAnimationsAnimations
+  = PAnimationReleaseAnimations
+    arg_pAnimationReleaseAnimationsAnimations
+instance ToJSON PAnimationReleaseAnimations where
+  toJSON p = A.object $ catMaybes [
+    ("animations" A..=) <$> Just (pAnimationReleaseAnimationsAnimations p)
+    ]
+instance Command PAnimationReleaseAnimations where
+  type CommandResponse PAnimationReleaseAnimations = ()
+  commandName _ = "Animation.releaseAnimations"
+  fromJSON = const . A.Success . const ()
+
+-- | Gets the remote object of the Animation.
+
+-- | Parameters of the 'Animation.resolveAnimation' command.
+data PAnimationResolveAnimation = PAnimationResolveAnimation
+  {
+    -- | Animation id.
+    pAnimationResolveAnimationAnimationId :: T.Text
+  }
+  deriving (Eq, Show)
+pAnimationResolveAnimation
+  {-
+  -- | Animation id.
+  -}
+  :: T.Text
+  -> PAnimationResolveAnimation
+pAnimationResolveAnimation
+  arg_pAnimationResolveAnimationAnimationId
+  = PAnimationResolveAnimation
+    arg_pAnimationResolveAnimationAnimationId
+instance ToJSON PAnimationResolveAnimation where
+  toJSON p = A.object $ catMaybes [
+    ("animationId" A..=) <$> Just (pAnimationResolveAnimationAnimationId p)
+    ]
+data AnimationResolveAnimation = AnimationResolveAnimation
+  {
+    -- | Corresponding remote object.
+    animationResolveAnimationRemoteObject :: Runtime.RuntimeRemoteObject
+  }
+  deriving (Eq, Show)
+instance FromJSON AnimationResolveAnimation where
+  parseJSON = A.withObject "AnimationResolveAnimation" $ \o -> AnimationResolveAnimation
+    <$> o A..: "remoteObject"
+instance Command PAnimationResolveAnimation where
+  type CommandResponse PAnimationResolveAnimation = AnimationResolveAnimation
+  commandName _ = "Animation.resolveAnimation"
+
+-- | Seek a set of animations to a particular time within each animation.
+
+-- | Parameters of the 'Animation.seekAnimations' command.
+data PAnimationSeekAnimations = PAnimationSeekAnimations
+  {
+    -- | List of animation ids to seek.
+    pAnimationSeekAnimationsAnimations :: [T.Text],
+    -- | Set the current time of each animation.
+    pAnimationSeekAnimationsCurrentTime :: Double
+  }
+  deriving (Eq, Show)
+pAnimationSeekAnimations
+  {-
+  -- | List of animation ids to seek.
+  -}
+  :: [T.Text]
+  {-
+  -- | Set the current time of each animation.
+  -}
+  -> Double
+  -> PAnimationSeekAnimations
+pAnimationSeekAnimations
+  arg_pAnimationSeekAnimationsAnimations
+  arg_pAnimationSeekAnimationsCurrentTime
+  = PAnimationSeekAnimations
+    arg_pAnimationSeekAnimationsAnimations
+    arg_pAnimationSeekAnimationsCurrentTime
+instance ToJSON PAnimationSeekAnimations where
+  toJSON p = A.object $ catMaybes [
+    ("animations" A..=) <$> Just (pAnimationSeekAnimationsAnimations p),
+    ("currentTime" A..=) <$> Just (pAnimationSeekAnimationsCurrentTime p)
+    ]
+instance Command PAnimationSeekAnimations where
+  type CommandResponse PAnimationSeekAnimations = ()
+  commandName _ = "Animation.seekAnimations"
+  fromJSON = const . A.Success . const ()
+
+-- | Sets the paused state of a set of animations.
+
+-- | Parameters of the 'Animation.setPaused' command.
+data PAnimationSetPaused = PAnimationSetPaused
+  {
+    -- | Animations to set the pause state of.
+    pAnimationSetPausedAnimations :: [T.Text],
+    -- | Paused state to set to.
+    pAnimationSetPausedPaused :: Bool
+  }
+  deriving (Eq, Show)
+pAnimationSetPaused
+  {-
+  -- | Animations to set the pause state of.
+  -}
+  :: [T.Text]
+  {-
+  -- | Paused state to set to.
+  -}
+  -> Bool
+  -> PAnimationSetPaused
+pAnimationSetPaused
+  arg_pAnimationSetPausedAnimations
+  arg_pAnimationSetPausedPaused
+  = PAnimationSetPaused
+    arg_pAnimationSetPausedAnimations
+    arg_pAnimationSetPausedPaused
+instance ToJSON PAnimationSetPaused where
+  toJSON p = A.object $ catMaybes [
+    ("animations" A..=) <$> Just (pAnimationSetPausedAnimations p),
+    ("paused" A..=) <$> Just (pAnimationSetPausedPaused p)
+    ]
+instance Command PAnimationSetPaused where
+  type CommandResponse PAnimationSetPaused = ()
+  commandName _ = "Animation.setPaused"
+  fromJSON = const . A.Success . const ()
+
+-- | Sets the playback rate of the document timeline.
+
+-- | Parameters of the 'Animation.setPlaybackRate' command.
+data PAnimationSetPlaybackRate = PAnimationSetPlaybackRate
+  {
+    -- | Playback rate for animations on page
+    pAnimationSetPlaybackRatePlaybackRate :: Double
+  }
+  deriving (Eq, Show)
+pAnimationSetPlaybackRate
+  {-
+  -- | Playback rate for animations on page
+  -}
+  :: Double
+  -> PAnimationSetPlaybackRate
+pAnimationSetPlaybackRate
+  arg_pAnimationSetPlaybackRatePlaybackRate
+  = PAnimationSetPlaybackRate
+    arg_pAnimationSetPlaybackRatePlaybackRate
+instance ToJSON PAnimationSetPlaybackRate where
+  toJSON p = A.object $ catMaybes [
+    ("playbackRate" A..=) <$> Just (pAnimationSetPlaybackRatePlaybackRate p)
+    ]
+instance Command PAnimationSetPlaybackRate where
+  type CommandResponse PAnimationSetPlaybackRate = ()
+  commandName _ = "Animation.setPlaybackRate"
+  fromJSON = const . A.Success . const ()
+
+-- | Sets the timing of an animation node.
+
+-- | Parameters of the 'Animation.setTiming' command.
+data PAnimationSetTiming = PAnimationSetTiming
+  {
+    -- | Animation id.
+    pAnimationSetTimingAnimationId :: T.Text,
+    -- | Duration of the animation.
+    pAnimationSetTimingDuration :: Double,
+    -- | Delay of the animation.
+    pAnimationSetTimingDelay :: Double
+  }
+  deriving (Eq, Show)
+pAnimationSetTiming
+  {-
+  -- | Animation id.
+  -}
+  :: T.Text
+  {-
+  -- | Duration of the animation.
+  -}
+  -> Double
+  {-
+  -- | Delay of the animation.
+  -}
+  -> Double
+  -> PAnimationSetTiming
+pAnimationSetTiming
+  arg_pAnimationSetTimingAnimationId
+  arg_pAnimationSetTimingDuration
+  arg_pAnimationSetTimingDelay
+  = PAnimationSetTiming
+    arg_pAnimationSetTimingAnimationId
+    arg_pAnimationSetTimingDuration
+    arg_pAnimationSetTimingDelay
+instance ToJSON PAnimationSetTiming where
+  toJSON p = A.object $ catMaybes [
+    ("animationId" A..=) <$> Just (pAnimationSetTimingAnimationId p),
+    ("duration" A..=) <$> Just (pAnimationSetTimingDuration p),
+    ("delay" A..=) <$> Just (pAnimationSetTimingDelay p)
+    ]
+instance Command PAnimationSetTiming where
+  type CommandResponse PAnimationSetTiming = ()
+  commandName _ = "Animation.setTiming"
+  fromJSON = const . A.Success . const ()
+
diff --git a/src/CDP/Domains/Audits.hs b/src/CDP/Domains/Audits.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains/Audits.hs
@@ -0,0 +1,1318 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+
+
+{- |
+= Audits
+
+Audits domain allows investigation of page violations and possible improvements.
+-}
+
+
+module CDP.Domains.Audits (module CDP.Domains.Audits) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+
+import CDP.Domains.DOMPageNetworkEmulationSecurity as DOMPageNetworkEmulationSecurity
+import CDP.Domains.Runtime as Runtime
+
+
+-- | Type 'Audits.AffectedCookie'.
+--   Information about a cookie that is affected by an inspector issue.
+data AuditsAffectedCookie = AuditsAffectedCookie
+  {
+    -- | The following three properties uniquely identify a cookie
+    auditsAffectedCookieName :: T.Text,
+    auditsAffectedCookiePath :: T.Text,
+    auditsAffectedCookieDomain :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON AuditsAffectedCookie where
+  parseJSON = A.withObject "AuditsAffectedCookie" $ \o -> AuditsAffectedCookie
+    <$> o A..: "name"
+    <*> o A..: "path"
+    <*> o A..: "domain"
+instance ToJSON AuditsAffectedCookie where
+  toJSON p = A.object $ catMaybes [
+    ("name" A..=) <$> Just (auditsAffectedCookieName p),
+    ("path" A..=) <$> Just (auditsAffectedCookiePath p),
+    ("domain" A..=) <$> Just (auditsAffectedCookieDomain p)
+    ]
+
+-- | Type 'Audits.AffectedRequest'.
+--   Information about a request that is affected by an inspector issue.
+data AuditsAffectedRequest = AuditsAffectedRequest
+  {
+    -- | The unique request id.
+    auditsAffectedRequestRequestId :: DOMPageNetworkEmulationSecurity.NetworkRequestId,
+    auditsAffectedRequestUrl :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON AuditsAffectedRequest where
+  parseJSON = A.withObject "AuditsAffectedRequest" $ \o -> AuditsAffectedRequest
+    <$> o A..: "requestId"
+    <*> o A..:? "url"
+instance ToJSON AuditsAffectedRequest where
+  toJSON p = A.object $ catMaybes [
+    ("requestId" A..=) <$> Just (auditsAffectedRequestRequestId p),
+    ("url" A..=) <$> (auditsAffectedRequestUrl p)
+    ]
+
+-- | Type 'Audits.AffectedFrame'.
+--   Information about the frame affected by an inspector issue.
+data AuditsAffectedFrame = AuditsAffectedFrame
+  {
+    auditsAffectedFrameFrameId :: DOMPageNetworkEmulationSecurity.PageFrameId
+  }
+  deriving (Eq, Show)
+instance FromJSON AuditsAffectedFrame where
+  parseJSON = A.withObject "AuditsAffectedFrame" $ \o -> AuditsAffectedFrame
+    <$> o A..: "frameId"
+instance ToJSON AuditsAffectedFrame where
+  toJSON p = A.object $ catMaybes [
+    ("frameId" A..=) <$> Just (auditsAffectedFrameFrameId p)
+    ]
+
+-- | Type 'Audits.CookieExclusionReason'.
+data AuditsCookieExclusionReason = AuditsCookieExclusionReasonExcludeSameSiteUnspecifiedTreatedAsLax | AuditsCookieExclusionReasonExcludeSameSiteNoneInsecure | AuditsCookieExclusionReasonExcludeSameSiteLax | AuditsCookieExclusionReasonExcludeSameSiteStrict | AuditsCookieExclusionReasonExcludeInvalidSameParty | AuditsCookieExclusionReasonExcludeSamePartyCrossPartyContext | AuditsCookieExclusionReasonExcludeDomainNonASCII
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON AuditsCookieExclusionReason where
+  parseJSON = A.withText "AuditsCookieExclusionReason" $ \v -> case v of
+    "ExcludeSameSiteUnspecifiedTreatedAsLax" -> pure AuditsCookieExclusionReasonExcludeSameSiteUnspecifiedTreatedAsLax
+    "ExcludeSameSiteNoneInsecure" -> pure AuditsCookieExclusionReasonExcludeSameSiteNoneInsecure
+    "ExcludeSameSiteLax" -> pure AuditsCookieExclusionReasonExcludeSameSiteLax
+    "ExcludeSameSiteStrict" -> pure AuditsCookieExclusionReasonExcludeSameSiteStrict
+    "ExcludeInvalidSameParty" -> pure AuditsCookieExclusionReasonExcludeInvalidSameParty
+    "ExcludeSamePartyCrossPartyContext" -> pure AuditsCookieExclusionReasonExcludeSamePartyCrossPartyContext
+    "ExcludeDomainNonASCII" -> pure AuditsCookieExclusionReasonExcludeDomainNonASCII
+    "_" -> fail "failed to parse AuditsCookieExclusionReason"
+instance ToJSON AuditsCookieExclusionReason where
+  toJSON v = A.String $ case v of
+    AuditsCookieExclusionReasonExcludeSameSiteUnspecifiedTreatedAsLax -> "ExcludeSameSiteUnspecifiedTreatedAsLax"
+    AuditsCookieExclusionReasonExcludeSameSiteNoneInsecure -> "ExcludeSameSiteNoneInsecure"
+    AuditsCookieExclusionReasonExcludeSameSiteLax -> "ExcludeSameSiteLax"
+    AuditsCookieExclusionReasonExcludeSameSiteStrict -> "ExcludeSameSiteStrict"
+    AuditsCookieExclusionReasonExcludeInvalidSameParty -> "ExcludeInvalidSameParty"
+    AuditsCookieExclusionReasonExcludeSamePartyCrossPartyContext -> "ExcludeSamePartyCrossPartyContext"
+    AuditsCookieExclusionReasonExcludeDomainNonASCII -> "ExcludeDomainNonASCII"
+
+-- | Type 'Audits.CookieWarningReason'.
+data AuditsCookieWarningReason = AuditsCookieWarningReasonWarnSameSiteUnspecifiedCrossSiteContext | AuditsCookieWarningReasonWarnSameSiteNoneInsecure | AuditsCookieWarningReasonWarnSameSiteUnspecifiedLaxAllowUnsafe | AuditsCookieWarningReasonWarnSameSiteStrictLaxDowngradeStrict | AuditsCookieWarningReasonWarnSameSiteStrictCrossDowngradeStrict | AuditsCookieWarningReasonWarnSameSiteStrictCrossDowngradeLax | AuditsCookieWarningReasonWarnSameSiteLaxCrossDowngradeStrict | AuditsCookieWarningReasonWarnSameSiteLaxCrossDowngradeLax | AuditsCookieWarningReasonWarnAttributeValueExceedsMaxSize | AuditsCookieWarningReasonWarnDomainNonASCII
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON AuditsCookieWarningReason where
+  parseJSON = A.withText "AuditsCookieWarningReason" $ \v -> case v of
+    "WarnSameSiteUnspecifiedCrossSiteContext" -> pure AuditsCookieWarningReasonWarnSameSiteUnspecifiedCrossSiteContext
+    "WarnSameSiteNoneInsecure" -> pure AuditsCookieWarningReasonWarnSameSiteNoneInsecure
+    "WarnSameSiteUnspecifiedLaxAllowUnsafe" -> pure AuditsCookieWarningReasonWarnSameSiteUnspecifiedLaxAllowUnsafe
+    "WarnSameSiteStrictLaxDowngradeStrict" -> pure AuditsCookieWarningReasonWarnSameSiteStrictLaxDowngradeStrict
+    "WarnSameSiteStrictCrossDowngradeStrict" -> pure AuditsCookieWarningReasonWarnSameSiteStrictCrossDowngradeStrict
+    "WarnSameSiteStrictCrossDowngradeLax" -> pure AuditsCookieWarningReasonWarnSameSiteStrictCrossDowngradeLax
+    "WarnSameSiteLaxCrossDowngradeStrict" -> pure AuditsCookieWarningReasonWarnSameSiteLaxCrossDowngradeStrict
+    "WarnSameSiteLaxCrossDowngradeLax" -> pure AuditsCookieWarningReasonWarnSameSiteLaxCrossDowngradeLax
+    "WarnAttributeValueExceedsMaxSize" -> pure AuditsCookieWarningReasonWarnAttributeValueExceedsMaxSize
+    "WarnDomainNonASCII" -> pure AuditsCookieWarningReasonWarnDomainNonASCII
+    "_" -> fail "failed to parse AuditsCookieWarningReason"
+instance ToJSON AuditsCookieWarningReason where
+  toJSON v = A.String $ case v of
+    AuditsCookieWarningReasonWarnSameSiteUnspecifiedCrossSiteContext -> "WarnSameSiteUnspecifiedCrossSiteContext"
+    AuditsCookieWarningReasonWarnSameSiteNoneInsecure -> "WarnSameSiteNoneInsecure"
+    AuditsCookieWarningReasonWarnSameSiteUnspecifiedLaxAllowUnsafe -> "WarnSameSiteUnspecifiedLaxAllowUnsafe"
+    AuditsCookieWarningReasonWarnSameSiteStrictLaxDowngradeStrict -> "WarnSameSiteStrictLaxDowngradeStrict"
+    AuditsCookieWarningReasonWarnSameSiteStrictCrossDowngradeStrict -> "WarnSameSiteStrictCrossDowngradeStrict"
+    AuditsCookieWarningReasonWarnSameSiteStrictCrossDowngradeLax -> "WarnSameSiteStrictCrossDowngradeLax"
+    AuditsCookieWarningReasonWarnSameSiteLaxCrossDowngradeStrict -> "WarnSameSiteLaxCrossDowngradeStrict"
+    AuditsCookieWarningReasonWarnSameSiteLaxCrossDowngradeLax -> "WarnSameSiteLaxCrossDowngradeLax"
+    AuditsCookieWarningReasonWarnAttributeValueExceedsMaxSize -> "WarnAttributeValueExceedsMaxSize"
+    AuditsCookieWarningReasonWarnDomainNonASCII -> "WarnDomainNonASCII"
+
+-- | Type 'Audits.CookieOperation'.
+data AuditsCookieOperation = AuditsCookieOperationSetCookie | AuditsCookieOperationReadCookie
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON AuditsCookieOperation where
+  parseJSON = A.withText "AuditsCookieOperation" $ \v -> case v of
+    "SetCookie" -> pure AuditsCookieOperationSetCookie
+    "ReadCookie" -> pure AuditsCookieOperationReadCookie
+    "_" -> fail "failed to parse AuditsCookieOperation"
+instance ToJSON AuditsCookieOperation where
+  toJSON v = A.String $ case v of
+    AuditsCookieOperationSetCookie -> "SetCookie"
+    AuditsCookieOperationReadCookie -> "ReadCookie"
+
+-- | Type 'Audits.CookieIssueDetails'.
+--   This information is currently necessary, as the front-end has a difficult
+--   time finding a specific cookie. With this, we can convey specific error
+--   information without the cookie.
+data AuditsCookieIssueDetails = AuditsCookieIssueDetails
+  {
+    -- | If AffectedCookie is not set then rawCookieLine contains the raw
+    --   Set-Cookie header string. This hints at a problem where the
+    --   cookie line is syntactically or semantically malformed in a way
+    --   that no valid cookie could be created.
+    auditsCookieIssueDetailsCookie :: Maybe AuditsAffectedCookie,
+    auditsCookieIssueDetailsRawCookieLine :: Maybe T.Text,
+    auditsCookieIssueDetailsCookieWarningReasons :: [AuditsCookieWarningReason],
+    auditsCookieIssueDetailsCookieExclusionReasons :: [AuditsCookieExclusionReason],
+    -- | Optionally identifies the site-for-cookies and the cookie url, which
+    --   may be used by the front-end as additional context.
+    auditsCookieIssueDetailsOperation :: AuditsCookieOperation,
+    auditsCookieIssueDetailsSiteForCookies :: Maybe T.Text,
+    auditsCookieIssueDetailsCookieUrl :: Maybe T.Text,
+    auditsCookieIssueDetailsRequest :: Maybe AuditsAffectedRequest
+  }
+  deriving (Eq, Show)
+instance FromJSON AuditsCookieIssueDetails where
+  parseJSON = A.withObject "AuditsCookieIssueDetails" $ \o -> AuditsCookieIssueDetails
+    <$> o A..:? "cookie"
+    <*> o A..:? "rawCookieLine"
+    <*> o A..: "cookieWarningReasons"
+    <*> o A..: "cookieExclusionReasons"
+    <*> o A..: "operation"
+    <*> o A..:? "siteForCookies"
+    <*> o A..:? "cookieUrl"
+    <*> o A..:? "request"
+instance ToJSON AuditsCookieIssueDetails where
+  toJSON p = A.object $ catMaybes [
+    ("cookie" A..=) <$> (auditsCookieIssueDetailsCookie p),
+    ("rawCookieLine" A..=) <$> (auditsCookieIssueDetailsRawCookieLine p),
+    ("cookieWarningReasons" A..=) <$> Just (auditsCookieIssueDetailsCookieWarningReasons p),
+    ("cookieExclusionReasons" A..=) <$> Just (auditsCookieIssueDetailsCookieExclusionReasons p),
+    ("operation" A..=) <$> Just (auditsCookieIssueDetailsOperation p),
+    ("siteForCookies" A..=) <$> (auditsCookieIssueDetailsSiteForCookies p),
+    ("cookieUrl" A..=) <$> (auditsCookieIssueDetailsCookieUrl p),
+    ("request" A..=) <$> (auditsCookieIssueDetailsRequest p)
+    ]
+
+-- | Type 'Audits.MixedContentResolutionStatus'.
+data AuditsMixedContentResolutionStatus = AuditsMixedContentResolutionStatusMixedContentBlocked | AuditsMixedContentResolutionStatusMixedContentAutomaticallyUpgraded | AuditsMixedContentResolutionStatusMixedContentWarning
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON AuditsMixedContentResolutionStatus where
+  parseJSON = A.withText "AuditsMixedContentResolutionStatus" $ \v -> case v of
+    "MixedContentBlocked" -> pure AuditsMixedContentResolutionStatusMixedContentBlocked
+    "MixedContentAutomaticallyUpgraded" -> pure AuditsMixedContentResolutionStatusMixedContentAutomaticallyUpgraded
+    "MixedContentWarning" -> pure AuditsMixedContentResolutionStatusMixedContentWarning
+    "_" -> fail "failed to parse AuditsMixedContentResolutionStatus"
+instance ToJSON AuditsMixedContentResolutionStatus where
+  toJSON v = A.String $ case v of
+    AuditsMixedContentResolutionStatusMixedContentBlocked -> "MixedContentBlocked"
+    AuditsMixedContentResolutionStatusMixedContentAutomaticallyUpgraded -> "MixedContentAutomaticallyUpgraded"
+    AuditsMixedContentResolutionStatusMixedContentWarning -> "MixedContentWarning"
+
+-- | Type 'Audits.MixedContentResourceType'.
+data AuditsMixedContentResourceType = AuditsMixedContentResourceTypeAttributionSrc | AuditsMixedContentResourceTypeAudio | AuditsMixedContentResourceTypeBeacon | AuditsMixedContentResourceTypeCSPReport | AuditsMixedContentResourceTypeDownload | AuditsMixedContentResourceTypeEventSource | AuditsMixedContentResourceTypeFavicon | AuditsMixedContentResourceTypeFont | AuditsMixedContentResourceTypeForm | AuditsMixedContentResourceTypeFrame | AuditsMixedContentResourceTypeImage | AuditsMixedContentResourceTypeImport | AuditsMixedContentResourceTypeManifest | AuditsMixedContentResourceTypePing | AuditsMixedContentResourceTypePluginData | AuditsMixedContentResourceTypePluginResource | AuditsMixedContentResourceTypePrefetch | AuditsMixedContentResourceTypeResource | AuditsMixedContentResourceTypeScript | AuditsMixedContentResourceTypeServiceWorker | AuditsMixedContentResourceTypeSharedWorker | AuditsMixedContentResourceTypeStylesheet | AuditsMixedContentResourceTypeTrack | AuditsMixedContentResourceTypeVideo | AuditsMixedContentResourceTypeWorker | AuditsMixedContentResourceTypeXMLHttpRequest | AuditsMixedContentResourceTypeXSLT
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON AuditsMixedContentResourceType where
+  parseJSON = A.withText "AuditsMixedContentResourceType" $ \v -> case v of
+    "AttributionSrc" -> pure AuditsMixedContentResourceTypeAttributionSrc
+    "Audio" -> pure AuditsMixedContentResourceTypeAudio
+    "Beacon" -> pure AuditsMixedContentResourceTypeBeacon
+    "CSPReport" -> pure AuditsMixedContentResourceTypeCSPReport
+    "Download" -> pure AuditsMixedContentResourceTypeDownload
+    "EventSource" -> pure AuditsMixedContentResourceTypeEventSource
+    "Favicon" -> pure AuditsMixedContentResourceTypeFavicon
+    "Font" -> pure AuditsMixedContentResourceTypeFont
+    "Form" -> pure AuditsMixedContentResourceTypeForm
+    "Frame" -> pure AuditsMixedContentResourceTypeFrame
+    "Image" -> pure AuditsMixedContentResourceTypeImage
+    "Import" -> pure AuditsMixedContentResourceTypeImport
+    "Manifest" -> pure AuditsMixedContentResourceTypeManifest
+    "Ping" -> pure AuditsMixedContentResourceTypePing
+    "PluginData" -> pure AuditsMixedContentResourceTypePluginData
+    "PluginResource" -> pure AuditsMixedContentResourceTypePluginResource
+    "Prefetch" -> pure AuditsMixedContentResourceTypePrefetch
+    "Resource" -> pure AuditsMixedContentResourceTypeResource
+    "Script" -> pure AuditsMixedContentResourceTypeScript
+    "ServiceWorker" -> pure AuditsMixedContentResourceTypeServiceWorker
+    "SharedWorker" -> pure AuditsMixedContentResourceTypeSharedWorker
+    "Stylesheet" -> pure AuditsMixedContentResourceTypeStylesheet
+    "Track" -> pure AuditsMixedContentResourceTypeTrack
+    "Video" -> pure AuditsMixedContentResourceTypeVideo
+    "Worker" -> pure AuditsMixedContentResourceTypeWorker
+    "XMLHttpRequest" -> pure AuditsMixedContentResourceTypeXMLHttpRequest
+    "XSLT" -> pure AuditsMixedContentResourceTypeXSLT
+    "_" -> fail "failed to parse AuditsMixedContentResourceType"
+instance ToJSON AuditsMixedContentResourceType where
+  toJSON v = A.String $ case v of
+    AuditsMixedContentResourceTypeAttributionSrc -> "AttributionSrc"
+    AuditsMixedContentResourceTypeAudio -> "Audio"
+    AuditsMixedContentResourceTypeBeacon -> "Beacon"
+    AuditsMixedContentResourceTypeCSPReport -> "CSPReport"
+    AuditsMixedContentResourceTypeDownload -> "Download"
+    AuditsMixedContentResourceTypeEventSource -> "EventSource"
+    AuditsMixedContentResourceTypeFavicon -> "Favicon"
+    AuditsMixedContentResourceTypeFont -> "Font"
+    AuditsMixedContentResourceTypeForm -> "Form"
+    AuditsMixedContentResourceTypeFrame -> "Frame"
+    AuditsMixedContentResourceTypeImage -> "Image"
+    AuditsMixedContentResourceTypeImport -> "Import"
+    AuditsMixedContentResourceTypeManifest -> "Manifest"
+    AuditsMixedContentResourceTypePing -> "Ping"
+    AuditsMixedContentResourceTypePluginData -> "PluginData"
+    AuditsMixedContentResourceTypePluginResource -> "PluginResource"
+    AuditsMixedContentResourceTypePrefetch -> "Prefetch"
+    AuditsMixedContentResourceTypeResource -> "Resource"
+    AuditsMixedContentResourceTypeScript -> "Script"
+    AuditsMixedContentResourceTypeServiceWorker -> "ServiceWorker"
+    AuditsMixedContentResourceTypeSharedWorker -> "SharedWorker"
+    AuditsMixedContentResourceTypeStylesheet -> "Stylesheet"
+    AuditsMixedContentResourceTypeTrack -> "Track"
+    AuditsMixedContentResourceTypeVideo -> "Video"
+    AuditsMixedContentResourceTypeWorker -> "Worker"
+    AuditsMixedContentResourceTypeXMLHttpRequest -> "XMLHttpRequest"
+    AuditsMixedContentResourceTypeXSLT -> "XSLT"
+
+-- | Type 'Audits.MixedContentIssueDetails'.
+data AuditsMixedContentIssueDetails = AuditsMixedContentIssueDetails
+  {
+    -- | The type of resource causing the mixed content issue (css, js, iframe,
+    --   form,...). Marked as optional because it is mapped to from
+    --   blink::mojom::RequestContextType, which will be replaced
+    --   by network::mojom::RequestDestination
+    auditsMixedContentIssueDetailsResourceType :: Maybe AuditsMixedContentResourceType,
+    -- | The way the mixed content issue is being resolved.
+    auditsMixedContentIssueDetailsResolutionStatus :: AuditsMixedContentResolutionStatus,
+    -- | The unsafe http url causing the mixed content issue.
+    auditsMixedContentIssueDetailsInsecureURL :: T.Text,
+    -- | The url responsible for the call to an unsafe url.
+    auditsMixedContentIssueDetailsMainResourceURL :: T.Text,
+    -- | The mixed content request.
+    --   Does not always exist (e.g. for unsafe form submission urls).
+    auditsMixedContentIssueDetailsRequest :: Maybe AuditsAffectedRequest,
+    -- | Optional because not every mixed content issue is necessarily linked to a frame.
+    auditsMixedContentIssueDetailsFrame :: Maybe AuditsAffectedFrame
+  }
+  deriving (Eq, Show)
+instance FromJSON AuditsMixedContentIssueDetails where
+  parseJSON = A.withObject "AuditsMixedContentIssueDetails" $ \o -> AuditsMixedContentIssueDetails
+    <$> o A..:? "resourceType"
+    <*> o A..: "resolutionStatus"
+    <*> o A..: "insecureURL"
+    <*> o A..: "mainResourceURL"
+    <*> o A..:? "request"
+    <*> o A..:? "frame"
+instance ToJSON AuditsMixedContentIssueDetails where
+  toJSON p = A.object $ catMaybes [
+    ("resourceType" A..=) <$> (auditsMixedContentIssueDetailsResourceType p),
+    ("resolutionStatus" A..=) <$> Just (auditsMixedContentIssueDetailsResolutionStatus p),
+    ("insecureURL" A..=) <$> Just (auditsMixedContentIssueDetailsInsecureURL p),
+    ("mainResourceURL" A..=) <$> Just (auditsMixedContentIssueDetailsMainResourceURL p),
+    ("request" A..=) <$> (auditsMixedContentIssueDetailsRequest p),
+    ("frame" A..=) <$> (auditsMixedContentIssueDetailsFrame p)
+    ]
+
+-- | Type 'Audits.BlockedByResponseReason'.
+--   Enum indicating the reason a response has been blocked. These reasons are
+--   refinements of the net error BLOCKED_BY_RESPONSE.
+data AuditsBlockedByResponseReason = AuditsBlockedByResponseReasonCoepFrameResourceNeedsCoepHeader | AuditsBlockedByResponseReasonCoopSandboxedIFrameCannotNavigateToCoopPage | AuditsBlockedByResponseReasonCorpNotSameOrigin | AuditsBlockedByResponseReasonCorpNotSameOriginAfterDefaultedToSameOriginByCoep | AuditsBlockedByResponseReasonCorpNotSameSite
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON AuditsBlockedByResponseReason where
+  parseJSON = A.withText "AuditsBlockedByResponseReason" $ \v -> case v of
+    "CoepFrameResourceNeedsCoepHeader" -> pure AuditsBlockedByResponseReasonCoepFrameResourceNeedsCoepHeader
+    "CoopSandboxedIFrameCannotNavigateToCoopPage" -> pure AuditsBlockedByResponseReasonCoopSandboxedIFrameCannotNavigateToCoopPage
+    "CorpNotSameOrigin" -> pure AuditsBlockedByResponseReasonCorpNotSameOrigin
+    "CorpNotSameOriginAfterDefaultedToSameOriginByCoep" -> pure AuditsBlockedByResponseReasonCorpNotSameOriginAfterDefaultedToSameOriginByCoep
+    "CorpNotSameSite" -> pure AuditsBlockedByResponseReasonCorpNotSameSite
+    "_" -> fail "failed to parse AuditsBlockedByResponseReason"
+instance ToJSON AuditsBlockedByResponseReason where
+  toJSON v = A.String $ case v of
+    AuditsBlockedByResponseReasonCoepFrameResourceNeedsCoepHeader -> "CoepFrameResourceNeedsCoepHeader"
+    AuditsBlockedByResponseReasonCoopSandboxedIFrameCannotNavigateToCoopPage -> "CoopSandboxedIFrameCannotNavigateToCoopPage"
+    AuditsBlockedByResponseReasonCorpNotSameOrigin -> "CorpNotSameOrigin"
+    AuditsBlockedByResponseReasonCorpNotSameOriginAfterDefaultedToSameOriginByCoep -> "CorpNotSameOriginAfterDefaultedToSameOriginByCoep"
+    AuditsBlockedByResponseReasonCorpNotSameSite -> "CorpNotSameSite"
+
+-- | Type 'Audits.BlockedByResponseIssueDetails'.
+--   Details for a request that has been blocked with the BLOCKED_BY_RESPONSE
+--   code. Currently only used for COEP/COOP, but may be extended to include
+--   some CSP errors in the future.
+data AuditsBlockedByResponseIssueDetails = AuditsBlockedByResponseIssueDetails
+  {
+    auditsBlockedByResponseIssueDetailsRequest :: AuditsAffectedRequest,
+    auditsBlockedByResponseIssueDetailsParentFrame :: Maybe AuditsAffectedFrame,
+    auditsBlockedByResponseIssueDetailsBlockedFrame :: Maybe AuditsAffectedFrame,
+    auditsBlockedByResponseIssueDetailsReason :: AuditsBlockedByResponseReason
+  }
+  deriving (Eq, Show)
+instance FromJSON AuditsBlockedByResponseIssueDetails where
+  parseJSON = A.withObject "AuditsBlockedByResponseIssueDetails" $ \o -> AuditsBlockedByResponseIssueDetails
+    <$> o A..: "request"
+    <*> o A..:? "parentFrame"
+    <*> o A..:? "blockedFrame"
+    <*> o A..: "reason"
+instance ToJSON AuditsBlockedByResponseIssueDetails where
+  toJSON p = A.object $ catMaybes [
+    ("request" A..=) <$> Just (auditsBlockedByResponseIssueDetailsRequest p),
+    ("parentFrame" A..=) <$> (auditsBlockedByResponseIssueDetailsParentFrame p),
+    ("blockedFrame" A..=) <$> (auditsBlockedByResponseIssueDetailsBlockedFrame p),
+    ("reason" A..=) <$> Just (auditsBlockedByResponseIssueDetailsReason p)
+    ]
+
+-- | Type 'Audits.HeavyAdResolutionStatus'.
+data AuditsHeavyAdResolutionStatus = AuditsHeavyAdResolutionStatusHeavyAdBlocked | AuditsHeavyAdResolutionStatusHeavyAdWarning
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON AuditsHeavyAdResolutionStatus where
+  parseJSON = A.withText "AuditsHeavyAdResolutionStatus" $ \v -> case v of
+    "HeavyAdBlocked" -> pure AuditsHeavyAdResolutionStatusHeavyAdBlocked
+    "HeavyAdWarning" -> pure AuditsHeavyAdResolutionStatusHeavyAdWarning
+    "_" -> fail "failed to parse AuditsHeavyAdResolutionStatus"
+instance ToJSON AuditsHeavyAdResolutionStatus where
+  toJSON v = A.String $ case v of
+    AuditsHeavyAdResolutionStatusHeavyAdBlocked -> "HeavyAdBlocked"
+    AuditsHeavyAdResolutionStatusHeavyAdWarning -> "HeavyAdWarning"
+
+-- | Type 'Audits.HeavyAdReason'.
+data AuditsHeavyAdReason = AuditsHeavyAdReasonNetworkTotalLimit | AuditsHeavyAdReasonCpuTotalLimit | AuditsHeavyAdReasonCpuPeakLimit
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON AuditsHeavyAdReason where
+  parseJSON = A.withText "AuditsHeavyAdReason" $ \v -> case v of
+    "NetworkTotalLimit" -> pure AuditsHeavyAdReasonNetworkTotalLimit
+    "CpuTotalLimit" -> pure AuditsHeavyAdReasonCpuTotalLimit
+    "CpuPeakLimit" -> pure AuditsHeavyAdReasonCpuPeakLimit
+    "_" -> fail "failed to parse AuditsHeavyAdReason"
+instance ToJSON AuditsHeavyAdReason where
+  toJSON v = A.String $ case v of
+    AuditsHeavyAdReasonNetworkTotalLimit -> "NetworkTotalLimit"
+    AuditsHeavyAdReasonCpuTotalLimit -> "CpuTotalLimit"
+    AuditsHeavyAdReasonCpuPeakLimit -> "CpuPeakLimit"
+
+-- | Type 'Audits.HeavyAdIssueDetails'.
+data AuditsHeavyAdIssueDetails = AuditsHeavyAdIssueDetails
+  {
+    -- | The resolution status, either blocking the content or warning.
+    auditsHeavyAdIssueDetailsResolution :: AuditsHeavyAdResolutionStatus,
+    -- | The reason the ad was blocked, total network or cpu or peak cpu.
+    auditsHeavyAdIssueDetailsReason :: AuditsHeavyAdReason,
+    -- | The frame that was blocked.
+    auditsHeavyAdIssueDetailsFrame :: AuditsAffectedFrame
+  }
+  deriving (Eq, Show)
+instance FromJSON AuditsHeavyAdIssueDetails where
+  parseJSON = A.withObject "AuditsHeavyAdIssueDetails" $ \o -> AuditsHeavyAdIssueDetails
+    <$> o A..: "resolution"
+    <*> o A..: "reason"
+    <*> o A..: "frame"
+instance ToJSON AuditsHeavyAdIssueDetails where
+  toJSON p = A.object $ catMaybes [
+    ("resolution" A..=) <$> Just (auditsHeavyAdIssueDetailsResolution p),
+    ("reason" A..=) <$> Just (auditsHeavyAdIssueDetailsReason p),
+    ("frame" A..=) <$> Just (auditsHeavyAdIssueDetailsFrame p)
+    ]
+
+-- | Type 'Audits.ContentSecurityPolicyViolationType'.
+data AuditsContentSecurityPolicyViolationType = AuditsContentSecurityPolicyViolationTypeKInlineViolation | AuditsContentSecurityPolicyViolationTypeKEvalViolation | AuditsContentSecurityPolicyViolationTypeKURLViolation | AuditsContentSecurityPolicyViolationTypeKTrustedTypesSinkViolation | AuditsContentSecurityPolicyViolationTypeKTrustedTypesPolicyViolation | AuditsContentSecurityPolicyViolationTypeKWasmEvalViolation
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON AuditsContentSecurityPolicyViolationType where
+  parseJSON = A.withText "AuditsContentSecurityPolicyViolationType" $ \v -> case v of
+    "kInlineViolation" -> pure AuditsContentSecurityPolicyViolationTypeKInlineViolation
+    "kEvalViolation" -> pure AuditsContentSecurityPolicyViolationTypeKEvalViolation
+    "kURLViolation" -> pure AuditsContentSecurityPolicyViolationTypeKURLViolation
+    "kTrustedTypesSinkViolation" -> pure AuditsContentSecurityPolicyViolationTypeKTrustedTypesSinkViolation
+    "kTrustedTypesPolicyViolation" -> pure AuditsContentSecurityPolicyViolationTypeKTrustedTypesPolicyViolation
+    "kWasmEvalViolation" -> pure AuditsContentSecurityPolicyViolationTypeKWasmEvalViolation
+    "_" -> fail "failed to parse AuditsContentSecurityPolicyViolationType"
+instance ToJSON AuditsContentSecurityPolicyViolationType where
+  toJSON v = A.String $ case v of
+    AuditsContentSecurityPolicyViolationTypeKInlineViolation -> "kInlineViolation"
+    AuditsContentSecurityPolicyViolationTypeKEvalViolation -> "kEvalViolation"
+    AuditsContentSecurityPolicyViolationTypeKURLViolation -> "kURLViolation"
+    AuditsContentSecurityPolicyViolationTypeKTrustedTypesSinkViolation -> "kTrustedTypesSinkViolation"
+    AuditsContentSecurityPolicyViolationTypeKTrustedTypesPolicyViolation -> "kTrustedTypesPolicyViolation"
+    AuditsContentSecurityPolicyViolationTypeKWasmEvalViolation -> "kWasmEvalViolation"
+
+-- | Type 'Audits.SourceCodeLocation'.
+data AuditsSourceCodeLocation = AuditsSourceCodeLocation
+  {
+    auditsSourceCodeLocationScriptId :: Maybe Runtime.RuntimeScriptId,
+    auditsSourceCodeLocationUrl :: T.Text,
+    auditsSourceCodeLocationLineNumber :: Int,
+    auditsSourceCodeLocationColumnNumber :: Int
+  }
+  deriving (Eq, Show)
+instance FromJSON AuditsSourceCodeLocation where
+  parseJSON = A.withObject "AuditsSourceCodeLocation" $ \o -> AuditsSourceCodeLocation
+    <$> o A..:? "scriptId"
+    <*> o A..: "url"
+    <*> o A..: "lineNumber"
+    <*> o A..: "columnNumber"
+instance ToJSON AuditsSourceCodeLocation where
+  toJSON p = A.object $ catMaybes [
+    ("scriptId" A..=) <$> (auditsSourceCodeLocationScriptId p),
+    ("url" A..=) <$> Just (auditsSourceCodeLocationUrl p),
+    ("lineNumber" A..=) <$> Just (auditsSourceCodeLocationLineNumber p),
+    ("columnNumber" A..=) <$> Just (auditsSourceCodeLocationColumnNumber p)
+    ]
+
+-- | Type 'Audits.ContentSecurityPolicyIssueDetails'.
+data AuditsContentSecurityPolicyIssueDetails = AuditsContentSecurityPolicyIssueDetails
+  {
+    -- | The url not included in allowed sources.
+    auditsContentSecurityPolicyIssueDetailsBlockedURL :: Maybe T.Text,
+    -- | Specific directive that is violated, causing the CSP issue.
+    auditsContentSecurityPolicyIssueDetailsViolatedDirective :: T.Text,
+    auditsContentSecurityPolicyIssueDetailsIsReportOnly :: Bool,
+    auditsContentSecurityPolicyIssueDetailsContentSecurityPolicyViolationType :: AuditsContentSecurityPolicyViolationType,
+    auditsContentSecurityPolicyIssueDetailsFrameAncestor :: Maybe AuditsAffectedFrame,
+    auditsContentSecurityPolicyIssueDetailsSourceCodeLocation :: Maybe AuditsSourceCodeLocation,
+    auditsContentSecurityPolicyIssueDetailsViolatingNodeId :: Maybe DOMPageNetworkEmulationSecurity.DOMBackendNodeId
+  }
+  deriving (Eq, Show)
+instance FromJSON AuditsContentSecurityPolicyIssueDetails where
+  parseJSON = A.withObject "AuditsContentSecurityPolicyIssueDetails" $ \o -> AuditsContentSecurityPolicyIssueDetails
+    <$> o A..:? "blockedURL"
+    <*> o A..: "violatedDirective"
+    <*> o A..: "isReportOnly"
+    <*> o A..: "contentSecurityPolicyViolationType"
+    <*> o A..:? "frameAncestor"
+    <*> o A..:? "sourceCodeLocation"
+    <*> o A..:? "violatingNodeId"
+instance ToJSON AuditsContentSecurityPolicyIssueDetails where
+  toJSON p = A.object $ catMaybes [
+    ("blockedURL" A..=) <$> (auditsContentSecurityPolicyIssueDetailsBlockedURL p),
+    ("violatedDirective" A..=) <$> Just (auditsContentSecurityPolicyIssueDetailsViolatedDirective p),
+    ("isReportOnly" A..=) <$> Just (auditsContentSecurityPolicyIssueDetailsIsReportOnly p),
+    ("contentSecurityPolicyViolationType" A..=) <$> Just (auditsContentSecurityPolicyIssueDetailsContentSecurityPolicyViolationType p),
+    ("frameAncestor" A..=) <$> (auditsContentSecurityPolicyIssueDetailsFrameAncestor p),
+    ("sourceCodeLocation" A..=) <$> (auditsContentSecurityPolicyIssueDetailsSourceCodeLocation p),
+    ("violatingNodeId" A..=) <$> (auditsContentSecurityPolicyIssueDetailsViolatingNodeId p)
+    ]
+
+-- | Type 'Audits.SharedArrayBufferIssueType'.
+data AuditsSharedArrayBufferIssueType = AuditsSharedArrayBufferIssueTypeTransferIssue | AuditsSharedArrayBufferIssueTypeCreationIssue
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON AuditsSharedArrayBufferIssueType where
+  parseJSON = A.withText "AuditsSharedArrayBufferIssueType" $ \v -> case v of
+    "TransferIssue" -> pure AuditsSharedArrayBufferIssueTypeTransferIssue
+    "CreationIssue" -> pure AuditsSharedArrayBufferIssueTypeCreationIssue
+    "_" -> fail "failed to parse AuditsSharedArrayBufferIssueType"
+instance ToJSON AuditsSharedArrayBufferIssueType where
+  toJSON v = A.String $ case v of
+    AuditsSharedArrayBufferIssueTypeTransferIssue -> "TransferIssue"
+    AuditsSharedArrayBufferIssueTypeCreationIssue -> "CreationIssue"
+
+-- | Type 'Audits.SharedArrayBufferIssueDetails'.
+--   Details for a issue arising from an SAB being instantiated in, or
+--   transferred to a context that is not cross-origin isolated.
+data AuditsSharedArrayBufferIssueDetails = AuditsSharedArrayBufferIssueDetails
+  {
+    auditsSharedArrayBufferIssueDetailsSourceCodeLocation :: AuditsSourceCodeLocation,
+    auditsSharedArrayBufferIssueDetailsIsWarning :: Bool,
+    auditsSharedArrayBufferIssueDetailsType :: AuditsSharedArrayBufferIssueType
+  }
+  deriving (Eq, Show)
+instance FromJSON AuditsSharedArrayBufferIssueDetails where
+  parseJSON = A.withObject "AuditsSharedArrayBufferIssueDetails" $ \o -> AuditsSharedArrayBufferIssueDetails
+    <$> o A..: "sourceCodeLocation"
+    <*> o A..: "isWarning"
+    <*> o A..: "type"
+instance ToJSON AuditsSharedArrayBufferIssueDetails where
+  toJSON p = A.object $ catMaybes [
+    ("sourceCodeLocation" A..=) <$> Just (auditsSharedArrayBufferIssueDetailsSourceCodeLocation p),
+    ("isWarning" A..=) <$> Just (auditsSharedArrayBufferIssueDetailsIsWarning p),
+    ("type" A..=) <$> Just (auditsSharedArrayBufferIssueDetailsType p)
+    ]
+
+-- | Type 'Audits.TwaQualityEnforcementViolationType'.
+data AuditsTwaQualityEnforcementViolationType = AuditsTwaQualityEnforcementViolationTypeKHttpError | AuditsTwaQualityEnforcementViolationTypeKUnavailableOffline | AuditsTwaQualityEnforcementViolationTypeKDigitalAssetLinks
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON AuditsTwaQualityEnforcementViolationType where
+  parseJSON = A.withText "AuditsTwaQualityEnforcementViolationType" $ \v -> case v of
+    "kHttpError" -> pure AuditsTwaQualityEnforcementViolationTypeKHttpError
+    "kUnavailableOffline" -> pure AuditsTwaQualityEnforcementViolationTypeKUnavailableOffline
+    "kDigitalAssetLinks" -> pure AuditsTwaQualityEnforcementViolationTypeKDigitalAssetLinks
+    "_" -> fail "failed to parse AuditsTwaQualityEnforcementViolationType"
+instance ToJSON AuditsTwaQualityEnforcementViolationType where
+  toJSON v = A.String $ case v of
+    AuditsTwaQualityEnforcementViolationTypeKHttpError -> "kHttpError"
+    AuditsTwaQualityEnforcementViolationTypeKUnavailableOffline -> "kUnavailableOffline"
+    AuditsTwaQualityEnforcementViolationTypeKDigitalAssetLinks -> "kDigitalAssetLinks"
+
+-- | Type 'Audits.TrustedWebActivityIssueDetails'.
+data AuditsTrustedWebActivityIssueDetails = AuditsTrustedWebActivityIssueDetails
+  {
+    -- | The url that triggers the violation.
+    auditsTrustedWebActivityIssueDetailsUrl :: T.Text,
+    auditsTrustedWebActivityIssueDetailsViolationType :: AuditsTwaQualityEnforcementViolationType,
+    auditsTrustedWebActivityIssueDetailsHttpStatusCode :: Maybe Int,
+    -- | The package name of the Trusted Web Activity client app. This field is
+    --   only used when violation type is kDigitalAssetLinks.
+    auditsTrustedWebActivityIssueDetailsPackageName :: Maybe T.Text,
+    -- | The signature of the Trusted Web Activity client app. This field is only
+    --   used when violation type is kDigitalAssetLinks.
+    auditsTrustedWebActivityIssueDetailsSignature :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON AuditsTrustedWebActivityIssueDetails where
+  parseJSON = A.withObject "AuditsTrustedWebActivityIssueDetails" $ \o -> AuditsTrustedWebActivityIssueDetails
+    <$> o A..: "url"
+    <*> o A..: "violationType"
+    <*> o A..:? "httpStatusCode"
+    <*> o A..:? "packageName"
+    <*> o A..:? "signature"
+instance ToJSON AuditsTrustedWebActivityIssueDetails where
+  toJSON p = A.object $ catMaybes [
+    ("url" A..=) <$> Just (auditsTrustedWebActivityIssueDetailsUrl p),
+    ("violationType" A..=) <$> Just (auditsTrustedWebActivityIssueDetailsViolationType p),
+    ("httpStatusCode" A..=) <$> (auditsTrustedWebActivityIssueDetailsHttpStatusCode p),
+    ("packageName" A..=) <$> (auditsTrustedWebActivityIssueDetailsPackageName p),
+    ("signature" A..=) <$> (auditsTrustedWebActivityIssueDetailsSignature p)
+    ]
+
+-- | Type 'Audits.LowTextContrastIssueDetails'.
+data AuditsLowTextContrastIssueDetails = AuditsLowTextContrastIssueDetails
+  {
+    auditsLowTextContrastIssueDetailsViolatingNodeId :: DOMPageNetworkEmulationSecurity.DOMBackendNodeId,
+    auditsLowTextContrastIssueDetailsViolatingNodeSelector :: T.Text,
+    auditsLowTextContrastIssueDetailsContrastRatio :: Double,
+    auditsLowTextContrastIssueDetailsThresholdAA :: Double,
+    auditsLowTextContrastIssueDetailsThresholdAAA :: Double,
+    auditsLowTextContrastIssueDetailsFontSize :: T.Text,
+    auditsLowTextContrastIssueDetailsFontWeight :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON AuditsLowTextContrastIssueDetails where
+  parseJSON = A.withObject "AuditsLowTextContrastIssueDetails" $ \o -> AuditsLowTextContrastIssueDetails
+    <$> o A..: "violatingNodeId"
+    <*> o A..: "violatingNodeSelector"
+    <*> o A..: "contrastRatio"
+    <*> o A..: "thresholdAA"
+    <*> o A..: "thresholdAAA"
+    <*> o A..: "fontSize"
+    <*> o A..: "fontWeight"
+instance ToJSON AuditsLowTextContrastIssueDetails where
+  toJSON p = A.object $ catMaybes [
+    ("violatingNodeId" A..=) <$> Just (auditsLowTextContrastIssueDetailsViolatingNodeId p),
+    ("violatingNodeSelector" A..=) <$> Just (auditsLowTextContrastIssueDetailsViolatingNodeSelector p),
+    ("contrastRatio" A..=) <$> Just (auditsLowTextContrastIssueDetailsContrastRatio p),
+    ("thresholdAA" A..=) <$> Just (auditsLowTextContrastIssueDetailsThresholdAA p),
+    ("thresholdAAA" A..=) <$> Just (auditsLowTextContrastIssueDetailsThresholdAAA p),
+    ("fontSize" A..=) <$> Just (auditsLowTextContrastIssueDetailsFontSize p),
+    ("fontWeight" A..=) <$> Just (auditsLowTextContrastIssueDetailsFontWeight p)
+    ]
+
+-- | Type 'Audits.CorsIssueDetails'.
+--   Details for a CORS related issue, e.g. a warning or error related to
+--   CORS RFC1918 enforcement.
+data AuditsCorsIssueDetails = AuditsCorsIssueDetails
+  {
+    auditsCorsIssueDetailsCorsErrorStatus :: DOMPageNetworkEmulationSecurity.NetworkCorsErrorStatus,
+    auditsCorsIssueDetailsIsWarning :: Bool,
+    auditsCorsIssueDetailsRequest :: AuditsAffectedRequest,
+    auditsCorsIssueDetailsLocation :: Maybe AuditsSourceCodeLocation,
+    auditsCorsIssueDetailsInitiatorOrigin :: Maybe T.Text,
+    auditsCorsIssueDetailsResourceIPAddressSpace :: Maybe DOMPageNetworkEmulationSecurity.NetworkIPAddressSpace,
+    auditsCorsIssueDetailsClientSecurityState :: Maybe DOMPageNetworkEmulationSecurity.NetworkClientSecurityState
+  }
+  deriving (Eq, Show)
+instance FromJSON AuditsCorsIssueDetails where
+  parseJSON = A.withObject "AuditsCorsIssueDetails" $ \o -> AuditsCorsIssueDetails
+    <$> o A..: "corsErrorStatus"
+    <*> o A..: "isWarning"
+    <*> o A..: "request"
+    <*> o A..:? "location"
+    <*> o A..:? "initiatorOrigin"
+    <*> o A..:? "resourceIPAddressSpace"
+    <*> o A..:? "clientSecurityState"
+instance ToJSON AuditsCorsIssueDetails where
+  toJSON p = A.object $ catMaybes [
+    ("corsErrorStatus" A..=) <$> Just (auditsCorsIssueDetailsCorsErrorStatus p),
+    ("isWarning" A..=) <$> Just (auditsCorsIssueDetailsIsWarning p),
+    ("request" A..=) <$> Just (auditsCorsIssueDetailsRequest p),
+    ("location" A..=) <$> (auditsCorsIssueDetailsLocation p),
+    ("initiatorOrigin" A..=) <$> (auditsCorsIssueDetailsInitiatorOrigin p),
+    ("resourceIPAddressSpace" A..=) <$> (auditsCorsIssueDetailsResourceIPAddressSpace p),
+    ("clientSecurityState" A..=) <$> (auditsCorsIssueDetailsClientSecurityState p)
+    ]
+
+-- | Type 'Audits.AttributionReportingIssueType'.
+data AuditsAttributionReportingIssueType = AuditsAttributionReportingIssueTypePermissionPolicyDisabled | AuditsAttributionReportingIssueTypePermissionPolicyNotDelegated | AuditsAttributionReportingIssueTypeUntrustworthyReportingOrigin | AuditsAttributionReportingIssueTypeInsecureContext | AuditsAttributionReportingIssueTypeInvalidHeader | AuditsAttributionReportingIssueTypeInvalidRegisterTriggerHeader | AuditsAttributionReportingIssueTypeInvalidEligibleHeader | AuditsAttributionReportingIssueTypeTooManyConcurrentRequests | AuditsAttributionReportingIssueTypeSourceAndTriggerHeaders | AuditsAttributionReportingIssueTypeSourceIgnored | AuditsAttributionReportingIssueTypeTriggerIgnored
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON AuditsAttributionReportingIssueType where
+  parseJSON = A.withText "AuditsAttributionReportingIssueType" $ \v -> case v of
+    "PermissionPolicyDisabled" -> pure AuditsAttributionReportingIssueTypePermissionPolicyDisabled
+    "PermissionPolicyNotDelegated" -> pure AuditsAttributionReportingIssueTypePermissionPolicyNotDelegated
+    "UntrustworthyReportingOrigin" -> pure AuditsAttributionReportingIssueTypeUntrustworthyReportingOrigin
+    "InsecureContext" -> pure AuditsAttributionReportingIssueTypeInsecureContext
+    "InvalidHeader" -> pure AuditsAttributionReportingIssueTypeInvalidHeader
+    "InvalidRegisterTriggerHeader" -> pure AuditsAttributionReportingIssueTypeInvalidRegisterTriggerHeader
+    "InvalidEligibleHeader" -> pure AuditsAttributionReportingIssueTypeInvalidEligibleHeader
+    "TooManyConcurrentRequests" -> pure AuditsAttributionReportingIssueTypeTooManyConcurrentRequests
+    "SourceAndTriggerHeaders" -> pure AuditsAttributionReportingIssueTypeSourceAndTriggerHeaders
+    "SourceIgnored" -> pure AuditsAttributionReportingIssueTypeSourceIgnored
+    "TriggerIgnored" -> pure AuditsAttributionReportingIssueTypeTriggerIgnored
+    "_" -> fail "failed to parse AuditsAttributionReportingIssueType"
+instance ToJSON AuditsAttributionReportingIssueType where
+  toJSON v = A.String $ case v of
+    AuditsAttributionReportingIssueTypePermissionPolicyDisabled -> "PermissionPolicyDisabled"
+    AuditsAttributionReportingIssueTypePermissionPolicyNotDelegated -> "PermissionPolicyNotDelegated"
+    AuditsAttributionReportingIssueTypeUntrustworthyReportingOrigin -> "UntrustworthyReportingOrigin"
+    AuditsAttributionReportingIssueTypeInsecureContext -> "InsecureContext"
+    AuditsAttributionReportingIssueTypeInvalidHeader -> "InvalidHeader"
+    AuditsAttributionReportingIssueTypeInvalidRegisterTriggerHeader -> "InvalidRegisterTriggerHeader"
+    AuditsAttributionReportingIssueTypeInvalidEligibleHeader -> "InvalidEligibleHeader"
+    AuditsAttributionReportingIssueTypeTooManyConcurrentRequests -> "TooManyConcurrentRequests"
+    AuditsAttributionReportingIssueTypeSourceAndTriggerHeaders -> "SourceAndTriggerHeaders"
+    AuditsAttributionReportingIssueTypeSourceIgnored -> "SourceIgnored"
+    AuditsAttributionReportingIssueTypeTriggerIgnored -> "TriggerIgnored"
+
+-- | Type 'Audits.AttributionReportingIssueDetails'.
+--   Details for issues around "Attribution Reporting API" usage.
+--   Explainer: https://github.com/WICG/attribution-reporting-api
+data AuditsAttributionReportingIssueDetails = AuditsAttributionReportingIssueDetails
+  {
+    auditsAttributionReportingIssueDetailsViolationType :: AuditsAttributionReportingIssueType,
+    auditsAttributionReportingIssueDetailsRequest :: Maybe AuditsAffectedRequest,
+    auditsAttributionReportingIssueDetailsViolatingNodeId :: Maybe DOMPageNetworkEmulationSecurity.DOMBackendNodeId,
+    auditsAttributionReportingIssueDetailsInvalidParameter :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON AuditsAttributionReportingIssueDetails where
+  parseJSON = A.withObject "AuditsAttributionReportingIssueDetails" $ \o -> AuditsAttributionReportingIssueDetails
+    <$> o A..: "violationType"
+    <*> o A..:? "request"
+    <*> o A..:? "violatingNodeId"
+    <*> o A..:? "invalidParameter"
+instance ToJSON AuditsAttributionReportingIssueDetails where
+  toJSON p = A.object $ catMaybes [
+    ("violationType" A..=) <$> Just (auditsAttributionReportingIssueDetailsViolationType p),
+    ("request" A..=) <$> (auditsAttributionReportingIssueDetailsRequest p),
+    ("violatingNodeId" A..=) <$> (auditsAttributionReportingIssueDetailsViolatingNodeId p),
+    ("invalidParameter" A..=) <$> (auditsAttributionReportingIssueDetailsInvalidParameter p)
+    ]
+
+-- | Type 'Audits.QuirksModeIssueDetails'.
+--   Details for issues about documents in Quirks Mode
+--   or Limited Quirks Mode that affects page layouting.
+data AuditsQuirksModeIssueDetails = AuditsQuirksModeIssueDetails
+  {
+    -- | If false, it means the document's mode is "quirks"
+    --   instead of "limited-quirks".
+    auditsQuirksModeIssueDetailsIsLimitedQuirksMode :: Bool,
+    auditsQuirksModeIssueDetailsDocumentNodeId :: DOMPageNetworkEmulationSecurity.DOMBackendNodeId,
+    auditsQuirksModeIssueDetailsUrl :: T.Text,
+    auditsQuirksModeIssueDetailsFrameId :: DOMPageNetworkEmulationSecurity.PageFrameId,
+    auditsQuirksModeIssueDetailsLoaderId :: DOMPageNetworkEmulationSecurity.NetworkLoaderId
+  }
+  deriving (Eq, Show)
+instance FromJSON AuditsQuirksModeIssueDetails where
+  parseJSON = A.withObject "AuditsQuirksModeIssueDetails" $ \o -> AuditsQuirksModeIssueDetails
+    <$> o A..: "isLimitedQuirksMode"
+    <*> o A..: "documentNodeId"
+    <*> o A..: "url"
+    <*> o A..: "frameId"
+    <*> o A..: "loaderId"
+instance ToJSON AuditsQuirksModeIssueDetails where
+  toJSON p = A.object $ catMaybes [
+    ("isLimitedQuirksMode" A..=) <$> Just (auditsQuirksModeIssueDetailsIsLimitedQuirksMode p),
+    ("documentNodeId" A..=) <$> Just (auditsQuirksModeIssueDetailsDocumentNodeId p),
+    ("url" A..=) <$> Just (auditsQuirksModeIssueDetailsUrl p),
+    ("frameId" A..=) <$> Just (auditsQuirksModeIssueDetailsFrameId p),
+    ("loaderId" A..=) <$> Just (auditsQuirksModeIssueDetailsLoaderId p)
+    ]
+
+-- | Type 'Audits.NavigatorUserAgentIssueDetails'.
+data AuditsNavigatorUserAgentIssueDetails = AuditsNavigatorUserAgentIssueDetails
+  {
+    auditsNavigatorUserAgentIssueDetailsUrl :: T.Text,
+    auditsNavigatorUserAgentIssueDetailsLocation :: Maybe AuditsSourceCodeLocation
+  }
+  deriving (Eq, Show)
+instance FromJSON AuditsNavigatorUserAgentIssueDetails where
+  parseJSON = A.withObject "AuditsNavigatorUserAgentIssueDetails" $ \o -> AuditsNavigatorUserAgentIssueDetails
+    <$> o A..: "url"
+    <*> o A..:? "location"
+instance ToJSON AuditsNavigatorUserAgentIssueDetails where
+  toJSON p = A.object $ catMaybes [
+    ("url" A..=) <$> Just (auditsNavigatorUserAgentIssueDetailsUrl p),
+    ("location" A..=) <$> (auditsNavigatorUserAgentIssueDetailsLocation p)
+    ]
+
+-- | Type 'Audits.GenericIssueErrorType'.
+data AuditsGenericIssueErrorType = AuditsGenericIssueErrorTypeCrossOriginPortalPostMessageError
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON AuditsGenericIssueErrorType where
+  parseJSON = A.withText "AuditsGenericIssueErrorType" $ \v -> case v of
+    "CrossOriginPortalPostMessageError" -> pure AuditsGenericIssueErrorTypeCrossOriginPortalPostMessageError
+    "_" -> fail "failed to parse AuditsGenericIssueErrorType"
+instance ToJSON AuditsGenericIssueErrorType where
+  toJSON v = A.String $ case v of
+    AuditsGenericIssueErrorTypeCrossOriginPortalPostMessageError -> "CrossOriginPortalPostMessageError"
+
+-- | Type 'Audits.GenericIssueDetails'.
+--   Depending on the concrete errorType, different properties are set.
+data AuditsGenericIssueDetails = AuditsGenericIssueDetails
+  {
+    -- | Issues with the same errorType are aggregated in the frontend.
+    auditsGenericIssueDetailsErrorType :: AuditsGenericIssueErrorType,
+    auditsGenericIssueDetailsFrameId :: Maybe DOMPageNetworkEmulationSecurity.PageFrameId
+  }
+  deriving (Eq, Show)
+instance FromJSON AuditsGenericIssueDetails where
+  parseJSON = A.withObject "AuditsGenericIssueDetails" $ \o -> AuditsGenericIssueDetails
+    <$> o A..: "errorType"
+    <*> o A..:? "frameId"
+instance ToJSON AuditsGenericIssueDetails where
+  toJSON p = A.object $ catMaybes [
+    ("errorType" A..=) <$> Just (auditsGenericIssueDetailsErrorType p),
+    ("frameId" A..=) <$> (auditsGenericIssueDetailsFrameId p)
+    ]
+
+-- | Type 'Audits.DeprecationIssueType'.
+data AuditsDeprecationIssueType = AuditsDeprecationIssueTypeAuthorizationCoveredByWildcard | AuditsDeprecationIssueTypeCanRequestURLHTTPContainingNewline | AuditsDeprecationIssueTypeChromeLoadTimesConnectionInfo | AuditsDeprecationIssueTypeChromeLoadTimesFirstPaintAfterLoadTime | AuditsDeprecationIssueTypeChromeLoadTimesWasAlternateProtocolAvailable | AuditsDeprecationIssueTypeCookieWithTruncatingChar | AuditsDeprecationIssueTypeCrossOriginAccessBasedOnDocumentDomain | AuditsDeprecationIssueTypeCrossOriginWindowAlert | AuditsDeprecationIssueTypeCrossOriginWindowConfirm | AuditsDeprecationIssueTypeCSSSelectorInternalMediaControlsOverlayCastButton | AuditsDeprecationIssueTypeDeprecationExample | AuditsDeprecationIssueTypeDocumentDomainSettingWithoutOriginAgentClusterHeader | AuditsDeprecationIssueTypeEventPath | AuditsDeprecationIssueTypeExpectCTHeader | AuditsDeprecationIssueTypeGeolocationInsecureOrigin | AuditsDeprecationIssueTypeGeolocationInsecureOriginDeprecatedNotRemoved | AuditsDeprecationIssueTypeGetUserMediaInsecureOrigin | AuditsDeprecationIssueTypeHostCandidateAttributeGetter | AuditsDeprecationIssueTypeIdentityInCanMakePaymentEvent | AuditsDeprecationIssueTypeInsecurePrivateNetworkSubresourceRequest | AuditsDeprecationIssueTypeLocalCSSFileExtensionRejected | AuditsDeprecationIssueTypeMediaSourceAbortRemove | AuditsDeprecationIssueTypeMediaSourceDurationTruncatingBuffered | AuditsDeprecationIssueTypeNoSysexWebMIDIWithoutPermission | AuditsDeprecationIssueTypeNotificationInsecureOrigin | AuditsDeprecationIssueTypeNotificationPermissionRequestedIframe | AuditsDeprecationIssueTypeObsoleteWebRtcCipherSuite | AuditsDeprecationIssueTypeOpenWebDatabaseInsecureContext | AuditsDeprecationIssueTypeOverflowVisibleOnReplacedElement | AuditsDeprecationIssueTypePaymentInstruments | AuditsDeprecationIssueTypePaymentRequestCSPViolation | AuditsDeprecationIssueTypePersistentQuotaType | AuditsDeprecationIssueTypePictureSourceSrc | AuditsDeprecationIssueTypePrefixedCancelAnimationFrame | AuditsDeprecationIssueTypePrefixedRequestAnimationFrame | AuditsDeprecationIssueTypePrefixedStorageInfo | AuditsDeprecationIssueTypePrefixedVideoDisplayingFullscreen | AuditsDeprecationIssueTypePrefixedVideoEnterFullscreen | AuditsDeprecationIssueTypePrefixedVideoEnterFullScreen | AuditsDeprecationIssueTypePrefixedVideoExitFullscreen | AuditsDeprecationIssueTypePrefixedVideoExitFullScreen | AuditsDeprecationIssueTypePrefixedVideoSupportsFullscreen | AuditsDeprecationIssueTypeRangeExpand | AuditsDeprecationIssueTypeRequestedSubresourceWithEmbeddedCredentials | AuditsDeprecationIssueTypeRTCConstraintEnableDtlsSrtpFalse | AuditsDeprecationIssueTypeRTCConstraintEnableDtlsSrtpTrue | AuditsDeprecationIssueTypeRTCPeerConnectionComplexPlanBSdpUsingDefaultSdpSemantics | AuditsDeprecationIssueTypeRTCPeerConnectionSdpSemanticsPlanB | AuditsDeprecationIssueTypeRtcpMuxPolicyNegotiate | AuditsDeprecationIssueTypeSharedArrayBufferConstructedWithoutIsolation | AuditsDeprecationIssueTypeTextToSpeech_DisallowedByAutoplay | AuditsDeprecationIssueTypeV8SharedArrayBufferConstructedInExtensionWithoutIsolation | AuditsDeprecationIssueTypeXHRJSONEncodingDetection | AuditsDeprecationIssueTypeXMLHttpRequestSynchronousInNonWorkerOutsideBeforeUnload | AuditsDeprecationIssueTypeXRSupportsSession
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON AuditsDeprecationIssueType where
+  parseJSON = A.withText "AuditsDeprecationIssueType" $ \v -> case v of
+    "AuthorizationCoveredByWildcard" -> pure AuditsDeprecationIssueTypeAuthorizationCoveredByWildcard
+    "CanRequestURLHTTPContainingNewline" -> pure AuditsDeprecationIssueTypeCanRequestURLHTTPContainingNewline
+    "ChromeLoadTimesConnectionInfo" -> pure AuditsDeprecationIssueTypeChromeLoadTimesConnectionInfo
+    "ChromeLoadTimesFirstPaintAfterLoadTime" -> pure AuditsDeprecationIssueTypeChromeLoadTimesFirstPaintAfterLoadTime
+    "ChromeLoadTimesWasAlternateProtocolAvailable" -> pure AuditsDeprecationIssueTypeChromeLoadTimesWasAlternateProtocolAvailable
+    "CookieWithTruncatingChar" -> pure AuditsDeprecationIssueTypeCookieWithTruncatingChar
+    "CrossOriginAccessBasedOnDocumentDomain" -> pure AuditsDeprecationIssueTypeCrossOriginAccessBasedOnDocumentDomain
+    "CrossOriginWindowAlert" -> pure AuditsDeprecationIssueTypeCrossOriginWindowAlert
+    "CrossOriginWindowConfirm" -> pure AuditsDeprecationIssueTypeCrossOriginWindowConfirm
+    "CSSSelectorInternalMediaControlsOverlayCastButton" -> pure AuditsDeprecationIssueTypeCSSSelectorInternalMediaControlsOverlayCastButton
+    "DeprecationExample" -> pure AuditsDeprecationIssueTypeDeprecationExample
+    "DocumentDomainSettingWithoutOriginAgentClusterHeader" -> pure AuditsDeprecationIssueTypeDocumentDomainSettingWithoutOriginAgentClusterHeader
+    "EventPath" -> pure AuditsDeprecationIssueTypeEventPath
+    "ExpectCTHeader" -> pure AuditsDeprecationIssueTypeExpectCTHeader
+    "GeolocationInsecureOrigin" -> pure AuditsDeprecationIssueTypeGeolocationInsecureOrigin
+    "GeolocationInsecureOriginDeprecatedNotRemoved" -> pure AuditsDeprecationIssueTypeGeolocationInsecureOriginDeprecatedNotRemoved
+    "GetUserMediaInsecureOrigin" -> pure AuditsDeprecationIssueTypeGetUserMediaInsecureOrigin
+    "HostCandidateAttributeGetter" -> pure AuditsDeprecationIssueTypeHostCandidateAttributeGetter
+    "IdentityInCanMakePaymentEvent" -> pure AuditsDeprecationIssueTypeIdentityInCanMakePaymentEvent
+    "InsecurePrivateNetworkSubresourceRequest" -> pure AuditsDeprecationIssueTypeInsecurePrivateNetworkSubresourceRequest
+    "LocalCSSFileExtensionRejected" -> pure AuditsDeprecationIssueTypeLocalCSSFileExtensionRejected
+    "MediaSourceAbortRemove" -> pure AuditsDeprecationIssueTypeMediaSourceAbortRemove
+    "MediaSourceDurationTruncatingBuffered" -> pure AuditsDeprecationIssueTypeMediaSourceDurationTruncatingBuffered
+    "NoSysexWebMIDIWithoutPermission" -> pure AuditsDeprecationIssueTypeNoSysexWebMIDIWithoutPermission
+    "NotificationInsecureOrigin" -> pure AuditsDeprecationIssueTypeNotificationInsecureOrigin
+    "NotificationPermissionRequestedIframe" -> pure AuditsDeprecationIssueTypeNotificationPermissionRequestedIframe
+    "ObsoleteWebRtcCipherSuite" -> pure AuditsDeprecationIssueTypeObsoleteWebRtcCipherSuite
+    "OpenWebDatabaseInsecureContext" -> pure AuditsDeprecationIssueTypeOpenWebDatabaseInsecureContext
+    "OverflowVisibleOnReplacedElement" -> pure AuditsDeprecationIssueTypeOverflowVisibleOnReplacedElement
+    "PaymentInstruments" -> pure AuditsDeprecationIssueTypePaymentInstruments
+    "PaymentRequestCSPViolation" -> pure AuditsDeprecationIssueTypePaymentRequestCSPViolation
+    "PersistentQuotaType" -> pure AuditsDeprecationIssueTypePersistentQuotaType
+    "PictureSourceSrc" -> pure AuditsDeprecationIssueTypePictureSourceSrc
+    "PrefixedCancelAnimationFrame" -> pure AuditsDeprecationIssueTypePrefixedCancelAnimationFrame
+    "PrefixedRequestAnimationFrame" -> pure AuditsDeprecationIssueTypePrefixedRequestAnimationFrame
+    "PrefixedStorageInfo" -> pure AuditsDeprecationIssueTypePrefixedStorageInfo
+    "PrefixedVideoDisplayingFullscreen" -> pure AuditsDeprecationIssueTypePrefixedVideoDisplayingFullscreen
+    "PrefixedVideoEnterFullscreen" -> pure AuditsDeprecationIssueTypePrefixedVideoEnterFullscreen
+    "PrefixedVideoEnterFullScreen" -> pure AuditsDeprecationIssueTypePrefixedVideoEnterFullScreen
+    "PrefixedVideoExitFullscreen" -> pure AuditsDeprecationIssueTypePrefixedVideoExitFullscreen
+    "PrefixedVideoExitFullScreen" -> pure AuditsDeprecationIssueTypePrefixedVideoExitFullScreen
+    "PrefixedVideoSupportsFullscreen" -> pure AuditsDeprecationIssueTypePrefixedVideoSupportsFullscreen
+    "RangeExpand" -> pure AuditsDeprecationIssueTypeRangeExpand
+    "RequestedSubresourceWithEmbeddedCredentials" -> pure AuditsDeprecationIssueTypeRequestedSubresourceWithEmbeddedCredentials
+    "RTCConstraintEnableDtlsSrtpFalse" -> pure AuditsDeprecationIssueTypeRTCConstraintEnableDtlsSrtpFalse
+    "RTCConstraintEnableDtlsSrtpTrue" -> pure AuditsDeprecationIssueTypeRTCConstraintEnableDtlsSrtpTrue
+    "RTCPeerConnectionComplexPlanBSdpUsingDefaultSdpSemantics" -> pure AuditsDeprecationIssueTypeRTCPeerConnectionComplexPlanBSdpUsingDefaultSdpSemantics
+    "RTCPeerConnectionSdpSemanticsPlanB" -> pure AuditsDeprecationIssueTypeRTCPeerConnectionSdpSemanticsPlanB
+    "RtcpMuxPolicyNegotiate" -> pure AuditsDeprecationIssueTypeRtcpMuxPolicyNegotiate
+    "SharedArrayBufferConstructedWithoutIsolation" -> pure AuditsDeprecationIssueTypeSharedArrayBufferConstructedWithoutIsolation
+    "TextToSpeech_DisallowedByAutoplay" -> pure AuditsDeprecationIssueTypeTextToSpeech_DisallowedByAutoplay
+    "V8SharedArrayBufferConstructedInExtensionWithoutIsolation" -> pure AuditsDeprecationIssueTypeV8SharedArrayBufferConstructedInExtensionWithoutIsolation
+    "XHRJSONEncodingDetection" -> pure AuditsDeprecationIssueTypeXHRJSONEncodingDetection
+    "XMLHttpRequestSynchronousInNonWorkerOutsideBeforeUnload" -> pure AuditsDeprecationIssueTypeXMLHttpRequestSynchronousInNonWorkerOutsideBeforeUnload
+    "XRSupportsSession" -> pure AuditsDeprecationIssueTypeXRSupportsSession
+    "_" -> fail "failed to parse AuditsDeprecationIssueType"
+instance ToJSON AuditsDeprecationIssueType where
+  toJSON v = A.String $ case v of
+    AuditsDeprecationIssueTypeAuthorizationCoveredByWildcard -> "AuthorizationCoveredByWildcard"
+    AuditsDeprecationIssueTypeCanRequestURLHTTPContainingNewline -> "CanRequestURLHTTPContainingNewline"
+    AuditsDeprecationIssueTypeChromeLoadTimesConnectionInfo -> "ChromeLoadTimesConnectionInfo"
+    AuditsDeprecationIssueTypeChromeLoadTimesFirstPaintAfterLoadTime -> "ChromeLoadTimesFirstPaintAfterLoadTime"
+    AuditsDeprecationIssueTypeChromeLoadTimesWasAlternateProtocolAvailable -> "ChromeLoadTimesWasAlternateProtocolAvailable"
+    AuditsDeprecationIssueTypeCookieWithTruncatingChar -> "CookieWithTruncatingChar"
+    AuditsDeprecationIssueTypeCrossOriginAccessBasedOnDocumentDomain -> "CrossOriginAccessBasedOnDocumentDomain"
+    AuditsDeprecationIssueTypeCrossOriginWindowAlert -> "CrossOriginWindowAlert"
+    AuditsDeprecationIssueTypeCrossOriginWindowConfirm -> "CrossOriginWindowConfirm"
+    AuditsDeprecationIssueTypeCSSSelectorInternalMediaControlsOverlayCastButton -> "CSSSelectorInternalMediaControlsOverlayCastButton"
+    AuditsDeprecationIssueTypeDeprecationExample -> "DeprecationExample"
+    AuditsDeprecationIssueTypeDocumentDomainSettingWithoutOriginAgentClusterHeader -> "DocumentDomainSettingWithoutOriginAgentClusterHeader"
+    AuditsDeprecationIssueTypeEventPath -> "EventPath"
+    AuditsDeprecationIssueTypeExpectCTHeader -> "ExpectCTHeader"
+    AuditsDeprecationIssueTypeGeolocationInsecureOrigin -> "GeolocationInsecureOrigin"
+    AuditsDeprecationIssueTypeGeolocationInsecureOriginDeprecatedNotRemoved -> "GeolocationInsecureOriginDeprecatedNotRemoved"
+    AuditsDeprecationIssueTypeGetUserMediaInsecureOrigin -> "GetUserMediaInsecureOrigin"
+    AuditsDeprecationIssueTypeHostCandidateAttributeGetter -> "HostCandidateAttributeGetter"
+    AuditsDeprecationIssueTypeIdentityInCanMakePaymentEvent -> "IdentityInCanMakePaymentEvent"
+    AuditsDeprecationIssueTypeInsecurePrivateNetworkSubresourceRequest -> "InsecurePrivateNetworkSubresourceRequest"
+    AuditsDeprecationIssueTypeLocalCSSFileExtensionRejected -> "LocalCSSFileExtensionRejected"
+    AuditsDeprecationIssueTypeMediaSourceAbortRemove -> "MediaSourceAbortRemove"
+    AuditsDeprecationIssueTypeMediaSourceDurationTruncatingBuffered -> "MediaSourceDurationTruncatingBuffered"
+    AuditsDeprecationIssueTypeNoSysexWebMIDIWithoutPermission -> "NoSysexWebMIDIWithoutPermission"
+    AuditsDeprecationIssueTypeNotificationInsecureOrigin -> "NotificationInsecureOrigin"
+    AuditsDeprecationIssueTypeNotificationPermissionRequestedIframe -> "NotificationPermissionRequestedIframe"
+    AuditsDeprecationIssueTypeObsoleteWebRtcCipherSuite -> "ObsoleteWebRtcCipherSuite"
+    AuditsDeprecationIssueTypeOpenWebDatabaseInsecureContext -> "OpenWebDatabaseInsecureContext"
+    AuditsDeprecationIssueTypeOverflowVisibleOnReplacedElement -> "OverflowVisibleOnReplacedElement"
+    AuditsDeprecationIssueTypePaymentInstruments -> "PaymentInstruments"
+    AuditsDeprecationIssueTypePaymentRequestCSPViolation -> "PaymentRequestCSPViolation"
+    AuditsDeprecationIssueTypePersistentQuotaType -> "PersistentQuotaType"
+    AuditsDeprecationIssueTypePictureSourceSrc -> "PictureSourceSrc"
+    AuditsDeprecationIssueTypePrefixedCancelAnimationFrame -> "PrefixedCancelAnimationFrame"
+    AuditsDeprecationIssueTypePrefixedRequestAnimationFrame -> "PrefixedRequestAnimationFrame"
+    AuditsDeprecationIssueTypePrefixedStorageInfo -> "PrefixedStorageInfo"
+    AuditsDeprecationIssueTypePrefixedVideoDisplayingFullscreen -> "PrefixedVideoDisplayingFullscreen"
+    AuditsDeprecationIssueTypePrefixedVideoEnterFullscreen -> "PrefixedVideoEnterFullscreen"
+    AuditsDeprecationIssueTypePrefixedVideoEnterFullScreen -> "PrefixedVideoEnterFullScreen"
+    AuditsDeprecationIssueTypePrefixedVideoExitFullscreen -> "PrefixedVideoExitFullscreen"
+    AuditsDeprecationIssueTypePrefixedVideoExitFullScreen -> "PrefixedVideoExitFullScreen"
+    AuditsDeprecationIssueTypePrefixedVideoSupportsFullscreen -> "PrefixedVideoSupportsFullscreen"
+    AuditsDeprecationIssueTypeRangeExpand -> "RangeExpand"
+    AuditsDeprecationIssueTypeRequestedSubresourceWithEmbeddedCredentials -> "RequestedSubresourceWithEmbeddedCredentials"
+    AuditsDeprecationIssueTypeRTCConstraintEnableDtlsSrtpFalse -> "RTCConstraintEnableDtlsSrtpFalse"
+    AuditsDeprecationIssueTypeRTCConstraintEnableDtlsSrtpTrue -> "RTCConstraintEnableDtlsSrtpTrue"
+    AuditsDeprecationIssueTypeRTCPeerConnectionComplexPlanBSdpUsingDefaultSdpSemantics -> "RTCPeerConnectionComplexPlanBSdpUsingDefaultSdpSemantics"
+    AuditsDeprecationIssueTypeRTCPeerConnectionSdpSemanticsPlanB -> "RTCPeerConnectionSdpSemanticsPlanB"
+    AuditsDeprecationIssueTypeRtcpMuxPolicyNegotiate -> "RtcpMuxPolicyNegotiate"
+    AuditsDeprecationIssueTypeSharedArrayBufferConstructedWithoutIsolation -> "SharedArrayBufferConstructedWithoutIsolation"
+    AuditsDeprecationIssueTypeTextToSpeech_DisallowedByAutoplay -> "TextToSpeech_DisallowedByAutoplay"
+    AuditsDeprecationIssueTypeV8SharedArrayBufferConstructedInExtensionWithoutIsolation -> "V8SharedArrayBufferConstructedInExtensionWithoutIsolation"
+    AuditsDeprecationIssueTypeXHRJSONEncodingDetection -> "XHRJSONEncodingDetection"
+    AuditsDeprecationIssueTypeXMLHttpRequestSynchronousInNonWorkerOutsideBeforeUnload -> "XMLHttpRequestSynchronousInNonWorkerOutsideBeforeUnload"
+    AuditsDeprecationIssueTypeXRSupportsSession -> "XRSupportsSession"
+
+-- | Type 'Audits.DeprecationIssueDetails'.
+--   This issue tracks information needed to print a deprecation message.
+--   https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/frame/third_party/blink/renderer/core/frame/deprecation/README.md
+data AuditsDeprecationIssueDetails = AuditsDeprecationIssueDetails
+  {
+    auditsDeprecationIssueDetailsAffectedFrame :: Maybe AuditsAffectedFrame,
+    auditsDeprecationIssueDetailsSourceCodeLocation :: AuditsSourceCodeLocation,
+    auditsDeprecationIssueDetailsType :: AuditsDeprecationIssueType
+  }
+  deriving (Eq, Show)
+instance FromJSON AuditsDeprecationIssueDetails where
+  parseJSON = A.withObject "AuditsDeprecationIssueDetails" $ \o -> AuditsDeprecationIssueDetails
+    <$> o A..:? "affectedFrame"
+    <*> o A..: "sourceCodeLocation"
+    <*> o A..: "type"
+instance ToJSON AuditsDeprecationIssueDetails where
+  toJSON p = A.object $ catMaybes [
+    ("affectedFrame" A..=) <$> (auditsDeprecationIssueDetailsAffectedFrame p),
+    ("sourceCodeLocation" A..=) <$> Just (auditsDeprecationIssueDetailsSourceCodeLocation p),
+    ("type" A..=) <$> Just (auditsDeprecationIssueDetailsType p)
+    ]
+
+-- | Type 'Audits.ClientHintIssueReason'.
+data AuditsClientHintIssueReason = AuditsClientHintIssueReasonMetaTagAllowListInvalidOrigin | AuditsClientHintIssueReasonMetaTagModifiedHTML
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON AuditsClientHintIssueReason where
+  parseJSON = A.withText "AuditsClientHintIssueReason" $ \v -> case v of
+    "MetaTagAllowListInvalidOrigin" -> pure AuditsClientHintIssueReasonMetaTagAllowListInvalidOrigin
+    "MetaTagModifiedHTML" -> pure AuditsClientHintIssueReasonMetaTagModifiedHTML
+    "_" -> fail "failed to parse AuditsClientHintIssueReason"
+instance ToJSON AuditsClientHintIssueReason where
+  toJSON v = A.String $ case v of
+    AuditsClientHintIssueReasonMetaTagAllowListInvalidOrigin -> "MetaTagAllowListInvalidOrigin"
+    AuditsClientHintIssueReasonMetaTagModifiedHTML -> "MetaTagModifiedHTML"
+
+-- | Type 'Audits.FederatedAuthRequestIssueDetails'.
+data AuditsFederatedAuthRequestIssueDetails = AuditsFederatedAuthRequestIssueDetails
+  {
+    auditsFederatedAuthRequestIssueDetailsFederatedAuthRequestIssueReason :: AuditsFederatedAuthRequestIssueReason
+  }
+  deriving (Eq, Show)
+instance FromJSON AuditsFederatedAuthRequestIssueDetails where
+  parseJSON = A.withObject "AuditsFederatedAuthRequestIssueDetails" $ \o -> AuditsFederatedAuthRequestIssueDetails
+    <$> o A..: "federatedAuthRequestIssueReason"
+instance ToJSON AuditsFederatedAuthRequestIssueDetails where
+  toJSON p = A.object $ catMaybes [
+    ("federatedAuthRequestIssueReason" A..=) <$> Just (auditsFederatedAuthRequestIssueDetailsFederatedAuthRequestIssueReason p)
+    ]
+
+-- | Type 'Audits.FederatedAuthRequestIssueReason'.
+--   Represents the failure reason when a federated authentication reason fails.
+--   Should be updated alongside RequestIdTokenStatus in
+--   third_party/blink/public/mojom/devtools/inspector_issue.mojom to include
+--   all cases except for success.
+data AuditsFederatedAuthRequestIssueReason = AuditsFederatedAuthRequestIssueReasonShouldEmbargo | AuditsFederatedAuthRequestIssueReasonTooManyRequests | AuditsFederatedAuthRequestIssueReasonManifestListHttpNotFound | AuditsFederatedAuthRequestIssueReasonManifestListNoResponse | AuditsFederatedAuthRequestIssueReasonManifestListInvalidResponse | AuditsFederatedAuthRequestIssueReasonManifestNotInManifestList | AuditsFederatedAuthRequestIssueReasonManifestListTooBig | AuditsFederatedAuthRequestIssueReasonManifestHttpNotFound | AuditsFederatedAuthRequestIssueReasonManifestNoResponse | AuditsFederatedAuthRequestIssueReasonManifestInvalidResponse | AuditsFederatedAuthRequestIssueReasonClientMetadataHttpNotFound | AuditsFederatedAuthRequestIssueReasonClientMetadataNoResponse | AuditsFederatedAuthRequestIssueReasonClientMetadataInvalidResponse | AuditsFederatedAuthRequestIssueReasonDisabledInSettings | AuditsFederatedAuthRequestIssueReasonErrorFetchingSignin | AuditsFederatedAuthRequestIssueReasonInvalidSigninResponse | AuditsFederatedAuthRequestIssueReasonAccountsHttpNotFound | AuditsFederatedAuthRequestIssueReasonAccountsNoResponse | AuditsFederatedAuthRequestIssueReasonAccountsInvalidResponse | AuditsFederatedAuthRequestIssueReasonIdTokenHttpNotFound | AuditsFederatedAuthRequestIssueReasonIdTokenNoResponse | AuditsFederatedAuthRequestIssueReasonIdTokenInvalidResponse | AuditsFederatedAuthRequestIssueReasonIdTokenInvalidRequest | AuditsFederatedAuthRequestIssueReasonErrorIdToken | AuditsFederatedAuthRequestIssueReasonCanceled | AuditsFederatedAuthRequestIssueReasonRpPageNotVisible
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON AuditsFederatedAuthRequestIssueReason where
+  parseJSON = A.withText "AuditsFederatedAuthRequestIssueReason" $ \v -> case v of
+    "ShouldEmbargo" -> pure AuditsFederatedAuthRequestIssueReasonShouldEmbargo
+    "TooManyRequests" -> pure AuditsFederatedAuthRequestIssueReasonTooManyRequests
+    "ManifestListHttpNotFound" -> pure AuditsFederatedAuthRequestIssueReasonManifestListHttpNotFound
+    "ManifestListNoResponse" -> pure AuditsFederatedAuthRequestIssueReasonManifestListNoResponse
+    "ManifestListInvalidResponse" -> pure AuditsFederatedAuthRequestIssueReasonManifestListInvalidResponse
+    "ManifestNotInManifestList" -> pure AuditsFederatedAuthRequestIssueReasonManifestNotInManifestList
+    "ManifestListTooBig" -> pure AuditsFederatedAuthRequestIssueReasonManifestListTooBig
+    "ManifestHttpNotFound" -> pure AuditsFederatedAuthRequestIssueReasonManifestHttpNotFound
+    "ManifestNoResponse" -> pure AuditsFederatedAuthRequestIssueReasonManifestNoResponse
+    "ManifestInvalidResponse" -> pure AuditsFederatedAuthRequestIssueReasonManifestInvalidResponse
+    "ClientMetadataHttpNotFound" -> pure AuditsFederatedAuthRequestIssueReasonClientMetadataHttpNotFound
+    "ClientMetadataNoResponse" -> pure AuditsFederatedAuthRequestIssueReasonClientMetadataNoResponse
+    "ClientMetadataInvalidResponse" -> pure AuditsFederatedAuthRequestIssueReasonClientMetadataInvalidResponse
+    "DisabledInSettings" -> pure AuditsFederatedAuthRequestIssueReasonDisabledInSettings
+    "ErrorFetchingSignin" -> pure AuditsFederatedAuthRequestIssueReasonErrorFetchingSignin
+    "InvalidSigninResponse" -> pure AuditsFederatedAuthRequestIssueReasonInvalidSigninResponse
+    "AccountsHttpNotFound" -> pure AuditsFederatedAuthRequestIssueReasonAccountsHttpNotFound
+    "AccountsNoResponse" -> pure AuditsFederatedAuthRequestIssueReasonAccountsNoResponse
+    "AccountsInvalidResponse" -> pure AuditsFederatedAuthRequestIssueReasonAccountsInvalidResponse
+    "IdTokenHttpNotFound" -> pure AuditsFederatedAuthRequestIssueReasonIdTokenHttpNotFound
+    "IdTokenNoResponse" -> pure AuditsFederatedAuthRequestIssueReasonIdTokenNoResponse
+    "IdTokenInvalidResponse" -> pure AuditsFederatedAuthRequestIssueReasonIdTokenInvalidResponse
+    "IdTokenInvalidRequest" -> pure AuditsFederatedAuthRequestIssueReasonIdTokenInvalidRequest
+    "ErrorIdToken" -> pure AuditsFederatedAuthRequestIssueReasonErrorIdToken
+    "Canceled" -> pure AuditsFederatedAuthRequestIssueReasonCanceled
+    "RpPageNotVisible" -> pure AuditsFederatedAuthRequestIssueReasonRpPageNotVisible
+    "_" -> fail "failed to parse AuditsFederatedAuthRequestIssueReason"
+instance ToJSON AuditsFederatedAuthRequestIssueReason where
+  toJSON v = A.String $ case v of
+    AuditsFederatedAuthRequestIssueReasonShouldEmbargo -> "ShouldEmbargo"
+    AuditsFederatedAuthRequestIssueReasonTooManyRequests -> "TooManyRequests"
+    AuditsFederatedAuthRequestIssueReasonManifestListHttpNotFound -> "ManifestListHttpNotFound"
+    AuditsFederatedAuthRequestIssueReasonManifestListNoResponse -> "ManifestListNoResponse"
+    AuditsFederatedAuthRequestIssueReasonManifestListInvalidResponse -> "ManifestListInvalidResponse"
+    AuditsFederatedAuthRequestIssueReasonManifestNotInManifestList -> "ManifestNotInManifestList"
+    AuditsFederatedAuthRequestIssueReasonManifestListTooBig -> "ManifestListTooBig"
+    AuditsFederatedAuthRequestIssueReasonManifestHttpNotFound -> "ManifestHttpNotFound"
+    AuditsFederatedAuthRequestIssueReasonManifestNoResponse -> "ManifestNoResponse"
+    AuditsFederatedAuthRequestIssueReasonManifestInvalidResponse -> "ManifestInvalidResponse"
+    AuditsFederatedAuthRequestIssueReasonClientMetadataHttpNotFound -> "ClientMetadataHttpNotFound"
+    AuditsFederatedAuthRequestIssueReasonClientMetadataNoResponse -> "ClientMetadataNoResponse"
+    AuditsFederatedAuthRequestIssueReasonClientMetadataInvalidResponse -> "ClientMetadataInvalidResponse"
+    AuditsFederatedAuthRequestIssueReasonDisabledInSettings -> "DisabledInSettings"
+    AuditsFederatedAuthRequestIssueReasonErrorFetchingSignin -> "ErrorFetchingSignin"
+    AuditsFederatedAuthRequestIssueReasonInvalidSigninResponse -> "InvalidSigninResponse"
+    AuditsFederatedAuthRequestIssueReasonAccountsHttpNotFound -> "AccountsHttpNotFound"
+    AuditsFederatedAuthRequestIssueReasonAccountsNoResponse -> "AccountsNoResponse"
+    AuditsFederatedAuthRequestIssueReasonAccountsInvalidResponse -> "AccountsInvalidResponse"
+    AuditsFederatedAuthRequestIssueReasonIdTokenHttpNotFound -> "IdTokenHttpNotFound"
+    AuditsFederatedAuthRequestIssueReasonIdTokenNoResponse -> "IdTokenNoResponse"
+    AuditsFederatedAuthRequestIssueReasonIdTokenInvalidResponse -> "IdTokenInvalidResponse"
+    AuditsFederatedAuthRequestIssueReasonIdTokenInvalidRequest -> "IdTokenInvalidRequest"
+    AuditsFederatedAuthRequestIssueReasonErrorIdToken -> "ErrorIdToken"
+    AuditsFederatedAuthRequestIssueReasonCanceled -> "Canceled"
+    AuditsFederatedAuthRequestIssueReasonRpPageNotVisible -> "RpPageNotVisible"
+
+-- | Type 'Audits.ClientHintIssueDetails'.
+--   This issue tracks client hints related issues. It's used to deprecate old
+--   features, encourage the use of new ones, and provide general guidance.
+data AuditsClientHintIssueDetails = AuditsClientHintIssueDetails
+  {
+    auditsClientHintIssueDetailsSourceCodeLocation :: AuditsSourceCodeLocation,
+    auditsClientHintIssueDetailsClientHintIssueReason :: AuditsClientHintIssueReason
+  }
+  deriving (Eq, Show)
+instance FromJSON AuditsClientHintIssueDetails where
+  parseJSON = A.withObject "AuditsClientHintIssueDetails" $ \o -> AuditsClientHintIssueDetails
+    <$> o A..: "sourceCodeLocation"
+    <*> o A..: "clientHintIssueReason"
+instance ToJSON AuditsClientHintIssueDetails where
+  toJSON p = A.object $ catMaybes [
+    ("sourceCodeLocation" A..=) <$> Just (auditsClientHintIssueDetailsSourceCodeLocation p),
+    ("clientHintIssueReason" A..=) <$> Just (auditsClientHintIssueDetailsClientHintIssueReason p)
+    ]
+
+-- | Type 'Audits.InspectorIssueCode'.
+--   A unique identifier for the type of issue. Each type may use one of the
+--   optional fields in InspectorIssueDetails to convey more specific
+--   information about the kind of issue.
+data AuditsInspectorIssueCode = AuditsInspectorIssueCodeCookieIssue | AuditsInspectorIssueCodeMixedContentIssue | AuditsInspectorIssueCodeBlockedByResponseIssue | AuditsInspectorIssueCodeHeavyAdIssue | AuditsInspectorIssueCodeContentSecurityPolicyIssue | AuditsInspectorIssueCodeSharedArrayBufferIssue | AuditsInspectorIssueCodeTrustedWebActivityIssue | AuditsInspectorIssueCodeLowTextContrastIssue | AuditsInspectorIssueCodeCorsIssue | AuditsInspectorIssueCodeAttributionReportingIssue | AuditsInspectorIssueCodeQuirksModeIssue | AuditsInspectorIssueCodeNavigatorUserAgentIssue | AuditsInspectorIssueCodeGenericIssue | AuditsInspectorIssueCodeDeprecationIssue | AuditsInspectorIssueCodeClientHintIssue | AuditsInspectorIssueCodeFederatedAuthRequestIssue
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON AuditsInspectorIssueCode where
+  parseJSON = A.withText "AuditsInspectorIssueCode" $ \v -> case v of
+    "CookieIssue" -> pure AuditsInspectorIssueCodeCookieIssue
+    "MixedContentIssue" -> pure AuditsInspectorIssueCodeMixedContentIssue
+    "BlockedByResponseIssue" -> pure AuditsInspectorIssueCodeBlockedByResponseIssue
+    "HeavyAdIssue" -> pure AuditsInspectorIssueCodeHeavyAdIssue
+    "ContentSecurityPolicyIssue" -> pure AuditsInspectorIssueCodeContentSecurityPolicyIssue
+    "SharedArrayBufferIssue" -> pure AuditsInspectorIssueCodeSharedArrayBufferIssue
+    "TrustedWebActivityIssue" -> pure AuditsInspectorIssueCodeTrustedWebActivityIssue
+    "LowTextContrastIssue" -> pure AuditsInspectorIssueCodeLowTextContrastIssue
+    "CorsIssue" -> pure AuditsInspectorIssueCodeCorsIssue
+    "AttributionReportingIssue" -> pure AuditsInspectorIssueCodeAttributionReportingIssue
+    "QuirksModeIssue" -> pure AuditsInspectorIssueCodeQuirksModeIssue
+    "NavigatorUserAgentIssue" -> pure AuditsInspectorIssueCodeNavigatorUserAgentIssue
+    "GenericIssue" -> pure AuditsInspectorIssueCodeGenericIssue
+    "DeprecationIssue" -> pure AuditsInspectorIssueCodeDeprecationIssue
+    "ClientHintIssue" -> pure AuditsInspectorIssueCodeClientHintIssue
+    "FederatedAuthRequestIssue" -> pure AuditsInspectorIssueCodeFederatedAuthRequestIssue
+    "_" -> fail "failed to parse AuditsInspectorIssueCode"
+instance ToJSON AuditsInspectorIssueCode where
+  toJSON v = A.String $ case v of
+    AuditsInspectorIssueCodeCookieIssue -> "CookieIssue"
+    AuditsInspectorIssueCodeMixedContentIssue -> "MixedContentIssue"
+    AuditsInspectorIssueCodeBlockedByResponseIssue -> "BlockedByResponseIssue"
+    AuditsInspectorIssueCodeHeavyAdIssue -> "HeavyAdIssue"
+    AuditsInspectorIssueCodeContentSecurityPolicyIssue -> "ContentSecurityPolicyIssue"
+    AuditsInspectorIssueCodeSharedArrayBufferIssue -> "SharedArrayBufferIssue"
+    AuditsInspectorIssueCodeTrustedWebActivityIssue -> "TrustedWebActivityIssue"
+    AuditsInspectorIssueCodeLowTextContrastIssue -> "LowTextContrastIssue"
+    AuditsInspectorIssueCodeCorsIssue -> "CorsIssue"
+    AuditsInspectorIssueCodeAttributionReportingIssue -> "AttributionReportingIssue"
+    AuditsInspectorIssueCodeQuirksModeIssue -> "QuirksModeIssue"
+    AuditsInspectorIssueCodeNavigatorUserAgentIssue -> "NavigatorUserAgentIssue"
+    AuditsInspectorIssueCodeGenericIssue -> "GenericIssue"
+    AuditsInspectorIssueCodeDeprecationIssue -> "DeprecationIssue"
+    AuditsInspectorIssueCodeClientHintIssue -> "ClientHintIssue"
+    AuditsInspectorIssueCodeFederatedAuthRequestIssue -> "FederatedAuthRequestIssue"
+
+-- | Type 'Audits.InspectorIssueDetails'.
+--   This struct holds a list of optional fields with additional information
+--   specific to the kind of issue. When adding a new issue code, please also
+--   add a new optional field to this type.
+data AuditsInspectorIssueDetails = AuditsInspectorIssueDetails
+  {
+    auditsInspectorIssueDetailsCookieIssueDetails :: Maybe AuditsCookieIssueDetails,
+    auditsInspectorIssueDetailsMixedContentIssueDetails :: Maybe AuditsMixedContentIssueDetails,
+    auditsInspectorIssueDetailsBlockedByResponseIssueDetails :: Maybe AuditsBlockedByResponseIssueDetails,
+    auditsInspectorIssueDetailsHeavyAdIssueDetails :: Maybe AuditsHeavyAdIssueDetails,
+    auditsInspectorIssueDetailsContentSecurityPolicyIssueDetails :: Maybe AuditsContentSecurityPolicyIssueDetails,
+    auditsInspectorIssueDetailsSharedArrayBufferIssueDetails :: Maybe AuditsSharedArrayBufferIssueDetails,
+    auditsInspectorIssueDetailsTwaQualityEnforcementDetails :: Maybe AuditsTrustedWebActivityIssueDetails,
+    auditsInspectorIssueDetailsLowTextContrastIssueDetails :: Maybe AuditsLowTextContrastIssueDetails,
+    auditsInspectorIssueDetailsCorsIssueDetails :: Maybe AuditsCorsIssueDetails,
+    auditsInspectorIssueDetailsAttributionReportingIssueDetails :: Maybe AuditsAttributionReportingIssueDetails,
+    auditsInspectorIssueDetailsQuirksModeIssueDetails :: Maybe AuditsQuirksModeIssueDetails,
+    auditsInspectorIssueDetailsNavigatorUserAgentIssueDetails :: Maybe AuditsNavigatorUserAgentIssueDetails,
+    auditsInspectorIssueDetailsGenericIssueDetails :: Maybe AuditsGenericIssueDetails,
+    auditsInspectorIssueDetailsDeprecationIssueDetails :: Maybe AuditsDeprecationIssueDetails,
+    auditsInspectorIssueDetailsClientHintIssueDetails :: Maybe AuditsClientHintIssueDetails,
+    auditsInspectorIssueDetailsFederatedAuthRequestIssueDetails :: Maybe AuditsFederatedAuthRequestIssueDetails
+  }
+  deriving (Eq, Show)
+instance FromJSON AuditsInspectorIssueDetails where
+  parseJSON = A.withObject "AuditsInspectorIssueDetails" $ \o -> AuditsInspectorIssueDetails
+    <$> o A..:? "cookieIssueDetails"
+    <*> o A..:? "mixedContentIssueDetails"
+    <*> o A..:? "blockedByResponseIssueDetails"
+    <*> o A..:? "heavyAdIssueDetails"
+    <*> o A..:? "contentSecurityPolicyIssueDetails"
+    <*> o A..:? "sharedArrayBufferIssueDetails"
+    <*> o A..:? "twaQualityEnforcementDetails"
+    <*> o A..:? "lowTextContrastIssueDetails"
+    <*> o A..:? "corsIssueDetails"
+    <*> o A..:? "attributionReportingIssueDetails"
+    <*> o A..:? "quirksModeIssueDetails"
+    <*> o A..:? "navigatorUserAgentIssueDetails"
+    <*> o A..:? "genericIssueDetails"
+    <*> o A..:? "deprecationIssueDetails"
+    <*> o A..:? "clientHintIssueDetails"
+    <*> o A..:? "federatedAuthRequestIssueDetails"
+instance ToJSON AuditsInspectorIssueDetails where
+  toJSON p = A.object $ catMaybes [
+    ("cookieIssueDetails" A..=) <$> (auditsInspectorIssueDetailsCookieIssueDetails p),
+    ("mixedContentIssueDetails" A..=) <$> (auditsInspectorIssueDetailsMixedContentIssueDetails p),
+    ("blockedByResponseIssueDetails" A..=) <$> (auditsInspectorIssueDetailsBlockedByResponseIssueDetails p),
+    ("heavyAdIssueDetails" A..=) <$> (auditsInspectorIssueDetailsHeavyAdIssueDetails p),
+    ("contentSecurityPolicyIssueDetails" A..=) <$> (auditsInspectorIssueDetailsContentSecurityPolicyIssueDetails p),
+    ("sharedArrayBufferIssueDetails" A..=) <$> (auditsInspectorIssueDetailsSharedArrayBufferIssueDetails p),
+    ("twaQualityEnforcementDetails" A..=) <$> (auditsInspectorIssueDetailsTwaQualityEnforcementDetails p),
+    ("lowTextContrastIssueDetails" A..=) <$> (auditsInspectorIssueDetailsLowTextContrastIssueDetails p),
+    ("corsIssueDetails" A..=) <$> (auditsInspectorIssueDetailsCorsIssueDetails p),
+    ("attributionReportingIssueDetails" A..=) <$> (auditsInspectorIssueDetailsAttributionReportingIssueDetails p),
+    ("quirksModeIssueDetails" A..=) <$> (auditsInspectorIssueDetailsQuirksModeIssueDetails p),
+    ("navigatorUserAgentIssueDetails" A..=) <$> (auditsInspectorIssueDetailsNavigatorUserAgentIssueDetails p),
+    ("genericIssueDetails" A..=) <$> (auditsInspectorIssueDetailsGenericIssueDetails p),
+    ("deprecationIssueDetails" A..=) <$> (auditsInspectorIssueDetailsDeprecationIssueDetails p),
+    ("clientHintIssueDetails" A..=) <$> (auditsInspectorIssueDetailsClientHintIssueDetails p),
+    ("federatedAuthRequestIssueDetails" A..=) <$> (auditsInspectorIssueDetailsFederatedAuthRequestIssueDetails p)
+    ]
+
+-- | Type 'Audits.IssueId'.
+--   A unique id for a DevTools inspector issue. Allows other entities (e.g.
+--   exceptions, CDP message, console messages, etc.) to reference an issue.
+type AuditsIssueId = T.Text
+
+-- | Type 'Audits.InspectorIssue'.
+--   An inspector issue reported from the back-end.
+data AuditsInspectorIssue = AuditsInspectorIssue
+  {
+    auditsInspectorIssueCode :: AuditsInspectorIssueCode,
+    auditsInspectorIssueDetails :: AuditsInspectorIssueDetails,
+    -- | A unique id for this issue. May be omitted if no other entity (e.g.
+    --   exception, CDP message, etc.) is referencing this issue.
+    auditsInspectorIssueIssueId :: Maybe AuditsIssueId
+  }
+  deriving (Eq, Show)
+instance FromJSON AuditsInspectorIssue where
+  parseJSON = A.withObject "AuditsInspectorIssue" $ \o -> AuditsInspectorIssue
+    <$> o A..: "code"
+    <*> o A..: "details"
+    <*> o A..:? "issueId"
+instance ToJSON AuditsInspectorIssue where
+  toJSON p = A.object $ catMaybes [
+    ("code" A..=) <$> Just (auditsInspectorIssueCode p),
+    ("details" A..=) <$> Just (auditsInspectorIssueDetails p),
+    ("issueId" A..=) <$> (auditsInspectorIssueIssueId p)
+    ]
+
+-- | Type of the 'Audits.issueAdded' event.
+data AuditsIssueAdded = AuditsIssueAdded
+  {
+    auditsIssueAddedIssue :: AuditsInspectorIssue
+  }
+  deriving (Eq, Show)
+instance FromJSON AuditsIssueAdded where
+  parseJSON = A.withObject "AuditsIssueAdded" $ \o -> AuditsIssueAdded
+    <$> o A..: "issue"
+instance Event AuditsIssueAdded where
+  eventName _ = "Audits.issueAdded"
+
+-- | Returns the response body and size if it were re-encoded with the specified settings. Only
+--   applies to images.
+
+-- | Parameters of the 'Audits.getEncodedResponse' command.
+data PAuditsGetEncodedResponseEncoding = PAuditsGetEncodedResponseEncodingWebp | PAuditsGetEncodedResponseEncodingJpeg | PAuditsGetEncodedResponseEncodingPng
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PAuditsGetEncodedResponseEncoding where
+  parseJSON = A.withText "PAuditsGetEncodedResponseEncoding" $ \v -> case v of
+    "webp" -> pure PAuditsGetEncodedResponseEncodingWebp
+    "jpeg" -> pure PAuditsGetEncodedResponseEncodingJpeg
+    "png" -> pure PAuditsGetEncodedResponseEncodingPng
+    "_" -> fail "failed to parse PAuditsGetEncodedResponseEncoding"
+instance ToJSON PAuditsGetEncodedResponseEncoding where
+  toJSON v = A.String $ case v of
+    PAuditsGetEncodedResponseEncodingWebp -> "webp"
+    PAuditsGetEncodedResponseEncodingJpeg -> "jpeg"
+    PAuditsGetEncodedResponseEncodingPng -> "png"
+data PAuditsGetEncodedResponse = PAuditsGetEncodedResponse
+  {
+    -- | Identifier of the network request to get content for.
+    pAuditsGetEncodedResponseRequestId :: DOMPageNetworkEmulationSecurity.NetworkRequestId,
+    -- | The encoding to use.
+    pAuditsGetEncodedResponseEncoding :: PAuditsGetEncodedResponseEncoding,
+    -- | The quality of the encoding (0-1). (defaults to 1)
+    pAuditsGetEncodedResponseQuality :: Maybe Double,
+    -- | Whether to only return the size information (defaults to false).
+    pAuditsGetEncodedResponseSizeOnly :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pAuditsGetEncodedResponse
+  {-
+  -- | Identifier of the network request to get content for.
+  -}
+  :: DOMPageNetworkEmulationSecurity.NetworkRequestId
+  {-
+  -- | The encoding to use.
+  -}
+  -> PAuditsGetEncodedResponseEncoding
+  -> PAuditsGetEncodedResponse
+pAuditsGetEncodedResponse
+  arg_pAuditsGetEncodedResponseRequestId
+  arg_pAuditsGetEncodedResponseEncoding
+  = PAuditsGetEncodedResponse
+    arg_pAuditsGetEncodedResponseRequestId
+    arg_pAuditsGetEncodedResponseEncoding
+    Nothing
+    Nothing
+instance ToJSON PAuditsGetEncodedResponse where
+  toJSON p = A.object $ catMaybes [
+    ("requestId" A..=) <$> Just (pAuditsGetEncodedResponseRequestId p),
+    ("encoding" A..=) <$> Just (pAuditsGetEncodedResponseEncoding p),
+    ("quality" A..=) <$> (pAuditsGetEncodedResponseQuality p),
+    ("sizeOnly" A..=) <$> (pAuditsGetEncodedResponseSizeOnly p)
+    ]
+data AuditsGetEncodedResponse = AuditsGetEncodedResponse
+  {
+    -- | The encoded body as a base64 string. Omitted if sizeOnly is true. (Encoded as a base64 string when passed over JSON)
+    auditsGetEncodedResponseBody :: Maybe T.Text,
+    -- | Size before re-encoding.
+    auditsGetEncodedResponseOriginalSize :: Int,
+    -- | Size after re-encoding.
+    auditsGetEncodedResponseEncodedSize :: Int
+  }
+  deriving (Eq, Show)
+instance FromJSON AuditsGetEncodedResponse where
+  parseJSON = A.withObject "AuditsGetEncodedResponse" $ \o -> AuditsGetEncodedResponse
+    <$> o A..:? "body"
+    <*> o A..: "originalSize"
+    <*> o A..: "encodedSize"
+instance Command PAuditsGetEncodedResponse where
+  type CommandResponse PAuditsGetEncodedResponse = AuditsGetEncodedResponse
+  commandName _ = "Audits.getEncodedResponse"
+
+-- | Disables issues domain, prevents further issues from being reported to the client.
+
+-- | Parameters of the 'Audits.disable' command.
+data PAuditsDisable = PAuditsDisable
+  deriving (Eq, Show)
+pAuditsDisable
+  :: PAuditsDisable
+pAuditsDisable
+  = PAuditsDisable
+instance ToJSON PAuditsDisable where
+  toJSON _ = A.Null
+instance Command PAuditsDisable where
+  type CommandResponse PAuditsDisable = ()
+  commandName _ = "Audits.disable"
+  fromJSON = const . A.Success . const ()
+
+-- | Enables issues domain, sends the issues collected so far to the client by means of the
+--   `issueAdded` event.
+
+-- | Parameters of the 'Audits.enable' command.
+data PAuditsEnable = PAuditsEnable
+  deriving (Eq, Show)
+pAuditsEnable
+  :: PAuditsEnable
+pAuditsEnable
+  = PAuditsEnable
+instance ToJSON PAuditsEnable where
+  toJSON _ = A.Null
+instance Command PAuditsEnable where
+  type CommandResponse PAuditsEnable = ()
+  commandName _ = "Audits.enable"
+  fromJSON = const . A.Success . const ()
+
+-- | Runs the contrast check for the target page. Found issues are reported
+--   using Audits.issueAdded event.
+
+-- | Parameters of the 'Audits.checkContrast' command.
+data PAuditsCheckContrast = PAuditsCheckContrast
+  {
+    -- | Whether to report WCAG AAA level issues. Default is false.
+    pAuditsCheckContrastReportAAA :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pAuditsCheckContrast
+  :: PAuditsCheckContrast
+pAuditsCheckContrast
+  = PAuditsCheckContrast
+    Nothing
+instance ToJSON PAuditsCheckContrast where
+  toJSON p = A.object $ catMaybes [
+    ("reportAAA" A..=) <$> (pAuditsCheckContrastReportAAA p)
+    ]
+instance Command PAuditsCheckContrast where
+  type CommandResponse PAuditsCheckContrast = ()
+  commandName _ = "Audits.checkContrast"
+  fromJSON = const . A.Success . const ()
+
diff --git a/src/CDP/Domains/BackgroundService.hs b/src/CDP/Domains/BackgroundService.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains/BackgroundService.hs
@@ -0,0 +1,260 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+
+
+{- |
+= BackgroundService
+
+Defines events for background web platform features.
+-}
+
+
+module CDP.Domains.BackgroundService (module CDP.Domains.BackgroundService) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+
+import CDP.Domains.DOMPageNetworkEmulationSecurity as DOMPageNetworkEmulationSecurity
+import CDP.Domains.ServiceWorker as ServiceWorker
+
+
+-- | Type 'BackgroundService.ServiceName'.
+--   The Background Service that will be associated with the commands/events.
+--   Every Background Service operates independently, but they share the same
+--   API.
+data BackgroundServiceServiceName = BackgroundServiceServiceNameBackgroundFetch | BackgroundServiceServiceNameBackgroundSync | BackgroundServiceServiceNamePushMessaging | BackgroundServiceServiceNameNotifications | BackgroundServiceServiceNamePaymentHandler | BackgroundServiceServiceNamePeriodicBackgroundSync
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON BackgroundServiceServiceName where
+  parseJSON = A.withText "BackgroundServiceServiceName" $ \v -> case v of
+    "backgroundFetch" -> pure BackgroundServiceServiceNameBackgroundFetch
+    "backgroundSync" -> pure BackgroundServiceServiceNameBackgroundSync
+    "pushMessaging" -> pure BackgroundServiceServiceNamePushMessaging
+    "notifications" -> pure BackgroundServiceServiceNameNotifications
+    "paymentHandler" -> pure BackgroundServiceServiceNamePaymentHandler
+    "periodicBackgroundSync" -> pure BackgroundServiceServiceNamePeriodicBackgroundSync
+    "_" -> fail "failed to parse BackgroundServiceServiceName"
+instance ToJSON BackgroundServiceServiceName where
+  toJSON v = A.String $ case v of
+    BackgroundServiceServiceNameBackgroundFetch -> "backgroundFetch"
+    BackgroundServiceServiceNameBackgroundSync -> "backgroundSync"
+    BackgroundServiceServiceNamePushMessaging -> "pushMessaging"
+    BackgroundServiceServiceNameNotifications -> "notifications"
+    BackgroundServiceServiceNamePaymentHandler -> "paymentHandler"
+    BackgroundServiceServiceNamePeriodicBackgroundSync -> "periodicBackgroundSync"
+
+-- | Type 'BackgroundService.EventMetadata'.
+--   A key-value pair for additional event information to pass along.
+data BackgroundServiceEventMetadata = BackgroundServiceEventMetadata
+  {
+    backgroundServiceEventMetadataKey :: T.Text,
+    backgroundServiceEventMetadataValue :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON BackgroundServiceEventMetadata where
+  parseJSON = A.withObject "BackgroundServiceEventMetadata" $ \o -> BackgroundServiceEventMetadata
+    <$> o A..: "key"
+    <*> o A..: "value"
+instance ToJSON BackgroundServiceEventMetadata where
+  toJSON p = A.object $ catMaybes [
+    ("key" A..=) <$> Just (backgroundServiceEventMetadataKey p),
+    ("value" A..=) <$> Just (backgroundServiceEventMetadataValue p)
+    ]
+
+-- | Type 'BackgroundService.BackgroundServiceEvent'.
+data BackgroundServiceBackgroundServiceEvent = BackgroundServiceBackgroundServiceEvent
+  {
+    -- | Timestamp of the event (in seconds).
+    backgroundServiceBackgroundServiceEventTimestamp :: DOMPageNetworkEmulationSecurity.NetworkTimeSinceEpoch,
+    -- | The origin this event belongs to.
+    backgroundServiceBackgroundServiceEventOrigin :: T.Text,
+    -- | The Service Worker ID that initiated the event.
+    backgroundServiceBackgroundServiceEventServiceWorkerRegistrationId :: ServiceWorker.ServiceWorkerRegistrationID,
+    -- | The Background Service this event belongs to.
+    backgroundServiceBackgroundServiceEventService :: BackgroundServiceServiceName,
+    -- | A description of the event.
+    backgroundServiceBackgroundServiceEventEventName :: T.Text,
+    -- | An identifier that groups related events together.
+    backgroundServiceBackgroundServiceEventInstanceId :: T.Text,
+    -- | A list of event-specific information.
+    backgroundServiceBackgroundServiceEventEventMetadata :: [BackgroundServiceEventMetadata]
+  }
+  deriving (Eq, Show)
+instance FromJSON BackgroundServiceBackgroundServiceEvent where
+  parseJSON = A.withObject "BackgroundServiceBackgroundServiceEvent" $ \o -> BackgroundServiceBackgroundServiceEvent
+    <$> o A..: "timestamp"
+    <*> o A..: "origin"
+    <*> o A..: "serviceWorkerRegistrationId"
+    <*> o A..: "service"
+    <*> o A..: "eventName"
+    <*> o A..: "instanceId"
+    <*> o A..: "eventMetadata"
+instance ToJSON BackgroundServiceBackgroundServiceEvent where
+  toJSON p = A.object $ catMaybes [
+    ("timestamp" A..=) <$> Just (backgroundServiceBackgroundServiceEventTimestamp p),
+    ("origin" A..=) <$> Just (backgroundServiceBackgroundServiceEventOrigin p),
+    ("serviceWorkerRegistrationId" A..=) <$> Just (backgroundServiceBackgroundServiceEventServiceWorkerRegistrationId p),
+    ("service" A..=) <$> Just (backgroundServiceBackgroundServiceEventService p),
+    ("eventName" A..=) <$> Just (backgroundServiceBackgroundServiceEventEventName p),
+    ("instanceId" A..=) <$> Just (backgroundServiceBackgroundServiceEventInstanceId p),
+    ("eventMetadata" A..=) <$> Just (backgroundServiceBackgroundServiceEventEventMetadata p)
+    ]
+
+-- | Type of the 'BackgroundService.recordingStateChanged' event.
+data BackgroundServiceRecordingStateChanged = BackgroundServiceRecordingStateChanged
+  {
+    backgroundServiceRecordingStateChangedIsRecording :: Bool,
+    backgroundServiceRecordingStateChangedService :: BackgroundServiceServiceName
+  }
+  deriving (Eq, Show)
+instance FromJSON BackgroundServiceRecordingStateChanged where
+  parseJSON = A.withObject "BackgroundServiceRecordingStateChanged" $ \o -> BackgroundServiceRecordingStateChanged
+    <$> o A..: "isRecording"
+    <*> o A..: "service"
+instance Event BackgroundServiceRecordingStateChanged where
+  eventName _ = "BackgroundService.recordingStateChanged"
+
+-- | Type of the 'BackgroundService.backgroundServiceEventReceived' event.
+data BackgroundServiceBackgroundServiceEventReceived = BackgroundServiceBackgroundServiceEventReceived
+  {
+    backgroundServiceBackgroundServiceEventReceivedBackgroundServiceEvent :: BackgroundServiceBackgroundServiceEvent
+  }
+  deriving (Eq, Show)
+instance FromJSON BackgroundServiceBackgroundServiceEventReceived where
+  parseJSON = A.withObject "BackgroundServiceBackgroundServiceEventReceived" $ \o -> BackgroundServiceBackgroundServiceEventReceived
+    <$> o A..: "backgroundServiceEvent"
+instance Event BackgroundServiceBackgroundServiceEventReceived where
+  eventName _ = "BackgroundService.backgroundServiceEventReceived"
+
+-- | Enables event updates for the service.
+
+-- | Parameters of the 'BackgroundService.startObserving' command.
+data PBackgroundServiceStartObserving = PBackgroundServiceStartObserving
+  {
+    pBackgroundServiceStartObservingService :: BackgroundServiceServiceName
+  }
+  deriving (Eq, Show)
+pBackgroundServiceStartObserving
+  :: BackgroundServiceServiceName
+  -> PBackgroundServiceStartObserving
+pBackgroundServiceStartObserving
+  arg_pBackgroundServiceStartObservingService
+  = PBackgroundServiceStartObserving
+    arg_pBackgroundServiceStartObservingService
+instance ToJSON PBackgroundServiceStartObserving where
+  toJSON p = A.object $ catMaybes [
+    ("service" A..=) <$> Just (pBackgroundServiceStartObservingService p)
+    ]
+instance Command PBackgroundServiceStartObserving where
+  type CommandResponse PBackgroundServiceStartObserving = ()
+  commandName _ = "BackgroundService.startObserving"
+  fromJSON = const . A.Success . const ()
+
+-- | Disables event updates for the service.
+
+-- | Parameters of the 'BackgroundService.stopObserving' command.
+data PBackgroundServiceStopObserving = PBackgroundServiceStopObserving
+  {
+    pBackgroundServiceStopObservingService :: BackgroundServiceServiceName
+  }
+  deriving (Eq, Show)
+pBackgroundServiceStopObserving
+  :: BackgroundServiceServiceName
+  -> PBackgroundServiceStopObserving
+pBackgroundServiceStopObserving
+  arg_pBackgroundServiceStopObservingService
+  = PBackgroundServiceStopObserving
+    arg_pBackgroundServiceStopObservingService
+instance ToJSON PBackgroundServiceStopObserving where
+  toJSON p = A.object $ catMaybes [
+    ("service" A..=) <$> Just (pBackgroundServiceStopObservingService p)
+    ]
+instance Command PBackgroundServiceStopObserving where
+  type CommandResponse PBackgroundServiceStopObserving = ()
+  commandName _ = "BackgroundService.stopObserving"
+  fromJSON = const . A.Success . const ()
+
+-- | Set the recording state for the service.
+
+-- | Parameters of the 'BackgroundService.setRecording' command.
+data PBackgroundServiceSetRecording = PBackgroundServiceSetRecording
+  {
+    pBackgroundServiceSetRecordingShouldRecord :: Bool,
+    pBackgroundServiceSetRecordingService :: BackgroundServiceServiceName
+  }
+  deriving (Eq, Show)
+pBackgroundServiceSetRecording
+  :: Bool
+  -> BackgroundServiceServiceName
+  -> PBackgroundServiceSetRecording
+pBackgroundServiceSetRecording
+  arg_pBackgroundServiceSetRecordingShouldRecord
+  arg_pBackgroundServiceSetRecordingService
+  = PBackgroundServiceSetRecording
+    arg_pBackgroundServiceSetRecordingShouldRecord
+    arg_pBackgroundServiceSetRecordingService
+instance ToJSON PBackgroundServiceSetRecording where
+  toJSON p = A.object $ catMaybes [
+    ("shouldRecord" A..=) <$> Just (pBackgroundServiceSetRecordingShouldRecord p),
+    ("service" A..=) <$> Just (pBackgroundServiceSetRecordingService p)
+    ]
+instance Command PBackgroundServiceSetRecording where
+  type CommandResponse PBackgroundServiceSetRecording = ()
+  commandName _ = "BackgroundService.setRecording"
+  fromJSON = const . A.Success . const ()
+
+-- | Clears all stored data for the service.
+
+-- | Parameters of the 'BackgroundService.clearEvents' command.
+data PBackgroundServiceClearEvents = PBackgroundServiceClearEvents
+  {
+    pBackgroundServiceClearEventsService :: BackgroundServiceServiceName
+  }
+  deriving (Eq, Show)
+pBackgroundServiceClearEvents
+  :: BackgroundServiceServiceName
+  -> PBackgroundServiceClearEvents
+pBackgroundServiceClearEvents
+  arg_pBackgroundServiceClearEventsService
+  = PBackgroundServiceClearEvents
+    arg_pBackgroundServiceClearEventsService
+instance ToJSON PBackgroundServiceClearEvents where
+  toJSON p = A.object $ catMaybes [
+    ("service" A..=) <$> Just (pBackgroundServiceClearEventsService p)
+    ]
+instance Command PBackgroundServiceClearEvents where
+  type CommandResponse PBackgroundServiceClearEvents = ()
+  commandName _ = "BackgroundService.clearEvents"
+  fromJSON = const . A.Success . const ()
+
diff --git a/src/CDP/Domains/BrowserTarget.hs b/src/CDP/Domains/BrowserTarget.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains/BrowserTarget.hs
@@ -0,0 +1,1621 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+
+
+{- |
+= Browser
+
+The Browser domain defines methods and events for browser managing.
+= Target
+
+Supports additional targets discovery and allows to attach to them.
+-}
+
+
+module CDP.Domains.BrowserTarget (module CDP.Domains.BrowserTarget) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+
+import CDP.Domains.DOMPageNetworkEmulationSecurity as DOMPageNetworkEmulationSecurity
+
+
+-- | Type 'Browser.BrowserContextID'.
+type BrowserBrowserContextID = T.Text
+
+-- | Type 'Browser.WindowID'.
+type BrowserWindowID = Int
+
+-- | Type 'Browser.WindowState'.
+--   The state of the browser window.
+data BrowserWindowState = BrowserWindowStateNormal | BrowserWindowStateMinimized | BrowserWindowStateMaximized | BrowserWindowStateFullscreen
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON BrowserWindowState where
+  parseJSON = A.withText "BrowserWindowState" $ \v -> case v of
+    "normal" -> pure BrowserWindowStateNormal
+    "minimized" -> pure BrowserWindowStateMinimized
+    "maximized" -> pure BrowserWindowStateMaximized
+    "fullscreen" -> pure BrowserWindowStateFullscreen
+    "_" -> fail "failed to parse BrowserWindowState"
+instance ToJSON BrowserWindowState where
+  toJSON v = A.String $ case v of
+    BrowserWindowStateNormal -> "normal"
+    BrowserWindowStateMinimized -> "minimized"
+    BrowserWindowStateMaximized -> "maximized"
+    BrowserWindowStateFullscreen -> "fullscreen"
+
+-- | Type 'Browser.Bounds'.
+--   Browser window bounds information
+data BrowserBounds = BrowserBounds
+  {
+    -- | The offset from the left edge of the screen to the window in pixels.
+    browserBoundsLeft :: Maybe Int,
+    -- | The offset from the top edge of the screen to the window in pixels.
+    browserBoundsTop :: Maybe Int,
+    -- | The window width in pixels.
+    browserBoundsWidth :: Maybe Int,
+    -- | The window height in pixels.
+    browserBoundsHeight :: Maybe Int,
+    -- | The window state. Default to normal.
+    browserBoundsWindowState :: Maybe BrowserWindowState
+  }
+  deriving (Eq, Show)
+instance FromJSON BrowserBounds where
+  parseJSON = A.withObject "BrowserBounds" $ \o -> BrowserBounds
+    <$> o A..:? "left"
+    <*> o A..:? "top"
+    <*> o A..:? "width"
+    <*> o A..:? "height"
+    <*> o A..:? "windowState"
+instance ToJSON BrowserBounds where
+  toJSON p = A.object $ catMaybes [
+    ("left" A..=) <$> (browserBoundsLeft p),
+    ("top" A..=) <$> (browserBoundsTop p),
+    ("width" A..=) <$> (browserBoundsWidth p),
+    ("height" A..=) <$> (browserBoundsHeight p),
+    ("windowState" A..=) <$> (browserBoundsWindowState p)
+    ]
+
+-- | Type 'Browser.PermissionType'.
+data BrowserPermissionType = BrowserPermissionTypeAccessibilityEvents | BrowserPermissionTypeAudioCapture | BrowserPermissionTypeBackgroundSync | BrowserPermissionTypeBackgroundFetch | BrowserPermissionTypeClipboardReadWrite | BrowserPermissionTypeClipboardSanitizedWrite | BrowserPermissionTypeDisplayCapture | BrowserPermissionTypeDurableStorage | BrowserPermissionTypeFlash | BrowserPermissionTypeGeolocation | BrowserPermissionTypeMidi | BrowserPermissionTypeMidiSysex | BrowserPermissionTypeNfc | BrowserPermissionTypeNotifications | BrowserPermissionTypePaymentHandler | BrowserPermissionTypePeriodicBackgroundSync | BrowserPermissionTypeProtectedMediaIdentifier | BrowserPermissionTypeSensors | BrowserPermissionTypeVideoCapture | BrowserPermissionTypeVideoCapturePanTiltZoom | BrowserPermissionTypeIdleDetection | BrowserPermissionTypeWakeLockScreen | BrowserPermissionTypeWakeLockSystem
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON BrowserPermissionType where
+  parseJSON = A.withText "BrowserPermissionType" $ \v -> case v of
+    "accessibilityEvents" -> pure BrowserPermissionTypeAccessibilityEvents
+    "audioCapture" -> pure BrowserPermissionTypeAudioCapture
+    "backgroundSync" -> pure BrowserPermissionTypeBackgroundSync
+    "backgroundFetch" -> pure BrowserPermissionTypeBackgroundFetch
+    "clipboardReadWrite" -> pure BrowserPermissionTypeClipboardReadWrite
+    "clipboardSanitizedWrite" -> pure BrowserPermissionTypeClipboardSanitizedWrite
+    "displayCapture" -> pure BrowserPermissionTypeDisplayCapture
+    "durableStorage" -> pure BrowserPermissionTypeDurableStorage
+    "flash" -> pure BrowserPermissionTypeFlash
+    "geolocation" -> pure BrowserPermissionTypeGeolocation
+    "midi" -> pure BrowserPermissionTypeMidi
+    "midiSysex" -> pure BrowserPermissionTypeMidiSysex
+    "nfc" -> pure BrowserPermissionTypeNfc
+    "notifications" -> pure BrowserPermissionTypeNotifications
+    "paymentHandler" -> pure BrowserPermissionTypePaymentHandler
+    "periodicBackgroundSync" -> pure BrowserPermissionTypePeriodicBackgroundSync
+    "protectedMediaIdentifier" -> pure BrowserPermissionTypeProtectedMediaIdentifier
+    "sensors" -> pure BrowserPermissionTypeSensors
+    "videoCapture" -> pure BrowserPermissionTypeVideoCapture
+    "videoCapturePanTiltZoom" -> pure BrowserPermissionTypeVideoCapturePanTiltZoom
+    "idleDetection" -> pure BrowserPermissionTypeIdleDetection
+    "wakeLockScreen" -> pure BrowserPermissionTypeWakeLockScreen
+    "wakeLockSystem" -> pure BrowserPermissionTypeWakeLockSystem
+    "_" -> fail "failed to parse BrowserPermissionType"
+instance ToJSON BrowserPermissionType where
+  toJSON v = A.String $ case v of
+    BrowserPermissionTypeAccessibilityEvents -> "accessibilityEvents"
+    BrowserPermissionTypeAudioCapture -> "audioCapture"
+    BrowserPermissionTypeBackgroundSync -> "backgroundSync"
+    BrowserPermissionTypeBackgroundFetch -> "backgroundFetch"
+    BrowserPermissionTypeClipboardReadWrite -> "clipboardReadWrite"
+    BrowserPermissionTypeClipboardSanitizedWrite -> "clipboardSanitizedWrite"
+    BrowserPermissionTypeDisplayCapture -> "displayCapture"
+    BrowserPermissionTypeDurableStorage -> "durableStorage"
+    BrowserPermissionTypeFlash -> "flash"
+    BrowserPermissionTypeGeolocation -> "geolocation"
+    BrowserPermissionTypeMidi -> "midi"
+    BrowserPermissionTypeMidiSysex -> "midiSysex"
+    BrowserPermissionTypeNfc -> "nfc"
+    BrowserPermissionTypeNotifications -> "notifications"
+    BrowserPermissionTypePaymentHandler -> "paymentHandler"
+    BrowserPermissionTypePeriodicBackgroundSync -> "periodicBackgroundSync"
+    BrowserPermissionTypeProtectedMediaIdentifier -> "protectedMediaIdentifier"
+    BrowserPermissionTypeSensors -> "sensors"
+    BrowserPermissionTypeVideoCapture -> "videoCapture"
+    BrowserPermissionTypeVideoCapturePanTiltZoom -> "videoCapturePanTiltZoom"
+    BrowserPermissionTypeIdleDetection -> "idleDetection"
+    BrowserPermissionTypeWakeLockScreen -> "wakeLockScreen"
+    BrowserPermissionTypeWakeLockSystem -> "wakeLockSystem"
+
+-- | Type 'Browser.PermissionSetting'.
+data BrowserPermissionSetting = BrowserPermissionSettingGranted | BrowserPermissionSettingDenied | BrowserPermissionSettingPrompt
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON BrowserPermissionSetting where
+  parseJSON = A.withText "BrowserPermissionSetting" $ \v -> case v of
+    "granted" -> pure BrowserPermissionSettingGranted
+    "denied" -> pure BrowserPermissionSettingDenied
+    "prompt" -> pure BrowserPermissionSettingPrompt
+    "_" -> fail "failed to parse BrowserPermissionSetting"
+instance ToJSON BrowserPermissionSetting where
+  toJSON v = A.String $ case v of
+    BrowserPermissionSettingGranted -> "granted"
+    BrowserPermissionSettingDenied -> "denied"
+    BrowserPermissionSettingPrompt -> "prompt"
+
+-- | Type 'Browser.PermissionDescriptor'.
+--   Definition of PermissionDescriptor defined in the Permissions API:
+--   https://w3c.github.io/permissions/#dictdef-permissiondescriptor.
+data BrowserPermissionDescriptor = BrowserPermissionDescriptor
+  {
+    -- | Name of permission.
+    --   See https://cs.chromium.org/chromium/src/third_party/blink/renderer/modules/permissions/permission_descriptor.idl for valid permission names.
+    browserPermissionDescriptorName :: T.Text,
+    -- | For "midi" permission, may also specify sysex control.
+    browserPermissionDescriptorSysex :: Maybe Bool,
+    -- | For "push" permission, may specify userVisibleOnly.
+    --   Note that userVisibleOnly = true is the only currently supported type.
+    browserPermissionDescriptorUserVisibleOnly :: Maybe Bool,
+    -- | For "clipboard" permission, may specify allowWithoutSanitization.
+    browserPermissionDescriptorAllowWithoutSanitization :: Maybe Bool,
+    -- | For "camera" permission, may specify panTiltZoom.
+    browserPermissionDescriptorPanTiltZoom :: Maybe Bool
+  }
+  deriving (Eq, Show)
+instance FromJSON BrowserPermissionDescriptor where
+  parseJSON = A.withObject "BrowserPermissionDescriptor" $ \o -> BrowserPermissionDescriptor
+    <$> o A..: "name"
+    <*> o A..:? "sysex"
+    <*> o A..:? "userVisibleOnly"
+    <*> o A..:? "allowWithoutSanitization"
+    <*> o A..:? "panTiltZoom"
+instance ToJSON BrowserPermissionDescriptor where
+  toJSON p = A.object $ catMaybes [
+    ("name" A..=) <$> Just (browserPermissionDescriptorName p),
+    ("sysex" A..=) <$> (browserPermissionDescriptorSysex p),
+    ("userVisibleOnly" A..=) <$> (browserPermissionDescriptorUserVisibleOnly p),
+    ("allowWithoutSanitization" A..=) <$> (browserPermissionDescriptorAllowWithoutSanitization p),
+    ("panTiltZoom" A..=) <$> (browserPermissionDescriptorPanTiltZoom p)
+    ]
+
+-- | Type 'Browser.BrowserCommandId'.
+--   Browser command ids used by executeBrowserCommand.
+data BrowserBrowserCommandId = BrowserBrowserCommandIdOpenTabSearch | BrowserBrowserCommandIdCloseTabSearch
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON BrowserBrowserCommandId where
+  parseJSON = A.withText "BrowserBrowserCommandId" $ \v -> case v of
+    "openTabSearch" -> pure BrowserBrowserCommandIdOpenTabSearch
+    "closeTabSearch" -> pure BrowserBrowserCommandIdCloseTabSearch
+    "_" -> fail "failed to parse BrowserBrowserCommandId"
+instance ToJSON BrowserBrowserCommandId where
+  toJSON v = A.String $ case v of
+    BrowserBrowserCommandIdOpenTabSearch -> "openTabSearch"
+    BrowserBrowserCommandIdCloseTabSearch -> "closeTabSearch"
+
+-- | Type 'Browser.Bucket'.
+--   Chrome histogram bucket.
+data BrowserBucket = BrowserBucket
+  {
+    -- | Minimum value (inclusive).
+    browserBucketLow :: Int,
+    -- | Maximum value (exclusive).
+    browserBucketHigh :: Int,
+    -- | Number of samples.
+    browserBucketCount :: Int
+  }
+  deriving (Eq, Show)
+instance FromJSON BrowserBucket where
+  parseJSON = A.withObject "BrowserBucket" $ \o -> BrowserBucket
+    <$> o A..: "low"
+    <*> o A..: "high"
+    <*> o A..: "count"
+instance ToJSON BrowserBucket where
+  toJSON p = A.object $ catMaybes [
+    ("low" A..=) <$> Just (browserBucketLow p),
+    ("high" A..=) <$> Just (browserBucketHigh p),
+    ("count" A..=) <$> Just (browserBucketCount p)
+    ]
+
+-- | Type 'Browser.Histogram'.
+--   Chrome histogram.
+data BrowserHistogram = BrowserHistogram
+  {
+    -- | Name.
+    browserHistogramName :: T.Text,
+    -- | Sum of sample values.
+    browserHistogramSum :: Int,
+    -- | Total number of samples.
+    browserHistogramCount :: Int,
+    -- | Buckets.
+    browserHistogramBuckets :: [BrowserBucket]
+  }
+  deriving (Eq, Show)
+instance FromJSON BrowserHistogram where
+  parseJSON = A.withObject "BrowserHistogram" $ \o -> BrowserHistogram
+    <$> o A..: "name"
+    <*> o A..: "sum"
+    <*> o A..: "count"
+    <*> o A..: "buckets"
+instance ToJSON BrowserHistogram where
+  toJSON p = A.object $ catMaybes [
+    ("name" A..=) <$> Just (browserHistogramName p),
+    ("sum" A..=) <$> Just (browserHistogramSum p),
+    ("count" A..=) <$> Just (browserHistogramCount p),
+    ("buckets" A..=) <$> Just (browserHistogramBuckets p)
+    ]
+
+-- | Type of the 'Browser.downloadWillBegin' event.
+data BrowserDownloadWillBegin = BrowserDownloadWillBegin
+  {
+    -- | Id of the frame that caused the download to begin.
+    browserDownloadWillBeginFrameId :: DOMPageNetworkEmulationSecurity.PageFrameId,
+    -- | Global unique identifier of the download.
+    browserDownloadWillBeginGuid :: T.Text,
+    -- | URL of the resource being downloaded.
+    browserDownloadWillBeginUrl :: T.Text,
+    -- | Suggested file name of the resource (the actual name of the file saved on disk may differ).
+    browserDownloadWillBeginSuggestedFilename :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON BrowserDownloadWillBegin where
+  parseJSON = A.withObject "BrowserDownloadWillBegin" $ \o -> BrowserDownloadWillBegin
+    <$> o A..: "frameId"
+    <*> o A..: "guid"
+    <*> o A..: "url"
+    <*> o A..: "suggestedFilename"
+instance Event BrowserDownloadWillBegin where
+  eventName _ = "Browser.downloadWillBegin"
+
+-- | Type of the 'Browser.downloadProgress' event.
+data BrowserDownloadProgressState = BrowserDownloadProgressStateInProgress | BrowserDownloadProgressStateCompleted | BrowserDownloadProgressStateCanceled
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON BrowserDownloadProgressState where
+  parseJSON = A.withText "BrowserDownloadProgressState" $ \v -> case v of
+    "inProgress" -> pure BrowserDownloadProgressStateInProgress
+    "completed" -> pure BrowserDownloadProgressStateCompleted
+    "canceled" -> pure BrowserDownloadProgressStateCanceled
+    "_" -> fail "failed to parse BrowserDownloadProgressState"
+instance ToJSON BrowserDownloadProgressState where
+  toJSON v = A.String $ case v of
+    BrowserDownloadProgressStateInProgress -> "inProgress"
+    BrowserDownloadProgressStateCompleted -> "completed"
+    BrowserDownloadProgressStateCanceled -> "canceled"
+data BrowserDownloadProgress = BrowserDownloadProgress
+  {
+    -- | Global unique identifier of the download.
+    browserDownloadProgressGuid :: T.Text,
+    -- | Total expected bytes to download.
+    browserDownloadProgressTotalBytes :: Double,
+    -- | Total bytes received.
+    browserDownloadProgressReceivedBytes :: Double,
+    -- | Download status.
+    browserDownloadProgressState :: BrowserDownloadProgressState
+  }
+  deriving (Eq, Show)
+instance FromJSON BrowserDownloadProgress where
+  parseJSON = A.withObject "BrowserDownloadProgress" $ \o -> BrowserDownloadProgress
+    <$> o A..: "guid"
+    <*> o A..: "totalBytes"
+    <*> o A..: "receivedBytes"
+    <*> o A..: "state"
+instance Event BrowserDownloadProgress where
+  eventName _ = "Browser.downloadProgress"
+
+-- | Set permission settings for given origin.
+
+-- | Parameters of the 'Browser.setPermission' command.
+data PBrowserSetPermission = PBrowserSetPermission
+  {
+    -- | Descriptor of permission to override.
+    pBrowserSetPermissionPermission :: BrowserPermissionDescriptor,
+    -- | Setting of the permission.
+    pBrowserSetPermissionSetting :: BrowserPermissionSetting,
+    -- | Origin the permission applies to, all origins if not specified.
+    pBrowserSetPermissionOrigin :: Maybe T.Text,
+    -- | Context to override. When omitted, default browser context is used.
+    pBrowserSetPermissionBrowserContextId :: Maybe BrowserBrowserContextID
+  }
+  deriving (Eq, Show)
+pBrowserSetPermission
+  {-
+  -- | Descriptor of permission to override.
+  -}
+  :: BrowserPermissionDescriptor
+  {-
+  -- | Setting of the permission.
+  -}
+  -> BrowserPermissionSetting
+  -> PBrowserSetPermission
+pBrowserSetPermission
+  arg_pBrowserSetPermissionPermission
+  arg_pBrowserSetPermissionSetting
+  = PBrowserSetPermission
+    arg_pBrowserSetPermissionPermission
+    arg_pBrowserSetPermissionSetting
+    Nothing
+    Nothing
+instance ToJSON PBrowserSetPermission where
+  toJSON p = A.object $ catMaybes [
+    ("permission" A..=) <$> Just (pBrowserSetPermissionPermission p),
+    ("setting" A..=) <$> Just (pBrowserSetPermissionSetting p),
+    ("origin" A..=) <$> (pBrowserSetPermissionOrigin p),
+    ("browserContextId" A..=) <$> (pBrowserSetPermissionBrowserContextId p)
+    ]
+instance Command PBrowserSetPermission where
+  type CommandResponse PBrowserSetPermission = ()
+  commandName _ = "Browser.setPermission"
+  fromJSON = const . A.Success . const ()
+
+-- | Grant specific permissions to the given origin and reject all others.
+
+-- | Parameters of the 'Browser.grantPermissions' command.
+data PBrowserGrantPermissions = PBrowserGrantPermissions
+  {
+    pBrowserGrantPermissionsPermissions :: [BrowserPermissionType],
+    -- | Origin the permission applies to, all origins if not specified.
+    pBrowserGrantPermissionsOrigin :: Maybe T.Text,
+    -- | BrowserContext to override permissions. When omitted, default browser context is used.
+    pBrowserGrantPermissionsBrowserContextId :: Maybe BrowserBrowserContextID
+  }
+  deriving (Eq, Show)
+pBrowserGrantPermissions
+  :: [BrowserPermissionType]
+  -> PBrowserGrantPermissions
+pBrowserGrantPermissions
+  arg_pBrowserGrantPermissionsPermissions
+  = PBrowserGrantPermissions
+    arg_pBrowserGrantPermissionsPermissions
+    Nothing
+    Nothing
+instance ToJSON PBrowserGrantPermissions where
+  toJSON p = A.object $ catMaybes [
+    ("permissions" A..=) <$> Just (pBrowserGrantPermissionsPermissions p),
+    ("origin" A..=) <$> (pBrowserGrantPermissionsOrigin p),
+    ("browserContextId" A..=) <$> (pBrowserGrantPermissionsBrowserContextId p)
+    ]
+instance Command PBrowserGrantPermissions where
+  type CommandResponse PBrowserGrantPermissions = ()
+  commandName _ = "Browser.grantPermissions"
+  fromJSON = const . A.Success . const ()
+
+-- | Reset all permission management for all origins.
+
+-- | Parameters of the 'Browser.resetPermissions' command.
+data PBrowserResetPermissions = PBrowserResetPermissions
+  {
+    -- | BrowserContext to reset permissions. When omitted, default browser context is used.
+    pBrowserResetPermissionsBrowserContextId :: Maybe BrowserBrowserContextID
+  }
+  deriving (Eq, Show)
+pBrowserResetPermissions
+  :: PBrowserResetPermissions
+pBrowserResetPermissions
+  = PBrowserResetPermissions
+    Nothing
+instance ToJSON PBrowserResetPermissions where
+  toJSON p = A.object $ catMaybes [
+    ("browserContextId" A..=) <$> (pBrowserResetPermissionsBrowserContextId p)
+    ]
+instance Command PBrowserResetPermissions where
+  type CommandResponse PBrowserResetPermissions = ()
+  commandName _ = "Browser.resetPermissions"
+  fromJSON = const . A.Success . const ()
+
+-- | Set the behavior when downloading a file.
+
+-- | Parameters of the 'Browser.setDownloadBehavior' command.
+data PBrowserSetDownloadBehaviorBehavior = PBrowserSetDownloadBehaviorBehaviorDeny | PBrowserSetDownloadBehaviorBehaviorAllow | PBrowserSetDownloadBehaviorBehaviorAllowAndName | PBrowserSetDownloadBehaviorBehaviorDefault
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PBrowserSetDownloadBehaviorBehavior where
+  parseJSON = A.withText "PBrowserSetDownloadBehaviorBehavior" $ \v -> case v of
+    "deny" -> pure PBrowserSetDownloadBehaviorBehaviorDeny
+    "allow" -> pure PBrowserSetDownloadBehaviorBehaviorAllow
+    "allowAndName" -> pure PBrowserSetDownloadBehaviorBehaviorAllowAndName
+    "default" -> pure PBrowserSetDownloadBehaviorBehaviorDefault
+    "_" -> fail "failed to parse PBrowserSetDownloadBehaviorBehavior"
+instance ToJSON PBrowserSetDownloadBehaviorBehavior where
+  toJSON v = A.String $ case v of
+    PBrowserSetDownloadBehaviorBehaviorDeny -> "deny"
+    PBrowserSetDownloadBehaviorBehaviorAllow -> "allow"
+    PBrowserSetDownloadBehaviorBehaviorAllowAndName -> "allowAndName"
+    PBrowserSetDownloadBehaviorBehaviorDefault -> "default"
+data PBrowserSetDownloadBehavior = PBrowserSetDownloadBehavior
+  {
+    -- | Whether to allow all or deny all download requests, or use default Chrome behavior if
+    --   available (otherwise deny). |allowAndName| allows download and names files according to
+    --   their dowmload guids.
+    pBrowserSetDownloadBehaviorBehavior :: PBrowserSetDownloadBehaviorBehavior,
+    -- | BrowserContext to set download behavior. When omitted, default browser context is used.
+    pBrowserSetDownloadBehaviorBrowserContextId :: Maybe BrowserBrowserContextID,
+    -- | The default path to save downloaded files to. This is required if behavior is set to 'allow'
+    --   or 'allowAndName'.
+    pBrowserSetDownloadBehaviorDownloadPath :: Maybe T.Text,
+    -- | Whether to emit download events (defaults to false).
+    pBrowserSetDownloadBehaviorEventsEnabled :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pBrowserSetDownloadBehavior
+  {-
+  -- | Whether to allow all or deny all download requests, or use default Chrome behavior if
+  --   available (otherwise deny). |allowAndName| allows download and names files according to
+  --   their dowmload guids.
+  -}
+  :: PBrowserSetDownloadBehaviorBehavior
+  -> PBrowserSetDownloadBehavior
+pBrowserSetDownloadBehavior
+  arg_pBrowserSetDownloadBehaviorBehavior
+  = PBrowserSetDownloadBehavior
+    arg_pBrowserSetDownloadBehaviorBehavior
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PBrowserSetDownloadBehavior where
+  toJSON p = A.object $ catMaybes [
+    ("behavior" A..=) <$> Just (pBrowserSetDownloadBehaviorBehavior p),
+    ("browserContextId" A..=) <$> (pBrowserSetDownloadBehaviorBrowserContextId p),
+    ("downloadPath" A..=) <$> (pBrowserSetDownloadBehaviorDownloadPath p),
+    ("eventsEnabled" A..=) <$> (pBrowserSetDownloadBehaviorEventsEnabled p)
+    ]
+instance Command PBrowserSetDownloadBehavior where
+  type CommandResponse PBrowserSetDownloadBehavior = ()
+  commandName _ = "Browser.setDownloadBehavior"
+  fromJSON = const . A.Success . const ()
+
+-- | Cancel a download if in progress
+
+-- | Parameters of the 'Browser.cancelDownload' command.
+data PBrowserCancelDownload = PBrowserCancelDownload
+  {
+    -- | Global unique identifier of the download.
+    pBrowserCancelDownloadGuid :: T.Text,
+    -- | BrowserContext to perform the action in. When omitted, default browser context is used.
+    pBrowserCancelDownloadBrowserContextId :: Maybe BrowserBrowserContextID
+  }
+  deriving (Eq, Show)
+pBrowserCancelDownload
+  {-
+  -- | Global unique identifier of the download.
+  -}
+  :: T.Text
+  -> PBrowserCancelDownload
+pBrowserCancelDownload
+  arg_pBrowserCancelDownloadGuid
+  = PBrowserCancelDownload
+    arg_pBrowserCancelDownloadGuid
+    Nothing
+instance ToJSON PBrowserCancelDownload where
+  toJSON p = A.object $ catMaybes [
+    ("guid" A..=) <$> Just (pBrowserCancelDownloadGuid p),
+    ("browserContextId" A..=) <$> (pBrowserCancelDownloadBrowserContextId p)
+    ]
+instance Command PBrowserCancelDownload where
+  type CommandResponse PBrowserCancelDownload = ()
+  commandName _ = "Browser.cancelDownload"
+  fromJSON = const . A.Success . const ()
+
+-- | Close browser gracefully.
+
+-- | Parameters of the 'Browser.close' command.
+data PBrowserClose = PBrowserClose
+  deriving (Eq, Show)
+pBrowserClose
+  :: PBrowserClose
+pBrowserClose
+  = PBrowserClose
+instance ToJSON PBrowserClose where
+  toJSON _ = A.Null
+instance Command PBrowserClose where
+  type CommandResponse PBrowserClose = ()
+  commandName _ = "Browser.close"
+  fromJSON = const . A.Success . const ()
+
+-- | Crashes browser on the main thread.
+
+-- | Parameters of the 'Browser.crash' command.
+data PBrowserCrash = PBrowserCrash
+  deriving (Eq, Show)
+pBrowserCrash
+  :: PBrowserCrash
+pBrowserCrash
+  = PBrowserCrash
+instance ToJSON PBrowserCrash where
+  toJSON _ = A.Null
+instance Command PBrowserCrash where
+  type CommandResponse PBrowserCrash = ()
+  commandName _ = "Browser.crash"
+  fromJSON = const . A.Success . const ()
+
+-- | Crashes GPU process.
+
+-- | Parameters of the 'Browser.crashGpuProcess' command.
+data PBrowserCrashGpuProcess = PBrowserCrashGpuProcess
+  deriving (Eq, Show)
+pBrowserCrashGpuProcess
+  :: PBrowserCrashGpuProcess
+pBrowserCrashGpuProcess
+  = PBrowserCrashGpuProcess
+instance ToJSON PBrowserCrashGpuProcess where
+  toJSON _ = A.Null
+instance Command PBrowserCrashGpuProcess where
+  type CommandResponse PBrowserCrashGpuProcess = ()
+  commandName _ = "Browser.crashGpuProcess"
+  fromJSON = const . A.Success . const ()
+
+-- | Returns version information.
+
+-- | Parameters of the 'Browser.getVersion' command.
+data PBrowserGetVersion = PBrowserGetVersion
+  deriving (Eq, Show)
+pBrowserGetVersion
+  :: PBrowserGetVersion
+pBrowserGetVersion
+  = PBrowserGetVersion
+instance ToJSON PBrowserGetVersion where
+  toJSON _ = A.Null
+data BrowserGetVersion = BrowserGetVersion
+  {
+    -- | Protocol version.
+    browserGetVersionProtocolVersion :: T.Text,
+    -- | Product name.
+    browserGetVersionProduct :: T.Text,
+    -- | Product revision.
+    browserGetVersionRevision :: T.Text,
+    -- | User-Agent.
+    browserGetVersionUserAgent :: T.Text,
+    -- | V8 version.
+    browserGetVersionJsVersion :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON BrowserGetVersion where
+  parseJSON = A.withObject "BrowserGetVersion" $ \o -> BrowserGetVersion
+    <$> o A..: "protocolVersion"
+    <*> o A..: "product"
+    <*> o A..: "revision"
+    <*> o A..: "userAgent"
+    <*> o A..: "jsVersion"
+instance Command PBrowserGetVersion where
+  type CommandResponse PBrowserGetVersion = BrowserGetVersion
+  commandName _ = "Browser.getVersion"
+
+-- | Returns the command line switches for the browser process if, and only if
+--   --enable-automation is on the commandline.
+
+-- | Parameters of the 'Browser.getBrowserCommandLine' command.
+data PBrowserGetBrowserCommandLine = PBrowserGetBrowserCommandLine
+  deriving (Eq, Show)
+pBrowserGetBrowserCommandLine
+  :: PBrowserGetBrowserCommandLine
+pBrowserGetBrowserCommandLine
+  = PBrowserGetBrowserCommandLine
+instance ToJSON PBrowserGetBrowserCommandLine where
+  toJSON _ = A.Null
+data BrowserGetBrowserCommandLine = BrowserGetBrowserCommandLine
+  {
+    -- | Commandline parameters
+    browserGetBrowserCommandLineArguments :: [T.Text]
+  }
+  deriving (Eq, Show)
+instance FromJSON BrowserGetBrowserCommandLine where
+  parseJSON = A.withObject "BrowserGetBrowserCommandLine" $ \o -> BrowserGetBrowserCommandLine
+    <$> o A..: "arguments"
+instance Command PBrowserGetBrowserCommandLine where
+  type CommandResponse PBrowserGetBrowserCommandLine = BrowserGetBrowserCommandLine
+  commandName _ = "Browser.getBrowserCommandLine"
+
+-- | Get Chrome histograms.
+
+-- | Parameters of the 'Browser.getHistograms' command.
+data PBrowserGetHistograms = PBrowserGetHistograms
+  {
+    -- | Requested substring in name. Only histograms which have query as a
+    --   substring in their name are extracted. An empty or absent query returns
+    --   all histograms.
+    pBrowserGetHistogramsQuery :: Maybe T.Text,
+    -- | If true, retrieve delta since last call.
+    pBrowserGetHistogramsDelta :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pBrowserGetHistograms
+  :: PBrowserGetHistograms
+pBrowserGetHistograms
+  = PBrowserGetHistograms
+    Nothing
+    Nothing
+instance ToJSON PBrowserGetHistograms where
+  toJSON p = A.object $ catMaybes [
+    ("query" A..=) <$> (pBrowserGetHistogramsQuery p),
+    ("delta" A..=) <$> (pBrowserGetHistogramsDelta p)
+    ]
+data BrowserGetHistograms = BrowserGetHistograms
+  {
+    -- | Histograms.
+    browserGetHistogramsHistograms :: [BrowserHistogram]
+  }
+  deriving (Eq, Show)
+instance FromJSON BrowserGetHistograms where
+  parseJSON = A.withObject "BrowserGetHistograms" $ \o -> BrowserGetHistograms
+    <$> o A..: "histograms"
+instance Command PBrowserGetHistograms where
+  type CommandResponse PBrowserGetHistograms = BrowserGetHistograms
+  commandName _ = "Browser.getHistograms"
+
+-- | Get a Chrome histogram by name.
+
+-- | Parameters of the 'Browser.getHistogram' command.
+data PBrowserGetHistogram = PBrowserGetHistogram
+  {
+    -- | Requested histogram name.
+    pBrowserGetHistogramName :: T.Text,
+    -- | If true, retrieve delta since last call.
+    pBrowserGetHistogramDelta :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pBrowserGetHistogram
+  {-
+  -- | Requested histogram name.
+  -}
+  :: T.Text
+  -> PBrowserGetHistogram
+pBrowserGetHistogram
+  arg_pBrowserGetHistogramName
+  = PBrowserGetHistogram
+    arg_pBrowserGetHistogramName
+    Nothing
+instance ToJSON PBrowserGetHistogram where
+  toJSON p = A.object $ catMaybes [
+    ("name" A..=) <$> Just (pBrowserGetHistogramName p),
+    ("delta" A..=) <$> (pBrowserGetHistogramDelta p)
+    ]
+data BrowserGetHistogram = BrowserGetHistogram
+  {
+    -- | Histogram.
+    browserGetHistogramHistogram :: BrowserHistogram
+  }
+  deriving (Eq, Show)
+instance FromJSON BrowserGetHistogram where
+  parseJSON = A.withObject "BrowserGetHistogram" $ \o -> BrowserGetHistogram
+    <$> o A..: "histogram"
+instance Command PBrowserGetHistogram where
+  type CommandResponse PBrowserGetHistogram = BrowserGetHistogram
+  commandName _ = "Browser.getHistogram"
+
+-- | Get position and size of the browser window.
+
+-- | Parameters of the 'Browser.getWindowBounds' command.
+data PBrowserGetWindowBounds = PBrowserGetWindowBounds
+  {
+    -- | Browser window id.
+    pBrowserGetWindowBoundsWindowId :: BrowserWindowID
+  }
+  deriving (Eq, Show)
+pBrowserGetWindowBounds
+  {-
+  -- | Browser window id.
+  -}
+  :: BrowserWindowID
+  -> PBrowserGetWindowBounds
+pBrowserGetWindowBounds
+  arg_pBrowserGetWindowBoundsWindowId
+  = PBrowserGetWindowBounds
+    arg_pBrowserGetWindowBoundsWindowId
+instance ToJSON PBrowserGetWindowBounds where
+  toJSON p = A.object $ catMaybes [
+    ("windowId" A..=) <$> Just (pBrowserGetWindowBoundsWindowId p)
+    ]
+data BrowserGetWindowBounds = BrowserGetWindowBounds
+  {
+    -- | Bounds information of the window. When window state is 'minimized', the restored window
+    --   position and size are returned.
+    browserGetWindowBoundsBounds :: BrowserBounds
+  }
+  deriving (Eq, Show)
+instance FromJSON BrowserGetWindowBounds where
+  parseJSON = A.withObject "BrowserGetWindowBounds" $ \o -> BrowserGetWindowBounds
+    <$> o A..: "bounds"
+instance Command PBrowserGetWindowBounds where
+  type CommandResponse PBrowserGetWindowBounds = BrowserGetWindowBounds
+  commandName _ = "Browser.getWindowBounds"
+
+-- | Get the browser window that contains the devtools target.
+
+-- | Parameters of the 'Browser.getWindowForTarget' command.
+data PBrowserGetWindowForTarget = PBrowserGetWindowForTarget
+  {
+    -- | Devtools agent host id. If called as a part of the session, associated targetId is used.
+    pBrowserGetWindowForTargetTargetId :: Maybe TargetTargetID
+  }
+  deriving (Eq, Show)
+pBrowserGetWindowForTarget
+  :: PBrowserGetWindowForTarget
+pBrowserGetWindowForTarget
+  = PBrowserGetWindowForTarget
+    Nothing
+instance ToJSON PBrowserGetWindowForTarget where
+  toJSON p = A.object $ catMaybes [
+    ("targetId" A..=) <$> (pBrowserGetWindowForTargetTargetId p)
+    ]
+data BrowserGetWindowForTarget = BrowserGetWindowForTarget
+  {
+    -- | Browser window id.
+    browserGetWindowForTargetWindowId :: BrowserWindowID,
+    -- | Bounds information of the window. When window state is 'minimized', the restored window
+    --   position and size are returned.
+    browserGetWindowForTargetBounds :: BrowserBounds
+  }
+  deriving (Eq, Show)
+instance FromJSON BrowserGetWindowForTarget where
+  parseJSON = A.withObject "BrowserGetWindowForTarget" $ \o -> BrowserGetWindowForTarget
+    <$> o A..: "windowId"
+    <*> o A..: "bounds"
+instance Command PBrowserGetWindowForTarget where
+  type CommandResponse PBrowserGetWindowForTarget = BrowserGetWindowForTarget
+  commandName _ = "Browser.getWindowForTarget"
+
+-- | Set position and/or size of the browser window.
+
+-- | Parameters of the 'Browser.setWindowBounds' command.
+data PBrowserSetWindowBounds = PBrowserSetWindowBounds
+  {
+    -- | Browser window id.
+    pBrowserSetWindowBoundsWindowId :: BrowserWindowID,
+    -- | New window bounds. The 'minimized', 'maximized' and 'fullscreen' states cannot be combined
+    --   with 'left', 'top', 'width' or 'height'. Leaves unspecified fields unchanged.
+    pBrowserSetWindowBoundsBounds :: BrowserBounds
+  }
+  deriving (Eq, Show)
+pBrowserSetWindowBounds
+  {-
+  -- | Browser window id.
+  -}
+  :: BrowserWindowID
+  {-
+  -- | New window bounds. The 'minimized', 'maximized' and 'fullscreen' states cannot be combined
+  --   with 'left', 'top', 'width' or 'height'. Leaves unspecified fields unchanged.
+  -}
+  -> BrowserBounds
+  -> PBrowserSetWindowBounds
+pBrowserSetWindowBounds
+  arg_pBrowserSetWindowBoundsWindowId
+  arg_pBrowserSetWindowBoundsBounds
+  = PBrowserSetWindowBounds
+    arg_pBrowserSetWindowBoundsWindowId
+    arg_pBrowserSetWindowBoundsBounds
+instance ToJSON PBrowserSetWindowBounds where
+  toJSON p = A.object $ catMaybes [
+    ("windowId" A..=) <$> Just (pBrowserSetWindowBoundsWindowId p),
+    ("bounds" A..=) <$> Just (pBrowserSetWindowBoundsBounds p)
+    ]
+instance Command PBrowserSetWindowBounds where
+  type CommandResponse PBrowserSetWindowBounds = ()
+  commandName _ = "Browser.setWindowBounds"
+  fromJSON = const . A.Success . const ()
+
+-- | Set dock tile details, platform-specific.
+
+-- | Parameters of the 'Browser.setDockTile' command.
+data PBrowserSetDockTile = PBrowserSetDockTile
+  {
+    pBrowserSetDockTileBadgeLabel :: Maybe T.Text,
+    -- | Png encoded image. (Encoded as a base64 string when passed over JSON)
+    pBrowserSetDockTileImage :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+pBrowserSetDockTile
+  :: PBrowserSetDockTile
+pBrowserSetDockTile
+  = PBrowserSetDockTile
+    Nothing
+    Nothing
+instance ToJSON PBrowserSetDockTile where
+  toJSON p = A.object $ catMaybes [
+    ("badgeLabel" A..=) <$> (pBrowserSetDockTileBadgeLabel p),
+    ("image" A..=) <$> (pBrowserSetDockTileImage p)
+    ]
+instance Command PBrowserSetDockTile where
+  type CommandResponse PBrowserSetDockTile = ()
+  commandName _ = "Browser.setDockTile"
+  fromJSON = const . A.Success . const ()
+
+-- | Invoke custom browser commands used by telemetry.
+
+-- | Parameters of the 'Browser.executeBrowserCommand' command.
+data PBrowserExecuteBrowserCommand = PBrowserExecuteBrowserCommand
+  {
+    pBrowserExecuteBrowserCommandCommandId :: BrowserBrowserCommandId
+  }
+  deriving (Eq, Show)
+pBrowserExecuteBrowserCommand
+  :: BrowserBrowserCommandId
+  -> PBrowserExecuteBrowserCommand
+pBrowserExecuteBrowserCommand
+  arg_pBrowserExecuteBrowserCommandCommandId
+  = PBrowserExecuteBrowserCommand
+    arg_pBrowserExecuteBrowserCommandCommandId
+instance ToJSON PBrowserExecuteBrowserCommand where
+  toJSON p = A.object $ catMaybes [
+    ("commandId" A..=) <$> Just (pBrowserExecuteBrowserCommandCommandId p)
+    ]
+instance Command PBrowserExecuteBrowserCommand where
+  type CommandResponse PBrowserExecuteBrowserCommand = ()
+  commandName _ = "Browser.executeBrowserCommand"
+  fromJSON = const . A.Success . const ()
+
+-- | Type 'Target.TargetID'.
+type TargetTargetID = T.Text
+
+-- | Type 'Target.SessionID'.
+--   Unique identifier of attached debugging session.
+type TargetSessionID = T.Text
+
+-- | Type 'Target.TargetInfo'.
+data TargetTargetInfo = TargetTargetInfo
+  {
+    targetTargetInfoTargetId :: TargetTargetID,
+    targetTargetInfoType :: T.Text,
+    targetTargetInfoTitle :: T.Text,
+    targetTargetInfoUrl :: T.Text,
+    -- | Whether the target has an attached client.
+    targetTargetInfoAttached :: Bool,
+    -- | Opener target Id
+    targetTargetInfoOpenerId :: Maybe TargetTargetID,
+    -- | Whether the target has access to the originating window.
+    targetTargetInfoCanAccessOpener :: Bool,
+    -- | Frame id of originating window (is only set if target has an opener).
+    targetTargetInfoOpenerFrameId :: Maybe DOMPageNetworkEmulationSecurity.PageFrameId,
+    targetTargetInfoBrowserContextId :: Maybe BrowserBrowserContextID,
+    -- | Provides additional details for specific target types. For example, for
+    --   the type of "page", this may be set to "portal" or "prerender".
+    targetTargetInfoSubtype :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON TargetTargetInfo where
+  parseJSON = A.withObject "TargetTargetInfo" $ \o -> TargetTargetInfo
+    <$> o A..: "targetId"
+    <*> o A..: "type"
+    <*> o A..: "title"
+    <*> o A..: "url"
+    <*> o A..: "attached"
+    <*> o A..:? "openerId"
+    <*> o A..: "canAccessOpener"
+    <*> o A..:? "openerFrameId"
+    <*> o A..:? "browserContextId"
+    <*> o A..:? "subtype"
+instance ToJSON TargetTargetInfo where
+  toJSON p = A.object $ catMaybes [
+    ("targetId" A..=) <$> Just (targetTargetInfoTargetId p),
+    ("type" A..=) <$> Just (targetTargetInfoType p),
+    ("title" A..=) <$> Just (targetTargetInfoTitle p),
+    ("url" A..=) <$> Just (targetTargetInfoUrl p),
+    ("attached" A..=) <$> Just (targetTargetInfoAttached p),
+    ("openerId" A..=) <$> (targetTargetInfoOpenerId p),
+    ("canAccessOpener" A..=) <$> Just (targetTargetInfoCanAccessOpener p),
+    ("openerFrameId" A..=) <$> (targetTargetInfoOpenerFrameId p),
+    ("browserContextId" A..=) <$> (targetTargetInfoBrowserContextId p),
+    ("subtype" A..=) <$> (targetTargetInfoSubtype p)
+    ]
+
+-- | Type 'Target.FilterEntry'.
+--   A filter used by target query/discovery/auto-attach operations.
+data TargetFilterEntry = TargetFilterEntry
+  {
+    -- | If set, causes exclusion of mathcing targets from the list.
+    targetFilterEntryExclude :: Maybe Bool,
+    -- | If not present, matches any type.
+    targetFilterEntryType :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON TargetFilterEntry where
+  parseJSON = A.withObject "TargetFilterEntry" $ \o -> TargetFilterEntry
+    <$> o A..:? "exclude"
+    <*> o A..:? "type"
+instance ToJSON TargetFilterEntry where
+  toJSON p = A.object $ catMaybes [
+    ("exclude" A..=) <$> (targetFilterEntryExclude p),
+    ("type" A..=) <$> (targetFilterEntryType p)
+    ]
+
+-- | Type 'Target.TargetFilter'.
+--   The entries in TargetFilter are matched sequentially against targets and
+--   the first entry that matches determines if the target is included or not,
+--   depending on the value of `exclude` field in the entry.
+--   If filter is not specified, the one assumed is
+--   [{type: "browser", exclude: true}, {type: "tab", exclude: true}, {}]
+--   (i.e. include everything but `browser` and `tab`).
+type TargetTargetFilter = [TargetFilterEntry]
+
+-- | Type 'Target.RemoteLocation'.
+data TargetRemoteLocation = TargetRemoteLocation
+  {
+    targetRemoteLocationHost :: T.Text,
+    targetRemoteLocationPort :: Int
+  }
+  deriving (Eq, Show)
+instance FromJSON TargetRemoteLocation where
+  parseJSON = A.withObject "TargetRemoteLocation" $ \o -> TargetRemoteLocation
+    <$> o A..: "host"
+    <*> o A..: "port"
+instance ToJSON TargetRemoteLocation where
+  toJSON p = A.object $ catMaybes [
+    ("host" A..=) <$> Just (targetRemoteLocationHost p),
+    ("port" A..=) <$> Just (targetRemoteLocationPort p)
+    ]
+
+-- | Type of the 'Target.attachedToTarget' event.
+data TargetAttachedToTarget = TargetAttachedToTarget
+  {
+    -- | Identifier assigned to the session used to send/receive messages.
+    targetAttachedToTargetSessionId :: TargetSessionID,
+    targetAttachedToTargetTargetInfo :: TargetTargetInfo,
+    targetAttachedToTargetWaitingForDebugger :: Bool
+  }
+  deriving (Eq, Show)
+instance FromJSON TargetAttachedToTarget where
+  parseJSON = A.withObject "TargetAttachedToTarget" $ \o -> TargetAttachedToTarget
+    <$> o A..: "sessionId"
+    <*> o A..: "targetInfo"
+    <*> o A..: "waitingForDebugger"
+instance Event TargetAttachedToTarget where
+  eventName _ = "Target.attachedToTarget"
+
+-- | Type of the 'Target.detachedFromTarget' event.
+data TargetDetachedFromTarget = TargetDetachedFromTarget
+  {
+    -- | Detached session identifier.
+    targetDetachedFromTargetSessionId :: TargetSessionID
+  }
+  deriving (Eq, Show)
+instance FromJSON TargetDetachedFromTarget where
+  parseJSON = A.withObject "TargetDetachedFromTarget" $ \o -> TargetDetachedFromTarget
+    <$> o A..: "sessionId"
+instance Event TargetDetachedFromTarget where
+  eventName _ = "Target.detachedFromTarget"
+
+-- | Type of the 'Target.receivedMessageFromTarget' event.
+data TargetReceivedMessageFromTarget = TargetReceivedMessageFromTarget
+  {
+    -- | Identifier of a session which sends a message.
+    targetReceivedMessageFromTargetSessionId :: TargetSessionID,
+    targetReceivedMessageFromTargetMessage :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON TargetReceivedMessageFromTarget where
+  parseJSON = A.withObject "TargetReceivedMessageFromTarget" $ \o -> TargetReceivedMessageFromTarget
+    <$> o A..: "sessionId"
+    <*> o A..: "message"
+instance Event TargetReceivedMessageFromTarget where
+  eventName _ = "Target.receivedMessageFromTarget"
+
+-- | Type of the 'Target.targetCreated' event.
+data TargetTargetCreated = TargetTargetCreated
+  {
+    targetTargetCreatedTargetInfo :: TargetTargetInfo
+  }
+  deriving (Eq, Show)
+instance FromJSON TargetTargetCreated where
+  parseJSON = A.withObject "TargetTargetCreated" $ \o -> TargetTargetCreated
+    <$> o A..: "targetInfo"
+instance Event TargetTargetCreated where
+  eventName _ = "Target.targetCreated"
+
+-- | Type of the 'Target.targetDestroyed' event.
+data TargetTargetDestroyed = TargetTargetDestroyed
+  {
+    targetTargetDestroyedTargetId :: TargetTargetID
+  }
+  deriving (Eq, Show)
+instance FromJSON TargetTargetDestroyed where
+  parseJSON = A.withObject "TargetTargetDestroyed" $ \o -> TargetTargetDestroyed
+    <$> o A..: "targetId"
+instance Event TargetTargetDestroyed where
+  eventName _ = "Target.targetDestroyed"
+
+-- | Type of the 'Target.targetCrashed' event.
+data TargetTargetCrashed = TargetTargetCrashed
+  {
+    targetTargetCrashedTargetId :: TargetTargetID,
+    -- | Termination status type.
+    targetTargetCrashedStatus :: T.Text,
+    -- | Termination error code.
+    targetTargetCrashedErrorCode :: Int
+  }
+  deriving (Eq, Show)
+instance FromJSON TargetTargetCrashed where
+  parseJSON = A.withObject "TargetTargetCrashed" $ \o -> TargetTargetCrashed
+    <$> o A..: "targetId"
+    <*> o A..: "status"
+    <*> o A..: "errorCode"
+instance Event TargetTargetCrashed where
+  eventName _ = "Target.targetCrashed"
+
+-- | Type of the 'Target.targetInfoChanged' event.
+data TargetTargetInfoChanged = TargetTargetInfoChanged
+  {
+    targetTargetInfoChangedTargetInfo :: TargetTargetInfo
+  }
+  deriving (Eq, Show)
+instance FromJSON TargetTargetInfoChanged where
+  parseJSON = A.withObject "TargetTargetInfoChanged" $ \o -> TargetTargetInfoChanged
+    <$> o A..: "targetInfo"
+instance Event TargetTargetInfoChanged where
+  eventName _ = "Target.targetInfoChanged"
+
+-- | Activates (focuses) the target.
+
+-- | Parameters of the 'Target.activateTarget' command.
+data PTargetActivateTarget = PTargetActivateTarget
+  {
+    pTargetActivateTargetTargetId :: TargetTargetID
+  }
+  deriving (Eq, Show)
+pTargetActivateTarget
+  :: TargetTargetID
+  -> PTargetActivateTarget
+pTargetActivateTarget
+  arg_pTargetActivateTargetTargetId
+  = PTargetActivateTarget
+    arg_pTargetActivateTargetTargetId
+instance ToJSON PTargetActivateTarget where
+  toJSON p = A.object $ catMaybes [
+    ("targetId" A..=) <$> Just (pTargetActivateTargetTargetId p)
+    ]
+instance Command PTargetActivateTarget where
+  type CommandResponse PTargetActivateTarget = ()
+  commandName _ = "Target.activateTarget"
+  fromJSON = const . A.Success . const ()
+
+-- | Attaches to the target with given id.
+
+-- | Parameters of the 'Target.attachToTarget' command.
+data PTargetAttachToTarget = PTargetAttachToTarget
+  {
+    pTargetAttachToTargetTargetId :: TargetTargetID,
+    -- | Enables "flat" access to the session via specifying sessionId attribute in the commands.
+    --   We plan to make this the default, deprecate non-flattened mode,
+    --   and eventually retire it. See crbug.com/991325.
+    pTargetAttachToTargetFlatten :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pTargetAttachToTarget
+  :: TargetTargetID
+  -> PTargetAttachToTarget
+pTargetAttachToTarget
+  arg_pTargetAttachToTargetTargetId
+  = PTargetAttachToTarget
+    arg_pTargetAttachToTargetTargetId
+    Nothing
+instance ToJSON PTargetAttachToTarget where
+  toJSON p = A.object $ catMaybes [
+    ("targetId" A..=) <$> Just (pTargetAttachToTargetTargetId p),
+    ("flatten" A..=) <$> (pTargetAttachToTargetFlatten p)
+    ]
+data TargetAttachToTarget = TargetAttachToTarget
+  {
+    -- | Id assigned to the session.
+    targetAttachToTargetSessionId :: TargetSessionID
+  }
+  deriving (Eq, Show)
+instance FromJSON TargetAttachToTarget where
+  parseJSON = A.withObject "TargetAttachToTarget" $ \o -> TargetAttachToTarget
+    <$> o A..: "sessionId"
+instance Command PTargetAttachToTarget where
+  type CommandResponse PTargetAttachToTarget = TargetAttachToTarget
+  commandName _ = "Target.attachToTarget"
+
+-- | Attaches to the browser target, only uses flat sessionId mode.
+
+-- | Parameters of the 'Target.attachToBrowserTarget' command.
+data PTargetAttachToBrowserTarget = PTargetAttachToBrowserTarget
+  deriving (Eq, Show)
+pTargetAttachToBrowserTarget
+  :: PTargetAttachToBrowserTarget
+pTargetAttachToBrowserTarget
+  = PTargetAttachToBrowserTarget
+instance ToJSON PTargetAttachToBrowserTarget where
+  toJSON _ = A.Null
+data TargetAttachToBrowserTarget = TargetAttachToBrowserTarget
+  {
+    -- | Id assigned to the session.
+    targetAttachToBrowserTargetSessionId :: TargetSessionID
+  }
+  deriving (Eq, Show)
+instance FromJSON TargetAttachToBrowserTarget where
+  parseJSON = A.withObject "TargetAttachToBrowserTarget" $ \o -> TargetAttachToBrowserTarget
+    <$> o A..: "sessionId"
+instance Command PTargetAttachToBrowserTarget where
+  type CommandResponse PTargetAttachToBrowserTarget = TargetAttachToBrowserTarget
+  commandName _ = "Target.attachToBrowserTarget"
+
+-- | Closes the target. If the target is a page that gets closed too.
+
+-- | Parameters of the 'Target.closeTarget' command.
+data PTargetCloseTarget = PTargetCloseTarget
+  {
+    pTargetCloseTargetTargetId :: TargetTargetID
+  }
+  deriving (Eq, Show)
+pTargetCloseTarget
+  :: TargetTargetID
+  -> PTargetCloseTarget
+pTargetCloseTarget
+  arg_pTargetCloseTargetTargetId
+  = PTargetCloseTarget
+    arg_pTargetCloseTargetTargetId
+instance ToJSON PTargetCloseTarget where
+  toJSON p = A.object $ catMaybes [
+    ("targetId" A..=) <$> Just (pTargetCloseTargetTargetId p)
+    ]
+instance Command PTargetCloseTarget where
+  type CommandResponse PTargetCloseTarget = ()
+  commandName _ = "Target.closeTarget"
+  fromJSON = const . A.Success . const ()
+
+-- | Inject object to the target's main frame that provides a communication
+--   channel with browser target.
+--   
+--   Injected object will be available as `window[bindingName]`.
+--   
+--   The object has the follwing API:
+--   - `binding.send(json)` - a method to send messages over the remote debugging protocol
+--   - `binding.onmessage = json => handleMessage(json)` - a callback that will be called for the protocol notifications and command responses.
+
+-- | Parameters of the 'Target.exposeDevToolsProtocol' command.
+data PTargetExposeDevToolsProtocol = PTargetExposeDevToolsProtocol
+  {
+    pTargetExposeDevToolsProtocolTargetId :: TargetTargetID,
+    -- | Binding name, 'cdp' if not specified.
+    pTargetExposeDevToolsProtocolBindingName :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+pTargetExposeDevToolsProtocol
+  :: TargetTargetID
+  -> PTargetExposeDevToolsProtocol
+pTargetExposeDevToolsProtocol
+  arg_pTargetExposeDevToolsProtocolTargetId
+  = PTargetExposeDevToolsProtocol
+    arg_pTargetExposeDevToolsProtocolTargetId
+    Nothing
+instance ToJSON PTargetExposeDevToolsProtocol where
+  toJSON p = A.object $ catMaybes [
+    ("targetId" A..=) <$> Just (pTargetExposeDevToolsProtocolTargetId p),
+    ("bindingName" A..=) <$> (pTargetExposeDevToolsProtocolBindingName p)
+    ]
+instance Command PTargetExposeDevToolsProtocol where
+  type CommandResponse PTargetExposeDevToolsProtocol = ()
+  commandName _ = "Target.exposeDevToolsProtocol"
+  fromJSON = const . A.Success . const ()
+
+-- | Creates a new empty BrowserContext. Similar to an incognito profile but you can have more than
+--   one.
+
+-- | Parameters of the 'Target.createBrowserContext' command.
+data PTargetCreateBrowserContext = PTargetCreateBrowserContext
+  {
+    -- | If specified, disposes this context when debugging session disconnects.
+    pTargetCreateBrowserContextDisposeOnDetach :: Maybe Bool,
+    -- | Proxy server, similar to the one passed to --proxy-server
+    pTargetCreateBrowserContextProxyServer :: Maybe T.Text,
+    -- | Proxy bypass list, similar to the one passed to --proxy-bypass-list
+    pTargetCreateBrowserContextProxyBypassList :: Maybe T.Text,
+    -- | An optional list of origins to grant unlimited cross-origin access to.
+    --   Parts of the URL other than those constituting origin are ignored.
+    pTargetCreateBrowserContextOriginsWithUniversalNetworkAccess :: Maybe [T.Text]
+  }
+  deriving (Eq, Show)
+pTargetCreateBrowserContext
+  :: PTargetCreateBrowserContext
+pTargetCreateBrowserContext
+  = PTargetCreateBrowserContext
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PTargetCreateBrowserContext where
+  toJSON p = A.object $ catMaybes [
+    ("disposeOnDetach" A..=) <$> (pTargetCreateBrowserContextDisposeOnDetach p),
+    ("proxyServer" A..=) <$> (pTargetCreateBrowserContextProxyServer p),
+    ("proxyBypassList" A..=) <$> (pTargetCreateBrowserContextProxyBypassList p),
+    ("originsWithUniversalNetworkAccess" A..=) <$> (pTargetCreateBrowserContextOriginsWithUniversalNetworkAccess p)
+    ]
+data TargetCreateBrowserContext = TargetCreateBrowserContext
+  {
+    -- | The id of the context created.
+    targetCreateBrowserContextBrowserContextId :: BrowserBrowserContextID
+  }
+  deriving (Eq, Show)
+instance FromJSON TargetCreateBrowserContext where
+  parseJSON = A.withObject "TargetCreateBrowserContext" $ \o -> TargetCreateBrowserContext
+    <$> o A..: "browserContextId"
+instance Command PTargetCreateBrowserContext where
+  type CommandResponse PTargetCreateBrowserContext = TargetCreateBrowserContext
+  commandName _ = "Target.createBrowserContext"
+
+-- | Returns all browser contexts created with `Target.createBrowserContext` method.
+
+-- | Parameters of the 'Target.getBrowserContexts' command.
+data PTargetGetBrowserContexts = PTargetGetBrowserContexts
+  deriving (Eq, Show)
+pTargetGetBrowserContexts
+  :: PTargetGetBrowserContexts
+pTargetGetBrowserContexts
+  = PTargetGetBrowserContexts
+instance ToJSON PTargetGetBrowserContexts where
+  toJSON _ = A.Null
+data TargetGetBrowserContexts = TargetGetBrowserContexts
+  {
+    -- | An array of browser context ids.
+    targetGetBrowserContextsBrowserContextIds :: [BrowserBrowserContextID]
+  }
+  deriving (Eq, Show)
+instance FromJSON TargetGetBrowserContexts where
+  parseJSON = A.withObject "TargetGetBrowserContexts" $ \o -> TargetGetBrowserContexts
+    <$> o A..: "browserContextIds"
+instance Command PTargetGetBrowserContexts where
+  type CommandResponse PTargetGetBrowserContexts = TargetGetBrowserContexts
+  commandName _ = "Target.getBrowserContexts"
+
+-- | Creates a new page.
+
+-- | Parameters of the 'Target.createTarget' command.
+data PTargetCreateTarget = PTargetCreateTarget
+  {
+    -- | The initial URL the page will be navigated to. An empty string indicates about:blank.
+    pTargetCreateTargetUrl :: T.Text,
+    -- | Frame width in DIP (headless chrome only).
+    pTargetCreateTargetWidth :: Maybe Int,
+    -- | Frame height in DIP (headless chrome only).
+    pTargetCreateTargetHeight :: Maybe Int,
+    -- | The browser context to create the page in.
+    pTargetCreateTargetBrowserContextId :: Maybe BrowserBrowserContextID,
+    -- | Whether BeginFrames for this target will be controlled via DevTools (headless chrome only,
+    --   not supported on MacOS yet, false by default).
+    pTargetCreateTargetEnableBeginFrameControl :: Maybe Bool,
+    -- | Whether to create a new Window or Tab (chrome-only, false by default).
+    pTargetCreateTargetNewWindow :: Maybe Bool,
+    -- | Whether to create the target in background or foreground (chrome-only,
+    --   false by default).
+    pTargetCreateTargetBackground :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pTargetCreateTarget
+  {-
+  -- | The initial URL the page will be navigated to. An empty string indicates about:blank.
+  -}
+  :: T.Text
+  -> PTargetCreateTarget
+pTargetCreateTarget
+  arg_pTargetCreateTargetUrl
+  = PTargetCreateTarget
+    arg_pTargetCreateTargetUrl
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PTargetCreateTarget where
+  toJSON p = A.object $ catMaybes [
+    ("url" A..=) <$> Just (pTargetCreateTargetUrl p),
+    ("width" A..=) <$> (pTargetCreateTargetWidth p),
+    ("height" A..=) <$> (pTargetCreateTargetHeight p),
+    ("browserContextId" A..=) <$> (pTargetCreateTargetBrowserContextId p),
+    ("enableBeginFrameControl" A..=) <$> (pTargetCreateTargetEnableBeginFrameControl p),
+    ("newWindow" A..=) <$> (pTargetCreateTargetNewWindow p),
+    ("background" A..=) <$> (pTargetCreateTargetBackground p)
+    ]
+data TargetCreateTarget = TargetCreateTarget
+  {
+    -- | The id of the page opened.
+    targetCreateTargetTargetId :: TargetTargetID
+  }
+  deriving (Eq, Show)
+instance FromJSON TargetCreateTarget where
+  parseJSON = A.withObject "TargetCreateTarget" $ \o -> TargetCreateTarget
+    <$> o A..: "targetId"
+instance Command PTargetCreateTarget where
+  type CommandResponse PTargetCreateTarget = TargetCreateTarget
+  commandName _ = "Target.createTarget"
+
+-- | Detaches session with given id.
+
+-- | Parameters of the 'Target.detachFromTarget' command.
+data PTargetDetachFromTarget = PTargetDetachFromTarget
+  {
+    -- | Session to detach.
+    pTargetDetachFromTargetSessionId :: Maybe TargetSessionID
+  }
+  deriving (Eq, Show)
+pTargetDetachFromTarget
+  :: PTargetDetachFromTarget
+pTargetDetachFromTarget
+  = PTargetDetachFromTarget
+    Nothing
+instance ToJSON PTargetDetachFromTarget where
+  toJSON p = A.object $ catMaybes [
+    ("sessionId" A..=) <$> (pTargetDetachFromTargetSessionId p)
+    ]
+instance Command PTargetDetachFromTarget where
+  type CommandResponse PTargetDetachFromTarget = ()
+  commandName _ = "Target.detachFromTarget"
+  fromJSON = const . A.Success . const ()
+
+-- | Deletes a BrowserContext. All the belonging pages will be closed without calling their
+--   beforeunload hooks.
+
+-- | Parameters of the 'Target.disposeBrowserContext' command.
+data PTargetDisposeBrowserContext = PTargetDisposeBrowserContext
+  {
+    pTargetDisposeBrowserContextBrowserContextId :: BrowserBrowserContextID
+  }
+  deriving (Eq, Show)
+pTargetDisposeBrowserContext
+  :: BrowserBrowserContextID
+  -> PTargetDisposeBrowserContext
+pTargetDisposeBrowserContext
+  arg_pTargetDisposeBrowserContextBrowserContextId
+  = PTargetDisposeBrowserContext
+    arg_pTargetDisposeBrowserContextBrowserContextId
+instance ToJSON PTargetDisposeBrowserContext where
+  toJSON p = A.object $ catMaybes [
+    ("browserContextId" A..=) <$> Just (pTargetDisposeBrowserContextBrowserContextId p)
+    ]
+instance Command PTargetDisposeBrowserContext where
+  type CommandResponse PTargetDisposeBrowserContext = ()
+  commandName _ = "Target.disposeBrowserContext"
+  fromJSON = const . A.Success . const ()
+
+-- | Returns information about a target.
+
+-- | Parameters of the 'Target.getTargetInfo' command.
+data PTargetGetTargetInfo = PTargetGetTargetInfo
+  {
+    pTargetGetTargetInfoTargetId :: Maybe TargetTargetID
+  }
+  deriving (Eq, Show)
+pTargetGetTargetInfo
+  :: PTargetGetTargetInfo
+pTargetGetTargetInfo
+  = PTargetGetTargetInfo
+    Nothing
+instance ToJSON PTargetGetTargetInfo where
+  toJSON p = A.object $ catMaybes [
+    ("targetId" A..=) <$> (pTargetGetTargetInfoTargetId p)
+    ]
+data TargetGetTargetInfo = TargetGetTargetInfo
+  {
+    targetGetTargetInfoTargetInfo :: TargetTargetInfo
+  }
+  deriving (Eq, Show)
+instance FromJSON TargetGetTargetInfo where
+  parseJSON = A.withObject "TargetGetTargetInfo" $ \o -> TargetGetTargetInfo
+    <$> o A..: "targetInfo"
+instance Command PTargetGetTargetInfo where
+  type CommandResponse PTargetGetTargetInfo = TargetGetTargetInfo
+  commandName _ = "Target.getTargetInfo"
+
+-- | Retrieves a list of available targets.
+
+-- | Parameters of the 'Target.getTargets' command.
+data PTargetGetTargets = PTargetGetTargets
+  {
+    -- | Only targets matching filter will be reported. If filter is not specified
+    --   and target discovery is currently enabled, a filter used for target discovery
+    --   is used for consistency.
+    pTargetGetTargetsFilter :: Maybe TargetTargetFilter
+  }
+  deriving (Eq, Show)
+pTargetGetTargets
+  :: PTargetGetTargets
+pTargetGetTargets
+  = PTargetGetTargets
+    Nothing
+instance ToJSON PTargetGetTargets where
+  toJSON p = A.object $ catMaybes [
+    ("filter" A..=) <$> (pTargetGetTargetsFilter p)
+    ]
+data TargetGetTargets = TargetGetTargets
+  {
+    -- | The list of targets.
+    targetGetTargetsTargetInfos :: [TargetTargetInfo]
+  }
+  deriving (Eq, Show)
+instance FromJSON TargetGetTargets where
+  parseJSON = A.withObject "TargetGetTargets" $ \o -> TargetGetTargets
+    <$> o A..: "targetInfos"
+instance Command PTargetGetTargets where
+  type CommandResponse PTargetGetTargets = TargetGetTargets
+  commandName _ = "Target.getTargets"
+
+-- | Controls whether to automatically attach to new targets which are considered to be related to
+--   this one. When turned on, attaches to all existing related targets as well. When turned off,
+--   automatically detaches from all currently attached targets.
+--   This also clears all targets added by `autoAttachRelated` from the list of targets to watch
+--   for creation of related targets.
+
+-- | Parameters of the 'Target.setAutoAttach' command.
+data PTargetSetAutoAttach = PTargetSetAutoAttach
+  {
+    -- | Whether to auto-attach to related targets.
+    pTargetSetAutoAttachAutoAttach :: Bool,
+    -- | Whether to pause new targets when attaching to them. Use `Runtime.runIfWaitingForDebugger`
+    --   to run paused targets.
+    pTargetSetAutoAttachWaitForDebuggerOnStart :: Bool,
+    -- | Enables "flat" access to the session via specifying sessionId attribute in the commands.
+    --   We plan to make this the default, deprecate non-flattened mode,
+    --   and eventually retire it. See crbug.com/991325.
+    pTargetSetAutoAttachFlatten :: Maybe Bool,
+    -- | Only targets matching filter will be attached.
+    pTargetSetAutoAttachFilter :: Maybe TargetTargetFilter
+  }
+  deriving (Eq, Show)
+pTargetSetAutoAttach
+  {-
+  -- | Whether to auto-attach to related targets.
+  -}
+  :: Bool
+  {-
+  -- | Whether to pause new targets when attaching to them. Use `Runtime.runIfWaitingForDebugger`
+  --   to run paused targets.
+  -}
+  -> Bool
+  -> PTargetSetAutoAttach
+pTargetSetAutoAttach
+  arg_pTargetSetAutoAttachAutoAttach
+  arg_pTargetSetAutoAttachWaitForDebuggerOnStart
+  = PTargetSetAutoAttach
+    arg_pTargetSetAutoAttachAutoAttach
+    arg_pTargetSetAutoAttachWaitForDebuggerOnStart
+    Nothing
+    Nothing
+instance ToJSON PTargetSetAutoAttach where
+  toJSON p = A.object $ catMaybes [
+    ("autoAttach" A..=) <$> Just (pTargetSetAutoAttachAutoAttach p),
+    ("waitForDebuggerOnStart" A..=) <$> Just (pTargetSetAutoAttachWaitForDebuggerOnStart p),
+    ("flatten" A..=) <$> (pTargetSetAutoAttachFlatten p),
+    ("filter" A..=) <$> (pTargetSetAutoAttachFilter p)
+    ]
+instance Command PTargetSetAutoAttach where
+  type CommandResponse PTargetSetAutoAttach = ()
+  commandName _ = "Target.setAutoAttach"
+  fromJSON = const . A.Success . const ()
+
+-- | Adds the specified target to the list of targets that will be monitored for any related target
+--   creation (such as child frames, child workers and new versions of service worker) and reported
+--   through `attachedToTarget`. The specified target is also auto-attached.
+--   This cancels the effect of any previous `setAutoAttach` and is also cancelled by subsequent
+--   `setAutoAttach`. Only available at the Browser target.
+
+-- | Parameters of the 'Target.autoAttachRelated' command.
+data PTargetAutoAttachRelated = PTargetAutoAttachRelated
+  {
+    pTargetAutoAttachRelatedTargetId :: TargetTargetID,
+    -- | Whether to pause new targets when attaching to them. Use `Runtime.runIfWaitingForDebugger`
+    --   to run paused targets.
+    pTargetAutoAttachRelatedWaitForDebuggerOnStart :: Bool,
+    -- | Only targets matching filter will be attached.
+    pTargetAutoAttachRelatedFilter :: Maybe TargetTargetFilter
+  }
+  deriving (Eq, Show)
+pTargetAutoAttachRelated
+  :: TargetTargetID
+  {-
+  -- | Whether to pause new targets when attaching to them. Use `Runtime.runIfWaitingForDebugger`
+  --   to run paused targets.
+  -}
+  -> Bool
+  -> PTargetAutoAttachRelated
+pTargetAutoAttachRelated
+  arg_pTargetAutoAttachRelatedTargetId
+  arg_pTargetAutoAttachRelatedWaitForDebuggerOnStart
+  = PTargetAutoAttachRelated
+    arg_pTargetAutoAttachRelatedTargetId
+    arg_pTargetAutoAttachRelatedWaitForDebuggerOnStart
+    Nothing
+instance ToJSON PTargetAutoAttachRelated where
+  toJSON p = A.object $ catMaybes [
+    ("targetId" A..=) <$> Just (pTargetAutoAttachRelatedTargetId p),
+    ("waitForDebuggerOnStart" A..=) <$> Just (pTargetAutoAttachRelatedWaitForDebuggerOnStart p),
+    ("filter" A..=) <$> (pTargetAutoAttachRelatedFilter p)
+    ]
+instance Command PTargetAutoAttachRelated where
+  type CommandResponse PTargetAutoAttachRelated = ()
+  commandName _ = "Target.autoAttachRelated"
+  fromJSON = const . A.Success . const ()
+
+-- | Controls whether to discover available targets and notify via
+--   `targetCreated/targetInfoChanged/targetDestroyed` events.
+
+-- | Parameters of the 'Target.setDiscoverTargets' command.
+data PTargetSetDiscoverTargets = PTargetSetDiscoverTargets
+  {
+    -- | Whether to discover available targets.
+    pTargetSetDiscoverTargetsDiscover :: Bool,
+    -- | Only targets matching filter will be attached. If `discover` is false,
+    --   `filter` must be omitted or empty.
+    pTargetSetDiscoverTargetsFilter :: Maybe TargetTargetFilter
+  }
+  deriving (Eq, Show)
+pTargetSetDiscoverTargets
+  {-
+  -- | Whether to discover available targets.
+  -}
+  :: Bool
+  -> PTargetSetDiscoverTargets
+pTargetSetDiscoverTargets
+  arg_pTargetSetDiscoverTargetsDiscover
+  = PTargetSetDiscoverTargets
+    arg_pTargetSetDiscoverTargetsDiscover
+    Nothing
+instance ToJSON PTargetSetDiscoverTargets where
+  toJSON p = A.object $ catMaybes [
+    ("discover" A..=) <$> Just (pTargetSetDiscoverTargetsDiscover p),
+    ("filter" A..=) <$> (pTargetSetDiscoverTargetsFilter p)
+    ]
+instance Command PTargetSetDiscoverTargets where
+  type CommandResponse PTargetSetDiscoverTargets = ()
+  commandName _ = "Target.setDiscoverTargets"
+  fromJSON = const . A.Success . const ()
+
+-- | Enables target discovery for the specified locations, when `setDiscoverTargets` was set to
+--   `true`.
+
+-- | Parameters of the 'Target.setRemoteLocations' command.
+data PTargetSetRemoteLocations = PTargetSetRemoteLocations
+  {
+    -- | List of remote locations.
+    pTargetSetRemoteLocationsLocations :: [TargetRemoteLocation]
+  }
+  deriving (Eq, Show)
+pTargetSetRemoteLocations
+  {-
+  -- | List of remote locations.
+  -}
+  :: [TargetRemoteLocation]
+  -> PTargetSetRemoteLocations
+pTargetSetRemoteLocations
+  arg_pTargetSetRemoteLocationsLocations
+  = PTargetSetRemoteLocations
+    arg_pTargetSetRemoteLocationsLocations
+instance ToJSON PTargetSetRemoteLocations where
+  toJSON p = A.object $ catMaybes [
+    ("locations" A..=) <$> Just (pTargetSetRemoteLocationsLocations p)
+    ]
+instance Command PTargetSetRemoteLocations where
+  type CommandResponse PTargetSetRemoteLocations = ()
+  commandName _ = "Target.setRemoteLocations"
+  fromJSON = const . A.Success . const ()
+
diff --git a/src/CDP/Domains/CSS.hs b/src/CDP/Domains/CSS.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains/CSS.hs
@@ -0,0 +1,1993 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+
+
+{- |
+= CSS
+
+This domain exposes CSS read/write operations. All CSS objects (stylesheets, rules, and styles)
+have an associated `id` used in subsequent operations on the related object. Each object type has
+a specific `id` structure, and those are not interchangeable between objects of different kinds.
+CSS objects can be loaded using the `get*ForNode()` calls (which accept a DOM node id). A client
+can also keep track of stylesheets via the `styleSheetAdded`/`styleSheetRemoved` events and
+subsequently load the required stylesheet contents using the `getStyleSheet[Text]()` methods.
+-}
+
+
+module CDP.Domains.CSS (module CDP.Domains.CSS) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+
+import CDP.Domains.DOMPageNetworkEmulationSecurity as DOMPageNetworkEmulationSecurity
+
+
+-- | Type 'CSS.StyleSheetId'.
+type CSSStyleSheetId = T.Text
+
+-- | Type 'CSS.StyleSheetOrigin'.
+--   Stylesheet type: "injected" for stylesheets injected via extension, "user-agent" for user-agent
+--   stylesheets, "inspector" for stylesheets created by the inspector (i.e. those holding the "via
+--   inspector" rules), "regular" for regular stylesheets.
+data CSSStyleSheetOrigin = CSSStyleSheetOriginInjected | CSSStyleSheetOriginUserAgent | CSSStyleSheetOriginInspector | CSSStyleSheetOriginRegular
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON CSSStyleSheetOrigin where
+  parseJSON = A.withText "CSSStyleSheetOrigin" $ \v -> case v of
+    "injected" -> pure CSSStyleSheetOriginInjected
+    "user-agent" -> pure CSSStyleSheetOriginUserAgent
+    "inspector" -> pure CSSStyleSheetOriginInspector
+    "regular" -> pure CSSStyleSheetOriginRegular
+    "_" -> fail "failed to parse CSSStyleSheetOrigin"
+instance ToJSON CSSStyleSheetOrigin where
+  toJSON v = A.String $ case v of
+    CSSStyleSheetOriginInjected -> "injected"
+    CSSStyleSheetOriginUserAgent -> "user-agent"
+    CSSStyleSheetOriginInspector -> "inspector"
+    CSSStyleSheetOriginRegular -> "regular"
+
+-- | Type 'CSS.PseudoElementMatches'.
+--   CSS rule collection for a single pseudo style.
+data CSSPseudoElementMatches = CSSPseudoElementMatches
+  {
+    -- | Pseudo element type.
+    cSSPseudoElementMatchesPseudoType :: DOMPageNetworkEmulationSecurity.DOMPseudoType,
+    -- | Pseudo element custom ident.
+    cSSPseudoElementMatchesPseudoIdentifier :: Maybe T.Text,
+    -- | Matches of CSS rules applicable to the pseudo style.
+    cSSPseudoElementMatchesMatches :: [CSSRuleMatch]
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSPseudoElementMatches where
+  parseJSON = A.withObject "CSSPseudoElementMatches" $ \o -> CSSPseudoElementMatches
+    <$> o A..: "pseudoType"
+    <*> o A..:? "pseudoIdentifier"
+    <*> o A..: "matches"
+instance ToJSON CSSPseudoElementMatches where
+  toJSON p = A.object $ catMaybes [
+    ("pseudoType" A..=) <$> Just (cSSPseudoElementMatchesPseudoType p),
+    ("pseudoIdentifier" A..=) <$> (cSSPseudoElementMatchesPseudoIdentifier p),
+    ("matches" A..=) <$> Just (cSSPseudoElementMatchesMatches p)
+    ]
+
+-- | Type 'CSS.InheritedStyleEntry'.
+--   Inherited CSS rule collection from ancestor node.
+data CSSInheritedStyleEntry = CSSInheritedStyleEntry
+  {
+    -- | The ancestor node's inline style, if any, in the style inheritance chain.
+    cSSInheritedStyleEntryInlineStyle :: Maybe CSSCSSStyle,
+    -- | Matches of CSS rules matching the ancestor node in the style inheritance chain.
+    cSSInheritedStyleEntryMatchedCSSRules :: [CSSRuleMatch]
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSInheritedStyleEntry where
+  parseJSON = A.withObject "CSSInheritedStyleEntry" $ \o -> CSSInheritedStyleEntry
+    <$> o A..:? "inlineStyle"
+    <*> o A..: "matchedCSSRules"
+instance ToJSON CSSInheritedStyleEntry where
+  toJSON p = A.object $ catMaybes [
+    ("inlineStyle" A..=) <$> (cSSInheritedStyleEntryInlineStyle p),
+    ("matchedCSSRules" A..=) <$> Just (cSSInheritedStyleEntryMatchedCSSRules p)
+    ]
+
+-- | Type 'CSS.InheritedPseudoElementMatches'.
+--   Inherited pseudo element matches from pseudos of an ancestor node.
+data CSSInheritedPseudoElementMatches = CSSInheritedPseudoElementMatches
+  {
+    -- | Matches of pseudo styles from the pseudos of an ancestor node.
+    cSSInheritedPseudoElementMatchesPseudoElements :: [CSSPseudoElementMatches]
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSInheritedPseudoElementMatches where
+  parseJSON = A.withObject "CSSInheritedPseudoElementMatches" $ \o -> CSSInheritedPseudoElementMatches
+    <$> o A..: "pseudoElements"
+instance ToJSON CSSInheritedPseudoElementMatches where
+  toJSON p = A.object $ catMaybes [
+    ("pseudoElements" A..=) <$> Just (cSSInheritedPseudoElementMatchesPseudoElements p)
+    ]
+
+-- | Type 'CSS.RuleMatch'.
+--   Match data for a CSS rule.
+data CSSRuleMatch = CSSRuleMatch
+  {
+    -- | CSS rule in the match.
+    cSSRuleMatchRule :: CSSCSSRule,
+    -- | Matching selector indices in the rule's selectorList selectors (0-based).
+    cSSRuleMatchMatchingSelectors :: [Int]
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSRuleMatch where
+  parseJSON = A.withObject "CSSRuleMatch" $ \o -> CSSRuleMatch
+    <$> o A..: "rule"
+    <*> o A..: "matchingSelectors"
+instance ToJSON CSSRuleMatch where
+  toJSON p = A.object $ catMaybes [
+    ("rule" A..=) <$> Just (cSSRuleMatchRule p),
+    ("matchingSelectors" A..=) <$> Just (cSSRuleMatchMatchingSelectors p)
+    ]
+
+-- | Type 'CSS.Value'.
+--   Data for a simple selector (these are delimited by commas in a selector list).
+data CSSValue = CSSValue
+  {
+    -- | Value text.
+    cSSValueText :: T.Text,
+    -- | Value range in the underlying resource (if available).
+    cSSValueRange :: Maybe CSSSourceRange
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSValue where
+  parseJSON = A.withObject "CSSValue" $ \o -> CSSValue
+    <$> o A..: "text"
+    <*> o A..:? "range"
+instance ToJSON CSSValue where
+  toJSON p = A.object $ catMaybes [
+    ("text" A..=) <$> Just (cSSValueText p),
+    ("range" A..=) <$> (cSSValueRange p)
+    ]
+
+-- | Type 'CSS.SelectorList'.
+--   Selector list data.
+data CSSSelectorList = CSSSelectorList
+  {
+    -- | Selectors in the list.
+    cSSSelectorListSelectors :: [CSSValue],
+    -- | Rule selector text.
+    cSSSelectorListText :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSSelectorList where
+  parseJSON = A.withObject "CSSSelectorList" $ \o -> CSSSelectorList
+    <$> o A..: "selectors"
+    <*> o A..: "text"
+instance ToJSON CSSSelectorList where
+  toJSON p = A.object $ catMaybes [
+    ("selectors" A..=) <$> Just (cSSSelectorListSelectors p),
+    ("text" A..=) <$> Just (cSSSelectorListText p)
+    ]
+
+-- | Type 'CSS.CSSStyleSheetHeader'.
+--   CSS stylesheet metainformation.
+data CSSCSSStyleSheetHeader = CSSCSSStyleSheetHeader
+  {
+    -- | The stylesheet identifier.
+    cSSCSSStyleSheetHeaderStyleSheetId :: CSSStyleSheetId,
+    -- | Owner frame identifier.
+    cSSCSSStyleSheetHeaderFrameId :: DOMPageNetworkEmulationSecurity.PageFrameId,
+    -- | Stylesheet resource URL. Empty if this is a constructed stylesheet created using
+    --   new CSSStyleSheet() (but non-empty if this is a constructed sylesheet imported
+    --   as a CSS module script).
+    cSSCSSStyleSheetHeaderSourceURL :: T.Text,
+    -- | URL of source map associated with the stylesheet (if any).
+    cSSCSSStyleSheetHeaderSourceMapURL :: Maybe T.Text,
+    -- | Stylesheet origin.
+    cSSCSSStyleSheetHeaderOrigin :: CSSStyleSheetOrigin,
+    -- | Stylesheet title.
+    cSSCSSStyleSheetHeaderTitle :: T.Text,
+    -- | The backend id for the owner node of the stylesheet.
+    cSSCSSStyleSheetHeaderOwnerNode :: Maybe DOMPageNetworkEmulationSecurity.DOMBackendNodeId,
+    -- | Denotes whether the stylesheet is disabled.
+    cSSCSSStyleSheetHeaderDisabled :: Bool,
+    -- | Whether the sourceURL field value comes from the sourceURL comment.
+    cSSCSSStyleSheetHeaderHasSourceURL :: Maybe Bool,
+    -- | Whether this stylesheet is created for STYLE tag by parser. This flag is not set for
+    --   document.written STYLE tags.
+    cSSCSSStyleSheetHeaderIsInline :: Bool,
+    -- | Whether this stylesheet is mutable. Inline stylesheets become mutable
+    --   after they have been modified via CSSOM API.
+    --   <link> element's stylesheets become mutable only if DevTools modifies them.
+    --   Constructed stylesheets (new CSSStyleSheet()) are mutable immediately after creation.
+    cSSCSSStyleSheetHeaderIsMutable :: Bool,
+    -- | True if this stylesheet is created through new CSSStyleSheet() or imported as a
+    --   CSS module script.
+    cSSCSSStyleSheetHeaderIsConstructed :: Bool,
+    -- | Line offset of the stylesheet within the resource (zero based).
+    cSSCSSStyleSheetHeaderStartLine :: Double,
+    -- | Column offset of the stylesheet within the resource (zero based).
+    cSSCSSStyleSheetHeaderStartColumn :: Double,
+    -- | Size of the content (in characters).
+    cSSCSSStyleSheetHeaderLength :: Double,
+    -- | Line offset of the end of the stylesheet within the resource (zero based).
+    cSSCSSStyleSheetHeaderEndLine :: Double,
+    -- | Column offset of the end of the stylesheet within the resource (zero based).
+    cSSCSSStyleSheetHeaderEndColumn :: Double
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSCSSStyleSheetHeader where
+  parseJSON = A.withObject "CSSCSSStyleSheetHeader" $ \o -> CSSCSSStyleSheetHeader
+    <$> o A..: "styleSheetId"
+    <*> o A..: "frameId"
+    <*> o A..: "sourceURL"
+    <*> o A..:? "sourceMapURL"
+    <*> o A..: "origin"
+    <*> o A..: "title"
+    <*> o A..:? "ownerNode"
+    <*> o A..: "disabled"
+    <*> o A..:? "hasSourceURL"
+    <*> o A..: "isInline"
+    <*> o A..: "isMutable"
+    <*> o A..: "isConstructed"
+    <*> o A..: "startLine"
+    <*> o A..: "startColumn"
+    <*> o A..: "length"
+    <*> o A..: "endLine"
+    <*> o A..: "endColumn"
+instance ToJSON CSSCSSStyleSheetHeader where
+  toJSON p = A.object $ catMaybes [
+    ("styleSheetId" A..=) <$> Just (cSSCSSStyleSheetHeaderStyleSheetId p),
+    ("frameId" A..=) <$> Just (cSSCSSStyleSheetHeaderFrameId p),
+    ("sourceURL" A..=) <$> Just (cSSCSSStyleSheetHeaderSourceURL p),
+    ("sourceMapURL" A..=) <$> (cSSCSSStyleSheetHeaderSourceMapURL p),
+    ("origin" A..=) <$> Just (cSSCSSStyleSheetHeaderOrigin p),
+    ("title" A..=) <$> Just (cSSCSSStyleSheetHeaderTitle p),
+    ("ownerNode" A..=) <$> (cSSCSSStyleSheetHeaderOwnerNode p),
+    ("disabled" A..=) <$> Just (cSSCSSStyleSheetHeaderDisabled p),
+    ("hasSourceURL" A..=) <$> (cSSCSSStyleSheetHeaderHasSourceURL p),
+    ("isInline" A..=) <$> Just (cSSCSSStyleSheetHeaderIsInline p),
+    ("isMutable" A..=) <$> Just (cSSCSSStyleSheetHeaderIsMutable p),
+    ("isConstructed" A..=) <$> Just (cSSCSSStyleSheetHeaderIsConstructed p),
+    ("startLine" A..=) <$> Just (cSSCSSStyleSheetHeaderStartLine p),
+    ("startColumn" A..=) <$> Just (cSSCSSStyleSheetHeaderStartColumn p),
+    ("length" A..=) <$> Just (cSSCSSStyleSheetHeaderLength p),
+    ("endLine" A..=) <$> Just (cSSCSSStyleSheetHeaderEndLine p),
+    ("endColumn" A..=) <$> Just (cSSCSSStyleSheetHeaderEndColumn p)
+    ]
+
+-- | Type 'CSS.CSSRule'.
+--   CSS rule representation.
+data CSSCSSRule = CSSCSSRule
+  {
+    -- | The css style sheet identifier (absent for user agent stylesheet and user-specified
+    --   stylesheet rules) this rule came from.
+    cSSCSSRuleStyleSheetId :: Maybe CSSStyleSheetId,
+    -- | Rule selector data.
+    cSSCSSRuleSelectorList :: CSSSelectorList,
+    -- | Parent stylesheet's origin.
+    cSSCSSRuleOrigin :: CSSStyleSheetOrigin,
+    -- | Associated style declaration.
+    cSSCSSRuleStyle :: CSSCSSStyle,
+    -- | Media list array (for rules involving media queries). The array enumerates media queries
+    --   starting with the innermost one, going outwards.
+    cSSCSSRuleMedia :: Maybe [CSSCSSMedia],
+    -- | Container query list array (for rules involving container queries).
+    --   The array enumerates container queries starting with the innermost one, going outwards.
+    cSSCSSRuleContainerQueries :: Maybe [CSSCSSContainerQuery],
+    -- | @supports CSS at-rule array.
+    --   The array enumerates @supports at-rules starting with the innermost one, going outwards.
+    cSSCSSRuleSupports :: Maybe [CSSCSSSupports],
+    -- | Cascade layer array. Contains the layer hierarchy that this rule belongs to starting
+    --   with the innermost layer and going outwards.
+    cSSCSSRuleLayers :: Maybe [CSSCSSLayer],
+    -- | @scope CSS at-rule array.
+    --   The array enumerates @scope at-rules starting with the innermost one, going outwards.
+    cSSCSSRuleScopes :: Maybe [CSSCSSScope]
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSCSSRule where
+  parseJSON = A.withObject "CSSCSSRule" $ \o -> CSSCSSRule
+    <$> o A..:? "styleSheetId"
+    <*> o A..: "selectorList"
+    <*> o A..: "origin"
+    <*> o A..: "style"
+    <*> o A..:? "media"
+    <*> o A..:? "containerQueries"
+    <*> o A..:? "supports"
+    <*> o A..:? "layers"
+    <*> o A..:? "scopes"
+instance ToJSON CSSCSSRule where
+  toJSON p = A.object $ catMaybes [
+    ("styleSheetId" A..=) <$> (cSSCSSRuleStyleSheetId p),
+    ("selectorList" A..=) <$> Just (cSSCSSRuleSelectorList p),
+    ("origin" A..=) <$> Just (cSSCSSRuleOrigin p),
+    ("style" A..=) <$> Just (cSSCSSRuleStyle p),
+    ("media" A..=) <$> (cSSCSSRuleMedia p),
+    ("containerQueries" A..=) <$> (cSSCSSRuleContainerQueries p),
+    ("supports" A..=) <$> (cSSCSSRuleSupports p),
+    ("layers" A..=) <$> (cSSCSSRuleLayers p),
+    ("scopes" A..=) <$> (cSSCSSRuleScopes p)
+    ]
+
+-- | Type 'CSS.RuleUsage'.
+--   CSS coverage information.
+data CSSRuleUsage = CSSRuleUsage
+  {
+    -- | The css style sheet identifier (absent for user agent stylesheet and user-specified
+    --   stylesheet rules) this rule came from.
+    cSSRuleUsageStyleSheetId :: CSSStyleSheetId,
+    -- | Offset of the start of the rule (including selector) from the beginning of the stylesheet.
+    cSSRuleUsageStartOffset :: Double,
+    -- | Offset of the end of the rule body from the beginning of the stylesheet.
+    cSSRuleUsageEndOffset :: Double,
+    -- | Indicates whether the rule was actually used by some element in the page.
+    cSSRuleUsageUsed :: Bool
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSRuleUsage where
+  parseJSON = A.withObject "CSSRuleUsage" $ \o -> CSSRuleUsage
+    <$> o A..: "styleSheetId"
+    <*> o A..: "startOffset"
+    <*> o A..: "endOffset"
+    <*> o A..: "used"
+instance ToJSON CSSRuleUsage where
+  toJSON p = A.object $ catMaybes [
+    ("styleSheetId" A..=) <$> Just (cSSRuleUsageStyleSheetId p),
+    ("startOffset" A..=) <$> Just (cSSRuleUsageStartOffset p),
+    ("endOffset" A..=) <$> Just (cSSRuleUsageEndOffset p),
+    ("used" A..=) <$> Just (cSSRuleUsageUsed p)
+    ]
+
+-- | Type 'CSS.SourceRange'.
+--   Text range within a resource. All numbers are zero-based.
+data CSSSourceRange = CSSSourceRange
+  {
+    -- | Start line of range.
+    cSSSourceRangeStartLine :: Int,
+    -- | Start column of range (inclusive).
+    cSSSourceRangeStartColumn :: Int,
+    -- | End line of range
+    cSSSourceRangeEndLine :: Int,
+    -- | End column of range (exclusive).
+    cSSSourceRangeEndColumn :: Int
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSSourceRange where
+  parseJSON = A.withObject "CSSSourceRange" $ \o -> CSSSourceRange
+    <$> o A..: "startLine"
+    <*> o A..: "startColumn"
+    <*> o A..: "endLine"
+    <*> o A..: "endColumn"
+instance ToJSON CSSSourceRange where
+  toJSON p = A.object $ catMaybes [
+    ("startLine" A..=) <$> Just (cSSSourceRangeStartLine p),
+    ("startColumn" A..=) <$> Just (cSSSourceRangeStartColumn p),
+    ("endLine" A..=) <$> Just (cSSSourceRangeEndLine p),
+    ("endColumn" A..=) <$> Just (cSSSourceRangeEndColumn p)
+    ]
+
+-- | Type 'CSS.ShorthandEntry'.
+data CSSShorthandEntry = CSSShorthandEntry
+  {
+    -- | Shorthand name.
+    cSSShorthandEntryName :: T.Text,
+    -- | Shorthand value.
+    cSSShorthandEntryValue :: T.Text,
+    -- | Whether the property has "!important" annotation (implies `false` if absent).
+    cSSShorthandEntryImportant :: Maybe Bool
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSShorthandEntry where
+  parseJSON = A.withObject "CSSShorthandEntry" $ \o -> CSSShorthandEntry
+    <$> o A..: "name"
+    <*> o A..: "value"
+    <*> o A..:? "important"
+instance ToJSON CSSShorthandEntry where
+  toJSON p = A.object $ catMaybes [
+    ("name" A..=) <$> Just (cSSShorthandEntryName p),
+    ("value" A..=) <$> Just (cSSShorthandEntryValue p),
+    ("important" A..=) <$> (cSSShorthandEntryImportant p)
+    ]
+
+-- | Type 'CSS.CSSComputedStyleProperty'.
+data CSSCSSComputedStyleProperty = CSSCSSComputedStyleProperty
+  {
+    -- | Computed style property name.
+    cSSCSSComputedStylePropertyName :: T.Text,
+    -- | Computed style property value.
+    cSSCSSComputedStylePropertyValue :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSCSSComputedStyleProperty where
+  parseJSON = A.withObject "CSSCSSComputedStyleProperty" $ \o -> CSSCSSComputedStyleProperty
+    <$> o A..: "name"
+    <*> o A..: "value"
+instance ToJSON CSSCSSComputedStyleProperty where
+  toJSON p = A.object $ catMaybes [
+    ("name" A..=) <$> Just (cSSCSSComputedStylePropertyName p),
+    ("value" A..=) <$> Just (cSSCSSComputedStylePropertyValue p)
+    ]
+
+-- | Type 'CSS.CSSStyle'.
+--   CSS style representation.
+data CSSCSSStyle = CSSCSSStyle
+  {
+    -- | The css style sheet identifier (absent for user agent stylesheet and user-specified
+    --   stylesheet rules) this rule came from.
+    cSSCSSStyleStyleSheetId :: Maybe CSSStyleSheetId,
+    -- | CSS properties in the style.
+    cSSCSSStyleCssProperties :: [CSSCSSProperty],
+    -- | Computed values for all shorthands found in the style.
+    cSSCSSStyleShorthandEntries :: [CSSShorthandEntry],
+    -- | Style declaration text (if available).
+    cSSCSSStyleCssText :: Maybe T.Text,
+    -- | Style declaration range in the enclosing stylesheet (if available).
+    cSSCSSStyleRange :: Maybe CSSSourceRange
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSCSSStyle where
+  parseJSON = A.withObject "CSSCSSStyle" $ \o -> CSSCSSStyle
+    <$> o A..:? "styleSheetId"
+    <*> o A..: "cssProperties"
+    <*> o A..: "shorthandEntries"
+    <*> o A..:? "cssText"
+    <*> o A..:? "range"
+instance ToJSON CSSCSSStyle where
+  toJSON p = A.object $ catMaybes [
+    ("styleSheetId" A..=) <$> (cSSCSSStyleStyleSheetId p),
+    ("cssProperties" A..=) <$> Just (cSSCSSStyleCssProperties p),
+    ("shorthandEntries" A..=) <$> Just (cSSCSSStyleShorthandEntries p),
+    ("cssText" A..=) <$> (cSSCSSStyleCssText p),
+    ("range" A..=) <$> (cSSCSSStyleRange p)
+    ]
+
+-- | Type 'CSS.CSSProperty'.
+--   CSS property declaration data.
+data CSSCSSProperty = CSSCSSProperty
+  {
+    -- | The property name.
+    cSSCSSPropertyName :: T.Text,
+    -- | The property value.
+    cSSCSSPropertyValue :: T.Text,
+    -- | Whether the property has "!important" annotation (implies `false` if absent).
+    cSSCSSPropertyImportant :: Maybe Bool,
+    -- | Whether the property is implicit (implies `false` if absent).
+    cSSCSSPropertyImplicit :: Maybe Bool,
+    -- | The full property text as specified in the style.
+    cSSCSSPropertyText :: Maybe T.Text,
+    -- | Whether the property is understood by the browser (implies `true` if absent).
+    cSSCSSPropertyParsedOk :: Maybe Bool,
+    -- | Whether the property is disabled by the user (present for source-based properties only).
+    cSSCSSPropertyDisabled :: Maybe Bool,
+    -- | The entire property range in the enclosing style declaration (if available).
+    cSSCSSPropertyRange :: Maybe CSSSourceRange,
+    -- | Parsed longhand components of this property if it is a shorthand.
+    --   This field will be empty if the given property is not a shorthand.
+    cSSCSSPropertyLonghandProperties :: Maybe [CSSCSSProperty]
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSCSSProperty where
+  parseJSON = A.withObject "CSSCSSProperty" $ \o -> CSSCSSProperty
+    <$> o A..: "name"
+    <*> o A..: "value"
+    <*> o A..:? "important"
+    <*> o A..:? "implicit"
+    <*> o A..:? "text"
+    <*> o A..:? "parsedOk"
+    <*> o A..:? "disabled"
+    <*> o A..:? "range"
+    <*> o A..:? "longhandProperties"
+instance ToJSON CSSCSSProperty where
+  toJSON p = A.object $ catMaybes [
+    ("name" A..=) <$> Just (cSSCSSPropertyName p),
+    ("value" A..=) <$> Just (cSSCSSPropertyValue p),
+    ("important" A..=) <$> (cSSCSSPropertyImportant p),
+    ("implicit" A..=) <$> (cSSCSSPropertyImplicit p),
+    ("text" A..=) <$> (cSSCSSPropertyText p),
+    ("parsedOk" A..=) <$> (cSSCSSPropertyParsedOk p),
+    ("disabled" A..=) <$> (cSSCSSPropertyDisabled p),
+    ("range" A..=) <$> (cSSCSSPropertyRange p),
+    ("longhandProperties" A..=) <$> (cSSCSSPropertyLonghandProperties p)
+    ]
+
+-- | Type 'CSS.CSSMedia'.
+--   CSS media rule descriptor.
+data CSSCSSMediaSource = CSSCSSMediaSourceMediaRule | CSSCSSMediaSourceImportRule | CSSCSSMediaSourceLinkedSheet | CSSCSSMediaSourceInlineSheet
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON CSSCSSMediaSource where
+  parseJSON = A.withText "CSSCSSMediaSource" $ \v -> case v of
+    "mediaRule" -> pure CSSCSSMediaSourceMediaRule
+    "importRule" -> pure CSSCSSMediaSourceImportRule
+    "linkedSheet" -> pure CSSCSSMediaSourceLinkedSheet
+    "inlineSheet" -> pure CSSCSSMediaSourceInlineSheet
+    "_" -> fail "failed to parse CSSCSSMediaSource"
+instance ToJSON CSSCSSMediaSource where
+  toJSON v = A.String $ case v of
+    CSSCSSMediaSourceMediaRule -> "mediaRule"
+    CSSCSSMediaSourceImportRule -> "importRule"
+    CSSCSSMediaSourceLinkedSheet -> "linkedSheet"
+    CSSCSSMediaSourceInlineSheet -> "inlineSheet"
+data CSSCSSMedia = CSSCSSMedia
+  {
+    -- | Media query text.
+    cSSCSSMediaText :: T.Text,
+    -- | Source of the media query: "mediaRule" if specified by a @media rule, "importRule" if
+    --   specified by an @import rule, "linkedSheet" if specified by a "media" attribute in a linked
+    --   stylesheet's LINK tag, "inlineSheet" if specified by a "media" attribute in an inline
+    --   stylesheet's STYLE tag.
+    cSSCSSMediaSource :: CSSCSSMediaSource,
+    -- | URL of the document containing the media query description.
+    cSSCSSMediaSourceURL :: Maybe T.Text,
+    -- | The associated rule (@media or @import) header range in the enclosing stylesheet (if
+    --   available).
+    cSSCSSMediaRange :: Maybe CSSSourceRange,
+    -- | Identifier of the stylesheet containing this object (if exists).
+    cSSCSSMediaStyleSheetId :: Maybe CSSStyleSheetId,
+    -- | Array of media queries.
+    cSSCSSMediaMediaList :: Maybe [CSSMediaQuery]
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSCSSMedia where
+  parseJSON = A.withObject "CSSCSSMedia" $ \o -> CSSCSSMedia
+    <$> o A..: "text"
+    <*> o A..: "source"
+    <*> o A..:? "sourceURL"
+    <*> o A..:? "range"
+    <*> o A..:? "styleSheetId"
+    <*> o A..:? "mediaList"
+instance ToJSON CSSCSSMedia where
+  toJSON p = A.object $ catMaybes [
+    ("text" A..=) <$> Just (cSSCSSMediaText p),
+    ("source" A..=) <$> Just (cSSCSSMediaSource p),
+    ("sourceURL" A..=) <$> (cSSCSSMediaSourceURL p),
+    ("range" A..=) <$> (cSSCSSMediaRange p),
+    ("styleSheetId" A..=) <$> (cSSCSSMediaStyleSheetId p),
+    ("mediaList" A..=) <$> (cSSCSSMediaMediaList p)
+    ]
+
+-- | Type 'CSS.MediaQuery'.
+--   Media query descriptor.
+data CSSMediaQuery = CSSMediaQuery
+  {
+    -- | Array of media query expressions.
+    cSSMediaQueryExpressions :: [CSSMediaQueryExpression],
+    -- | Whether the media query condition is satisfied.
+    cSSMediaQueryActive :: Bool
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSMediaQuery where
+  parseJSON = A.withObject "CSSMediaQuery" $ \o -> CSSMediaQuery
+    <$> o A..: "expressions"
+    <*> o A..: "active"
+instance ToJSON CSSMediaQuery where
+  toJSON p = A.object $ catMaybes [
+    ("expressions" A..=) <$> Just (cSSMediaQueryExpressions p),
+    ("active" A..=) <$> Just (cSSMediaQueryActive p)
+    ]
+
+-- | Type 'CSS.MediaQueryExpression'.
+--   Media query expression descriptor.
+data CSSMediaQueryExpression = CSSMediaQueryExpression
+  {
+    -- | Media query expression value.
+    cSSMediaQueryExpressionValue :: Double,
+    -- | Media query expression units.
+    cSSMediaQueryExpressionUnit :: T.Text,
+    -- | Media query expression feature.
+    cSSMediaQueryExpressionFeature :: T.Text,
+    -- | The associated range of the value text in the enclosing stylesheet (if available).
+    cSSMediaQueryExpressionValueRange :: Maybe CSSSourceRange,
+    -- | Computed length of media query expression (if applicable).
+    cSSMediaQueryExpressionComputedLength :: Maybe Double
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSMediaQueryExpression where
+  parseJSON = A.withObject "CSSMediaQueryExpression" $ \o -> CSSMediaQueryExpression
+    <$> o A..: "value"
+    <*> o A..: "unit"
+    <*> o A..: "feature"
+    <*> o A..:? "valueRange"
+    <*> o A..:? "computedLength"
+instance ToJSON CSSMediaQueryExpression where
+  toJSON p = A.object $ catMaybes [
+    ("value" A..=) <$> Just (cSSMediaQueryExpressionValue p),
+    ("unit" A..=) <$> Just (cSSMediaQueryExpressionUnit p),
+    ("feature" A..=) <$> Just (cSSMediaQueryExpressionFeature p),
+    ("valueRange" A..=) <$> (cSSMediaQueryExpressionValueRange p),
+    ("computedLength" A..=) <$> (cSSMediaQueryExpressionComputedLength p)
+    ]
+
+-- | Type 'CSS.CSSContainerQuery'.
+--   CSS container query rule descriptor.
+data CSSCSSContainerQuery = CSSCSSContainerQuery
+  {
+    -- | Container query text.
+    cSSCSSContainerQueryText :: T.Text,
+    -- | The associated rule header range in the enclosing stylesheet (if
+    --   available).
+    cSSCSSContainerQueryRange :: Maybe CSSSourceRange,
+    -- | Identifier of the stylesheet containing this object (if exists).
+    cSSCSSContainerQueryStyleSheetId :: Maybe CSSStyleSheetId,
+    -- | Optional name for the container.
+    cSSCSSContainerQueryName :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSCSSContainerQuery where
+  parseJSON = A.withObject "CSSCSSContainerQuery" $ \o -> CSSCSSContainerQuery
+    <$> o A..: "text"
+    <*> o A..:? "range"
+    <*> o A..:? "styleSheetId"
+    <*> o A..:? "name"
+instance ToJSON CSSCSSContainerQuery where
+  toJSON p = A.object $ catMaybes [
+    ("text" A..=) <$> Just (cSSCSSContainerQueryText p),
+    ("range" A..=) <$> (cSSCSSContainerQueryRange p),
+    ("styleSheetId" A..=) <$> (cSSCSSContainerQueryStyleSheetId p),
+    ("name" A..=) <$> (cSSCSSContainerQueryName p)
+    ]
+
+-- | Type 'CSS.CSSSupports'.
+--   CSS Supports at-rule descriptor.
+data CSSCSSSupports = CSSCSSSupports
+  {
+    -- | Supports rule text.
+    cSSCSSSupportsText :: T.Text,
+    -- | Whether the supports condition is satisfied.
+    cSSCSSSupportsActive :: Bool,
+    -- | The associated rule header range in the enclosing stylesheet (if
+    --   available).
+    cSSCSSSupportsRange :: Maybe CSSSourceRange,
+    -- | Identifier of the stylesheet containing this object (if exists).
+    cSSCSSSupportsStyleSheetId :: Maybe CSSStyleSheetId
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSCSSSupports where
+  parseJSON = A.withObject "CSSCSSSupports" $ \o -> CSSCSSSupports
+    <$> o A..: "text"
+    <*> o A..: "active"
+    <*> o A..:? "range"
+    <*> o A..:? "styleSheetId"
+instance ToJSON CSSCSSSupports where
+  toJSON p = A.object $ catMaybes [
+    ("text" A..=) <$> Just (cSSCSSSupportsText p),
+    ("active" A..=) <$> Just (cSSCSSSupportsActive p),
+    ("range" A..=) <$> (cSSCSSSupportsRange p),
+    ("styleSheetId" A..=) <$> (cSSCSSSupportsStyleSheetId p)
+    ]
+
+-- | Type 'CSS.CSSScope'.
+--   CSS Scope at-rule descriptor.
+data CSSCSSScope = CSSCSSScope
+  {
+    -- | Scope rule text.
+    cSSCSSScopeText :: T.Text,
+    -- | The associated rule header range in the enclosing stylesheet (if
+    --   available).
+    cSSCSSScopeRange :: Maybe CSSSourceRange,
+    -- | Identifier of the stylesheet containing this object (if exists).
+    cSSCSSScopeStyleSheetId :: Maybe CSSStyleSheetId
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSCSSScope where
+  parseJSON = A.withObject "CSSCSSScope" $ \o -> CSSCSSScope
+    <$> o A..: "text"
+    <*> o A..:? "range"
+    <*> o A..:? "styleSheetId"
+instance ToJSON CSSCSSScope where
+  toJSON p = A.object $ catMaybes [
+    ("text" A..=) <$> Just (cSSCSSScopeText p),
+    ("range" A..=) <$> (cSSCSSScopeRange p),
+    ("styleSheetId" A..=) <$> (cSSCSSScopeStyleSheetId p)
+    ]
+
+-- | Type 'CSS.CSSLayer'.
+--   CSS Layer at-rule descriptor.
+data CSSCSSLayer = CSSCSSLayer
+  {
+    -- | Layer name.
+    cSSCSSLayerText :: T.Text,
+    -- | The associated rule header range in the enclosing stylesheet (if
+    --   available).
+    cSSCSSLayerRange :: Maybe CSSSourceRange,
+    -- | Identifier of the stylesheet containing this object (if exists).
+    cSSCSSLayerStyleSheetId :: Maybe CSSStyleSheetId
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSCSSLayer where
+  parseJSON = A.withObject "CSSCSSLayer" $ \o -> CSSCSSLayer
+    <$> o A..: "text"
+    <*> o A..:? "range"
+    <*> o A..:? "styleSheetId"
+instance ToJSON CSSCSSLayer where
+  toJSON p = A.object $ catMaybes [
+    ("text" A..=) <$> Just (cSSCSSLayerText p),
+    ("range" A..=) <$> (cSSCSSLayerRange p),
+    ("styleSheetId" A..=) <$> (cSSCSSLayerStyleSheetId p)
+    ]
+
+-- | Type 'CSS.CSSLayerData'.
+--   CSS Layer data.
+data CSSCSSLayerData = CSSCSSLayerData
+  {
+    -- | Layer name.
+    cSSCSSLayerDataName :: T.Text,
+    -- | Direct sub-layers
+    cSSCSSLayerDataSubLayers :: Maybe [CSSCSSLayerData],
+    -- | Layer order. The order determines the order of the layer in the cascade order.
+    --   A higher number has higher priority in the cascade order.
+    cSSCSSLayerDataOrder :: Double
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSCSSLayerData where
+  parseJSON = A.withObject "CSSCSSLayerData" $ \o -> CSSCSSLayerData
+    <$> o A..: "name"
+    <*> o A..:? "subLayers"
+    <*> o A..: "order"
+instance ToJSON CSSCSSLayerData where
+  toJSON p = A.object $ catMaybes [
+    ("name" A..=) <$> Just (cSSCSSLayerDataName p),
+    ("subLayers" A..=) <$> (cSSCSSLayerDataSubLayers p),
+    ("order" A..=) <$> Just (cSSCSSLayerDataOrder p)
+    ]
+
+-- | Type 'CSS.PlatformFontUsage'.
+--   Information about amount of glyphs that were rendered with given font.
+data CSSPlatformFontUsage = CSSPlatformFontUsage
+  {
+    -- | Font's family name reported by platform.
+    cSSPlatformFontUsageFamilyName :: T.Text,
+    -- | Indicates if the font was downloaded or resolved locally.
+    cSSPlatformFontUsageIsCustomFont :: Bool,
+    -- | Amount of glyphs that were rendered with this font.
+    cSSPlatformFontUsageGlyphCount :: Double
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSPlatformFontUsage where
+  parseJSON = A.withObject "CSSPlatformFontUsage" $ \o -> CSSPlatformFontUsage
+    <$> o A..: "familyName"
+    <*> o A..: "isCustomFont"
+    <*> o A..: "glyphCount"
+instance ToJSON CSSPlatformFontUsage where
+  toJSON p = A.object $ catMaybes [
+    ("familyName" A..=) <$> Just (cSSPlatformFontUsageFamilyName p),
+    ("isCustomFont" A..=) <$> Just (cSSPlatformFontUsageIsCustomFont p),
+    ("glyphCount" A..=) <$> Just (cSSPlatformFontUsageGlyphCount p)
+    ]
+
+-- | Type 'CSS.FontVariationAxis'.
+--   Information about font variation axes for variable fonts
+data CSSFontVariationAxis = CSSFontVariationAxis
+  {
+    -- | The font-variation-setting tag (a.k.a. "axis tag").
+    cSSFontVariationAxisTag :: T.Text,
+    -- | Human-readable variation name in the default language (normally, "en").
+    cSSFontVariationAxisName :: T.Text,
+    -- | The minimum value (inclusive) the font supports for this tag.
+    cSSFontVariationAxisMinValue :: Double,
+    -- | The maximum value (inclusive) the font supports for this tag.
+    cSSFontVariationAxisMaxValue :: Double,
+    -- | The default value.
+    cSSFontVariationAxisDefaultValue :: Double
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSFontVariationAxis where
+  parseJSON = A.withObject "CSSFontVariationAxis" $ \o -> CSSFontVariationAxis
+    <$> o A..: "tag"
+    <*> o A..: "name"
+    <*> o A..: "minValue"
+    <*> o A..: "maxValue"
+    <*> o A..: "defaultValue"
+instance ToJSON CSSFontVariationAxis where
+  toJSON p = A.object $ catMaybes [
+    ("tag" A..=) <$> Just (cSSFontVariationAxisTag p),
+    ("name" A..=) <$> Just (cSSFontVariationAxisName p),
+    ("minValue" A..=) <$> Just (cSSFontVariationAxisMinValue p),
+    ("maxValue" A..=) <$> Just (cSSFontVariationAxisMaxValue p),
+    ("defaultValue" A..=) <$> Just (cSSFontVariationAxisDefaultValue p)
+    ]
+
+-- | Type 'CSS.FontFace'.
+--   Properties of a web font: https://www.w3.org/TR/2008/REC-CSS2-20080411/fonts.html#font-descriptions
+--   and additional information such as platformFontFamily and fontVariationAxes.
+data CSSFontFace = CSSFontFace
+  {
+    -- | The font-family.
+    cSSFontFaceFontFamily :: T.Text,
+    -- | The font-style.
+    cSSFontFaceFontStyle :: T.Text,
+    -- | The font-variant.
+    cSSFontFaceFontVariant :: T.Text,
+    -- | The font-weight.
+    cSSFontFaceFontWeight :: T.Text,
+    -- | The font-stretch.
+    cSSFontFaceFontStretch :: T.Text,
+    -- | The font-display.
+    cSSFontFaceFontDisplay :: T.Text,
+    -- | The unicode-range.
+    cSSFontFaceUnicodeRange :: T.Text,
+    -- | The src.
+    cSSFontFaceSrc :: T.Text,
+    -- | The resolved platform font family
+    cSSFontFacePlatformFontFamily :: T.Text,
+    -- | Available variation settings (a.k.a. "axes").
+    cSSFontFaceFontVariationAxes :: Maybe [CSSFontVariationAxis]
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSFontFace where
+  parseJSON = A.withObject "CSSFontFace" $ \o -> CSSFontFace
+    <$> o A..: "fontFamily"
+    <*> o A..: "fontStyle"
+    <*> o A..: "fontVariant"
+    <*> o A..: "fontWeight"
+    <*> o A..: "fontStretch"
+    <*> o A..: "fontDisplay"
+    <*> o A..: "unicodeRange"
+    <*> o A..: "src"
+    <*> o A..: "platformFontFamily"
+    <*> o A..:? "fontVariationAxes"
+instance ToJSON CSSFontFace where
+  toJSON p = A.object $ catMaybes [
+    ("fontFamily" A..=) <$> Just (cSSFontFaceFontFamily p),
+    ("fontStyle" A..=) <$> Just (cSSFontFaceFontStyle p),
+    ("fontVariant" A..=) <$> Just (cSSFontFaceFontVariant p),
+    ("fontWeight" A..=) <$> Just (cSSFontFaceFontWeight p),
+    ("fontStretch" A..=) <$> Just (cSSFontFaceFontStretch p),
+    ("fontDisplay" A..=) <$> Just (cSSFontFaceFontDisplay p),
+    ("unicodeRange" A..=) <$> Just (cSSFontFaceUnicodeRange p),
+    ("src" A..=) <$> Just (cSSFontFaceSrc p),
+    ("platformFontFamily" A..=) <$> Just (cSSFontFacePlatformFontFamily p),
+    ("fontVariationAxes" A..=) <$> (cSSFontFaceFontVariationAxes p)
+    ]
+
+-- | Type 'CSS.CSSKeyframesRule'.
+--   CSS keyframes rule representation.
+data CSSCSSKeyframesRule = CSSCSSKeyframesRule
+  {
+    -- | Animation name.
+    cSSCSSKeyframesRuleAnimationName :: CSSValue,
+    -- | List of keyframes.
+    cSSCSSKeyframesRuleKeyframes :: [CSSCSSKeyframeRule]
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSCSSKeyframesRule where
+  parseJSON = A.withObject "CSSCSSKeyframesRule" $ \o -> CSSCSSKeyframesRule
+    <$> o A..: "animationName"
+    <*> o A..: "keyframes"
+instance ToJSON CSSCSSKeyframesRule where
+  toJSON p = A.object $ catMaybes [
+    ("animationName" A..=) <$> Just (cSSCSSKeyframesRuleAnimationName p),
+    ("keyframes" A..=) <$> Just (cSSCSSKeyframesRuleKeyframes p)
+    ]
+
+-- | Type 'CSS.CSSKeyframeRule'.
+--   CSS keyframe rule representation.
+data CSSCSSKeyframeRule = CSSCSSKeyframeRule
+  {
+    -- | The css style sheet identifier (absent for user agent stylesheet and user-specified
+    --   stylesheet rules) this rule came from.
+    cSSCSSKeyframeRuleStyleSheetId :: Maybe CSSStyleSheetId,
+    -- | Parent stylesheet's origin.
+    cSSCSSKeyframeRuleOrigin :: CSSStyleSheetOrigin,
+    -- | Associated key text.
+    cSSCSSKeyframeRuleKeyText :: CSSValue,
+    -- | Associated style declaration.
+    cSSCSSKeyframeRuleStyle :: CSSCSSStyle
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSCSSKeyframeRule where
+  parseJSON = A.withObject "CSSCSSKeyframeRule" $ \o -> CSSCSSKeyframeRule
+    <$> o A..:? "styleSheetId"
+    <*> o A..: "origin"
+    <*> o A..: "keyText"
+    <*> o A..: "style"
+instance ToJSON CSSCSSKeyframeRule where
+  toJSON p = A.object $ catMaybes [
+    ("styleSheetId" A..=) <$> (cSSCSSKeyframeRuleStyleSheetId p),
+    ("origin" A..=) <$> Just (cSSCSSKeyframeRuleOrigin p),
+    ("keyText" A..=) <$> Just (cSSCSSKeyframeRuleKeyText p),
+    ("style" A..=) <$> Just (cSSCSSKeyframeRuleStyle p)
+    ]
+
+-- | Type 'CSS.StyleDeclarationEdit'.
+--   A descriptor of operation to mutate style declaration text.
+data CSSStyleDeclarationEdit = CSSStyleDeclarationEdit
+  {
+    -- | The css style sheet identifier.
+    cSSStyleDeclarationEditStyleSheetId :: CSSStyleSheetId,
+    -- | The range of the style text in the enclosing stylesheet.
+    cSSStyleDeclarationEditRange :: CSSSourceRange,
+    -- | New style text.
+    cSSStyleDeclarationEditText :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSStyleDeclarationEdit where
+  parseJSON = A.withObject "CSSStyleDeclarationEdit" $ \o -> CSSStyleDeclarationEdit
+    <$> o A..: "styleSheetId"
+    <*> o A..: "range"
+    <*> o A..: "text"
+instance ToJSON CSSStyleDeclarationEdit where
+  toJSON p = A.object $ catMaybes [
+    ("styleSheetId" A..=) <$> Just (cSSStyleDeclarationEditStyleSheetId p),
+    ("range" A..=) <$> Just (cSSStyleDeclarationEditRange p),
+    ("text" A..=) <$> Just (cSSStyleDeclarationEditText p)
+    ]
+
+-- | Type of the 'CSS.fontsUpdated' event.
+data CSSFontsUpdated = CSSFontsUpdated
+  {
+    -- | The web font that has loaded.
+    cSSFontsUpdatedFont :: Maybe CSSFontFace
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSFontsUpdated where
+  parseJSON = A.withObject "CSSFontsUpdated" $ \o -> CSSFontsUpdated
+    <$> o A..:? "font"
+instance Event CSSFontsUpdated where
+  eventName _ = "CSS.fontsUpdated"
+
+-- | Type of the 'CSS.mediaQueryResultChanged' event.
+data CSSMediaQueryResultChanged = CSSMediaQueryResultChanged
+  deriving (Eq, Show, Read)
+instance FromJSON CSSMediaQueryResultChanged where
+  parseJSON _ = pure CSSMediaQueryResultChanged
+instance Event CSSMediaQueryResultChanged where
+  eventName _ = "CSS.mediaQueryResultChanged"
+
+-- | Type of the 'CSS.styleSheetAdded' event.
+data CSSStyleSheetAdded = CSSStyleSheetAdded
+  {
+    -- | Added stylesheet metainfo.
+    cSSStyleSheetAddedHeader :: CSSCSSStyleSheetHeader
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSStyleSheetAdded where
+  parseJSON = A.withObject "CSSStyleSheetAdded" $ \o -> CSSStyleSheetAdded
+    <$> o A..: "header"
+instance Event CSSStyleSheetAdded where
+  eventName _ = "CSS.styleSheetAdded"
+
+-- | Type of the 'CSS.styleSheetChanged' event.
+data CSSStyleSheetChanged = CSSStyleSheetChanged
+  {
+    cSSStyleSheetChangedStyleSheetId :: CSSStyleSheetId
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSStyleSheetChanged where
+  parseJSON = A.withObject "CSSStyleSheetChanged" $ \o -> CSSStyleSheetChanged
+    <$> o A..: "styleSheetId"
+instance Event CSSStyleSheetChanged where
+  eventName _ = "CSS.styleSheetChanged"
+
+-- | Type of the 'CSS.styleSheetRemoved' event.
+data CSSStyleSheetRemoved = CSSStyleSheetRemoved
+  {
+    -- | Identifier of the removed stylesheet.
+    cSSStyleSheetRemovedStyleSheetId :: CSSStyleSheetId
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSStyleSheetRemoved where
+  parseJSON = A.withObject "CSSStyleSheetRemoved" $ \o -> CSSStyleSheetRemoved
+    <$> o A..: "styleSheetId"
+instance Event CSSStyleSheetRemoved where
+  eventName _ = "CSS.styleSheetRemoved"
+
+-- | Inserts a new rule with the given `ruleText` in a stylesheet with given `styleSheetId`, at the
+--   position specified by `location`.
+
+-- | Parameters of the 'CSS.addRule' command.
+data PCSSAddRule = PCSSAddRule
+  {
+    -- | The css style sheet identifier where a new rule should be inserted.
+    pCSSAddRuleStyleSheetId :: CSSStyleSheetId,
+    -- | The text of a new rule.
+    pCSSAddRuleRuleText :: T.Text,
+    -- | Text position of a new rule in the target style sheet.
+    pCSSAddRuleLocation :: CSSSourceRange
+  }
+  deriving (Eq, Show)
+pCSSAddRule
+  {-
+  -- | The css style sheet identifier where a new rule should be inserted.
+  -}
+  :: CSSStyleSheetId
+  {-
+  -- | The text of a new rule.
+  -}
+  -> T.Text
+  {-
+  -- | Text position of a new rule in the target style sheet.
+  -}
+  -> CSSSourceRange
+  -> PCSSAddRule
+pCSSAddRule
+  arg_pCSSAddRuleStyleSheetId
+  arg_pCSSAddRuleRuleText
+  arg_pCSSAddRuleLocation
+  = PCSSAddRule
+    arg_pCSSAddRuleStyleSheetId
+    arg_pCSSAddRuleRuleText
+    arg_pCSSAddRuleLocation
+instance ToJSON PCSSAddRule where
+  toJSON p = A.object $ catMaybes [
+    ("styleSheetId" A..=) <$> Just (pCSSAddRuleStyleSheetId p),
+    ("ruleText" A..=) <$> Just (pCSSAddRuleRuleText p),
+    ("location" A..=) <$> Just (pCSSAddRuleLocation p)
+    ]
+data CSSAddRule = CSSAddRule
+  {
+    -- | The newly created rule.
+    cSSAddRuleRule :: CSSCSSRule
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSAddRule where
+  parseJSON = A.withObject "CSSAddRule" $ \o -> CSSAddRule
+    <$> o A..: "rule"
+instance Command PCSSAddRule where
+  type CommandResponse PCSSAddRule = CSSAddRule
+  commandName _ = "CSS.addRule"
+
+-- | Returns all class names from specified stylesheet.
+
+-- | Parameters of the 'CSS.collectClassNames' command.
+data PCSSCollectClassNames = PCSSCollectClassNames
+  {
+    pCSSCollectClassNamesStyleSheetId :: CSSStyleSheetId
+  }
+  deriving (Eq, Show)
+pCSSCollectClassNames
+  :: CSSStyleSheetId
+  -> PCSSCollectClassNames
+pCSSCollectClassNames
+  arg_pCSSCollectClassNamesStyleSheetId
+  = PCSSCollectClassNames
+    arg_pCSSCollectClassNamesStyleSheetId
+instance ToJSON PCSSCollectClassNames where
+  toJSON p = A.object $ catMaybes [
+    ("styleSheetId" A..=) <$> Just (pCSSCollectClassNamesStyleSheetId p)
+    ]
+data CSSCollectClassNames = CSSCollectClassNames
+  {
+    -- | Class name list.
+    cSSCollectClassNamesClassNames :: [T.Text]
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSCollectClassNames where
+  parseJSON = A.withObject "CSSCollectClassNames" $ \o -> CSSCollectClassNames
+    <$> o A..: "classNames"
+instance Command PCSSCollectClassNames where
+  type CommandResponse PCSSCollectClassNames = CSSCollectClassNames
+  commandName _ = "CSS.collectClassNames"
+
+-- | Creates a new special "via-inspector" stylesheet in the frame with given `frameId`.
+
+-- | Parameters of the 'CSS.createStyleSheet' command.
+data PCSSCreateStyleSheet = PCSSCreateStyleSheet
+  {
+    -- | Identifier of the frame where "via-inspector" stylesheet should be created.
+    pCSSCreateStyleSheetFrameId :: DOMPageNetworkEmulationSecurity.PageFrameId
+  }
+  deriving (Eq, Show)
+pCSSCreateStyleSheet
+  {-
+  -- | Identifier of the frame where "via-inspector" stylesheet should be created.
+  -}
+  :: DOMPageNetworkEmulationSecurity.PageFrameId
+  -> PCSSCreateStyleSheet
+pCSSCreateStyleSheet
+  arg_pCSSCreateStyleSheetFrameId
+  = PCSSCreateStyleSheet
+    arg_pCSSCreateStyleSheetFrameId
+instance ToJSON PCSSCreateStyleSheet where
+  toJSON p = A.object $ catMaybes [
+    ("frameId" A..=) <$> Just (pCSSCreateStyleSheetFrameId p)
+    ]
+data CSSCreateStyleSheet = CSSCreateStyleSheet
+  {
+    -- | Identifier of the created "via-inspector" stylesheet.
+    cSSCreateStyleSheetStyleSheetId :: CSSStyleSheetId
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSCreateStyleSheet where
+  parseJSON = A.withObject "CSSCreateStyleSheet" $ \o -> CSSCreateStyleSheet
+    <$> o A..: "styleSheetId"
+instance Command PCSSCreateStyleSheet where
+  type CommandResponse PCSSCreateStyleSheet = CSSCreateStyleSheet
+  commandName _ = "CSS.createStyleSheet"
+
+-- | Disables the CSS agent for the given page.
+
+-- | Parameters of the 'CSS.disable' command.
+data PCSSDisable = PCSSDisable
+  deriving (Eq, Show)
+pCSSDisable
+  :: PCSSDisable
+pCSSDisable
+  = PCSSDisable
+instance ToJSON PCSSDisable where
+  toJSON _ = A.Null
+instance Command PCSSDisable where
+  type CommandResponse PCSSDisable = ()
+  commandName _ = "CSS.disable"
+  fromJSON = const . A.Success . const ()
+
+-- | Enables the CSS agent for the given page. Clients should not assume that the CSS agent has been
+--   enabled until the result of this command is received.
+
+-- | Parameters of the 'CSS.enable' command.
+data PCSSEnable = PCSSEnable
+  deriving (Eq, Show)
+pCSSEnable
+  :: PCSSEnable
+pCSSEnable
+  = PCSSEnable
+instance ToJSON PCSSEnable where
+  toJSON _ = A.Null
+instance Command PCSSEnable where
+  type CommandResponse PCSSEnable = ()
+  commandName _ = "CSS.enable"
+  fromJSON = const . A.Success . const ()
+
+-- | Ensures that the given node will have specified pseudo-classes whenever its style is computed by
+--   the browser.
+
+-- | Parameters of the 'CSS.forcePseudoState' command.
+data PCSSForcePseudoState = PCSSForcePseudoState
+  {
+    -- | The element id for which to force the pseudo state.
+    pCSSForcePseudoStateNodeId :: DOMPageNetworkEmulationSecurity.DOMNodeId,
+    -- | Element pseudo classes to force when computing the element's style.
+    pCSSForcePseudoStateForcedPseudoClasses :: [T.Text]
+  }
+  deriving (Eq, Show)
+pCSSForcePseudoState
+  {-
+  -- | The element id for which to force the pseudo state.
+  -}
+  :: DOMPageNetworkEmulationSecurity.DOMNodeId
+  {-
+  -- | Element pseudo classes to force when computing the element's style.
+  -}
+  -> [T.Text]
+  -> PCSSForcePseudoState
+pCSSForcePseudoState
+  arg_pCSSForcePseudoStateNodeId
+  arg_pCSSForcePseudoStateForcedPseudoClasses
+  = PCSSForcePseudoState
+    arg_pCSSForcePseudoStateNodeId
+    arg_pCSSForcePseudoStateForcedPseudoClasses
+instance ToJSON PCSSForcePseudoState where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> Just (pCSSForcePseudoStateNodeId p),
+    ("forcedPseudoClasses" A..=) <$> Just (pCSSForcePseudoStateForcedPseudoClasses p)
+    ]
+instance Command PCSSForcePseudoState where
+  type CommandResponse PCSSForcePseudoState = ()
+  commandName _ = "CSS.forcePseudoState"
+  fromJSON = const . A.Success . const ()
+
+
+-- | Parameters of the 'CSS.getBackgroundColors' command.
+data PCSSGetBackgroundColors = PCSSGetBackgroundColors
+  {
+    -- | Id of the node to get background colors for.
+    pCSSGetBackgroundColorsNodeId :: DOMPageNetworkEmulationSecurity.DOMNodeId
+  }
+  deriving (Eq, Show)
+pCSSGetBackgroundColors
+  {-
+  -- | Id of the node to get background colors for.
+  -}
+  :: DOMPageNetworkEmulationSecurity.DOMNodeId
+  -> PCSSGetBackgroundColors
+pCSSGetBackgroundColors
+  arg_pCSSGetBackgroundColorsNodeId
+  = PCSSGetBackgroundColors
+    arg_pCSSGetBackgroundColorsNodeId
+instance ToJSON PCSSGetBackgroundColors where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> Just (pCSSGetBackgroundColorsNodeId p)
+    ]
+data CSSGetBackgroundColors = CSSGetBackgroundColors
+  {
+    -- | The range of background colors behind this element, if it contains any visible text. If no
+    --   visible text is present, this will be undefined. In the case of a flat background color,
+    --   this will consist of simply that color. In the case of a gradient, this will consist of each
+    --   of the color stops. For anything more complicated, this will be an empty array. Images will
+    --   be ignored (as if the image had failed to load).
+    cSSGetBackgroundColorsBackgroundColors :: Maybe [T.Text],
+    -- | The computed font size for this node, as a CSS computed value string (e.g. '12px').
+    cSSGetBackgroundColorsComputedFontSize :: Maybe T.Text,
+    -- | The computed font weight for this node, as a CSS computed value string (e.g. 'normal' or
+    --   '100').
+    cSSGetBackgroundColorsComputedFontWeight :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSGetBackgroundColors where
+  parseJSON = A.withObject "CSSGetBackgroundColors" $ \o -> CSSGetBackgroundColors
+    <$> o A..:? "backgroundColors"
+    <*> o A..:? "computedFontSize"
+    <*> o A..:? "computedFontWeight"
+instance Command PCSSGetBackgroundColors where
+  type CommandResponse PCSSGetBackgroundColors = CSSGetBackgroundColors
+  commandName _ = "CSS.getBackgroundColors"
+
+-- | Returns the computed style for a DOM node identified by `nodeId`.
+
+-- | Parameters of the 'CSS.getComputedStyleForNode' command.
+data PCSSGetComputedStyleForNode = PCSSGetComputedStyleForNode
+  {
+    pCSSGetComputedStyleForNodeNodeId :: DOMPageNetworkEmulationSecurity.DOMNodeId
+  }
+  deriving (Eq, Show)
+pCSSGetComputedStyleForNode
+  :: DOMPageNetworkEmulationSecurity.DOMNodeId
+  -> PCSSGetComputedStyleForNode
+pCSSGetComputedStyleForNode
+  arg_pCSSGetComputedStyleForNodeNodeId
+  = PCSSGetComputedStyleForNode
+    arg_pCSSGetComputedStyleForNodeNodeId
+instance ToJSON PCSSGetComputedStyleForNode where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> Just (pCSSGetComputedStyleForNodeNodeId p)
+    ]
+data CSSGetComputedStyleForNode = CSSGetComputedStyleForNode
+  {
+    -- | Computed style for the specified DOM node.
+    cSSGetComputedStyleForNodeComputedStyle :: [CSSCSSComputedStyleProperty]
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSGetComputedStyleForNode where
+  parseJSON = A.withObject "CSSGetComputedStyleForNode" $ \o -> CSSGetComputedStyleForNode
+    <$> o A..: "computedStyle"
+instance Command PCSSGetComputedStyleForNode where
+  type CommandResponse PCSSGetComputedStyleForNode = CSSGetComputedStyleForNode
+  commandName _ = "CSS.getComputedStyleForNode"
+
+-- | Returns the styles defined inline (explicitly in the "style" attribute and implicitly, using DOM
+--   attributes) for a DOM node identified by `nodeId`.
+
+-- | Parameters of the 'CSS.getInlineStylesForNode' command.
+data PCSSGetInlineStylesForNode = PCSSGetInlineStylesForNode
+  {
+    pCSSGetInlineStylesForNodeNodeId :: DOMPageNetworkEmulationSecurity.DOMNodeId
+  }
+  deriving (Eq, Show)
+pCSSGetInlineStylesForNode
+  :: DOMPageNetworkEmulationSecurity.DOMNodeId
+  -> PCSSGetInlineStylesForNode
+pCSSGetInlineStylesForNode
+  arg_pCSSGetInlineStylesForNodeNodeId
+  = PCSSGetInlineStylesForNode
+    arg_pCSSGetInlineStylesForNodeNodeId
+instance ToJSON PCSSGetInlineStylesForNode where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> Just (pCSSGetInlineStylesForNodeNodeId p)
+    ]
+data CSSGetInlineStylesForNode = CSSGetInlineStylesForNode
+  {
+    -- | Inline style for the specified DOM node.
+    cSSGetInlineStylesForNodeInlineStyle :: Maybe CSSCSSStyle,
+    -- | Attribute-defined element style (e.g. resulting from "width=20 height=100%").
+    cSSGetInlineStylesForNodeAttributesStyle :: Maybe CSSCSSStyle
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSGetInlineStylesForNode where
+  parseJSON = A.withObject "CSSGetInlineStylesForNode" $ \o -> CSSGetInlineStylesForNode
+    <$> o A..:? "inlineStyle"
+    <*> o A..:? "attributesStyle"
+instance Command PCSSGetInlineStylesForNode where
+  type CommandResponse PCSSGetInlineStylesForNode = CSSGetInlineStylesForNode
+  commandName _ = "CSS.getInlineStylesForNode"
+
+-- | Returns requested styles for a DOM node identified by `nodeId`.
+
+-- | Parameters of the 'CSS.getMatchedStylesForNode' command.
+data PCSSGetMatchedStylesForNode = PCSSGetMatchedStylesForNode
+  {
+    pCSSGetMatchedStylesForNodeNodeId :: DOMPageNetworkEmulationSecurity.DOMNodeId
+  }
+  deriving (Eq, Show)
+pCSSGetMatchedStylesForNode
+  :: DOMPageNetworkEmulationSecurity.DOMNodeId
+  -> PCSSGetMatchedStylesForNode
+pCSSGetMatchedStylesForNode
+  arg_pCSSGetMatchedStylesForNodeNodeId
+  = PCSSGetMatchedStylesForNode
+    arg_pCSSGetMatchedStylesForNodeNodeId
+instance ToJSON PCSSGetMatchedStylesForNode where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> Just (pCSSGetMatchedStylesForNodeNodeId p)
+    ]
+data CSSGetMatchedStylesForNode = CSSGetMatchedStylesForNode
+  {
+    -- | Inline style for the specified DOM node.
+    cSSGetMatchedStylesForNodeInlineStyle :: Maybe CSSCSSStyle,
+    -- | Attribute-defined element style (e.g. resulting from "width=20 height=100%").
+    cSSGetMatchedStylesForNodeAttributesStyle :: Maybe CSSCSSStyle,
+    -- | CSS rules matching this node, from all applicable stylesheets.
+    cSSGetMatchedStylesForNodeMatchedCSSRules :: Maybe [CSSRuleMatch],
+    -- | Pseudo style matches for this node.
+    cSSGetMatchedStylesForNodePseudoElements :: Maybe [CSSPseudoElementMatches],
+    -- | A chain of inherited styles (from the immediate node parent up to the DOM tree root).
+    cSSGetMatchedStylesForNodeInherited :: Maybe [CSSInheritedStyleEntry],
+    -- | A chain of inherited pseudo element styles (from the immediate node parent up to the DOM tree root).
+    cSSGetMatchedStylesForNodeInheritedPseudoElements :: Maybe [CSSInheritedPseudoElementMatches],
+    -- | A list of CSS keyframed animations matching this node.
+    cSSGetMatchedStylesForNodeCssKeyframesRules :: Maybe [CSSCSSKeyframesRule],
+    -- | Id of the first parent element that does not have display: contents.
+    cSSGetMatchedStylesForNodeParentLayoutNodeId :: Maybe DOMPageNetworkEmulationSecurity.DOMNodeId
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSGetMatchedStylesForNode where
+  parseJSON = A.withObject "CSSGetMatchedStylesForNode" $ \o -> CSSGetMatchedStylesForNode
+    <$> o A..:? "inlineStyle"
+    <*> o A..:? "attributesStyle"
+    <*> o A..:? "matchedCSSRules"
+    <*> o A..:? "pseudoElements"
+    <*> o A..:? "inherited"
+    <*> o A..:? "inheritedPseudoElements"
+    <*> o A..:? "cssKeyframesRules"
+    <*> o A..:? "parentLayoutNodeId"
+instance Command PCSSGetMatchedStylesForNode where
+  type CommandResponse PCSSGetMatchedStylesForNode = CSSGetMatchedStylesForNode
+  commandName _ = "CSS.getMatchedStylesForNode"
+
+-- | Returns all media queries parsed by the rendering engine.
+
+-- | Parameters of the 'CSS.getMediaQueries' command.
+data PCSSGetMediaQueries = PCSSGetMediaQueries
+  deriving (Eq, Show)
+pCSSGetMediaQueries
+  :: PCSSGetMediaQueries
+pCSSGetMediaQueries
+  = PCSSGetMediaQueries
+instance ToJSON PCSSGetMediaQueries where
+  toJSON _ = A.Null
+data CSSGetMediaQueries = CSSGetMediaQueries
+  {
+    cSSGetMediaQueriesMedias :: [CSSCSSMedia]
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSGetMediaQueries where
+  parseJSON = A.withObject "CSSGetMediaQueries" $ \o -> CSSGetMediaQueries
+    <$> o A..: "medias"
+instance Command PCSSGetMediaQueries where
+  type CommandResponse PCSSGetMediaQueries = CSSGetMediaQueries
+  commandName _ = "CSS.getMediaQueries"
+
+-- | Requests information about platform fonts which we used to render child TextNodes in the given
+--   node.
+
+-- | Parameters of the 'CSS.getPlatformFontsForNode' command.
+data PCSSGetPlatformFontsForNode = PCSSGetPlatformFontsForNode
+  {
+    pCSSGetPlatformFontsForNodeNodeId :: DOMPageNetworkEmulationSecurity.DOMNodeId
+  }
+  deriving (Eq, Show)
+pCSSGetPlatformFontsForNode
+  :: DOMPageNetworkEmulationSecurity.DOMNodeId
+  -> PCSSGetPlatformFontsForNode
+pCSSGetPlatformFontsForNode
+  arg_pCSSGetPlatformFontsForNodeNodeId
+  = PCSSGetPlatformFontsForNode
+    arg_pCSSGetPlatformFontsForNodeNodeId
+instance ToJSON PCSSGetPlatformFontsForNode where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> Just (pCSSGetPlatformFontsForNodeNodeId p)
+    ]
+data CSSGetPlatformFontsForNode = CSSGetPlatformFontsForNode
+  {
+    -- | Usage statistics for every employed platform font.
+    cSSGetPlatformFontsForNodeFonts :: [CSSPlatformFontUsage]
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSGetPlatformFontsForNode where
+  parseJSON = A.withObject "CSSGetPlatformFontsForNode" $ \o -> CSSGetPlatformFontsForNode
+    <$> o A..: "fonts"
+instance Command PCSSGetPlatformFontsForNode where
+  type CommandResponse PCSSGetPlatformFontsForNode = CSSGetPlatformFontsForNode
+  commandName _ = "CSS.getPlatformFontsForNode"
+
+-- | Returns the current textual content for a stylesheet.
+
+-- | Parameters of the 'CSS.getStyleSheetText' command.
+data PCSSGetStyleSheetText = PCSSGetStyleSheetText
+  {
+    pCSSGetStyleSheetTextStyleSheetId :: CSSStyleSheetId
+  }
+  deriving (Eq, Show)
+pCSSGetStyleSheetText
+  :: CSSStyleSheetId
+  -> PCSSGetStyleSheetText
+pCSSGetStyleSheetText
+  arg_pCSSGetStyleSheetTextStyleSheetId
+  = PCSSGetStyleSheetText
+    arg_pCSSGetStyleSheetTextStyleSheetId
+instance ToJSON PCSSGetStyleSheetText where
+  toJSON p = A.object $ catMaybes [
+    ("styleSheetId" A..=) <$> Just (pCSSGetStyleSheetTextStyleSheetId p)
+    ]
+data CSSGetStyleSheetText = CSSGetStyleSheetText
+  {
+    -- | The stylesheet text.
+    cSSGetStyleSheetTextText :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSGetStyleSheetText where
+  parseJSON = A.withObject "CSSGetStyleSheetText" $ \o -> CSSGetStyleSheetText
+    <$> o A..: "text"
+instance Command PCSSGetStyleSheetText where
+  type CommandResponse PCSSGetStyleSheetText = CSSGetStyleSheetText
+  commandName _ = "CSS.getStyleSheetText"
+
+-- | Returns all layers parsed by the rendering engine for the tree scope of a node.
+--   Given a DOM element identified by nodeId, getLayersForNode returns the root
+--   layer for the nearest ancestor document or shadow root. The layer root contains
+--   the full layer tree for the tree scope and their ordering.
+
+-- | Parameters of the 'CSS.getLayersForNode' command.
+data PCSSGetLayersForNode = PCSSGetLayersForNode
+  {
+    pCSSGetLayersForNodeNodeId :: DOMPageNetworkEmulationSecurity.DOMNodeId
+  }
+  deriving (Eq, Show)
+pCSSGetLayersForNode
+  :: DOMPageNetworkEmulationSecurity.DOMNodeId
+  -> PCSSGetLayersForNode
+pCSSGetLayersForNode
+  arg_pCSSGetLayersForNodeNodeId
+  = PCSSGetLayersForNode
+    arg_pCSSGetLayersForNodeNodeId
+instance ToJSON PCSSGetLayersForNode where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> Just (pCSSGetLayersForNodeNodeId p)
+    ]
+data CSSGetLayersForNode = CSSGetLayersForNode
+  {
+    cSSGetLayersForNodeRootLayer :: CSSCSSLayerData
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSGetLayersForNode where
+  parseJSON = A.withObject "CSSGetLayersForNode" $ \o -> CSSGetLayersForNode
+    <$> o A..: "rootLayer"
+instance Command PCSSGetLayersForNode where
+  type CommandResponse PCSSGetLayersForNode = CSSGetLayersForNode
+  commandName _ = "CSS.getLayersForNode"
+
+-- | Starts tracking the given computed styles for updates. The specified array of properties
+--   replaces the one previously specified. Pass empty array to disable tracking.
+--   Use takeComputedStyleUpdates to retrieve the list of nodes that had properties modified.
+--   The changes to computed style properties are only tracked for nodes pushed to the front-end
+--   by the DOM agent. If no changes to the tracked properties occur after the node has been pushed
+--   to the front-end, no updates will be issued for the node.
+
+-- | Parameters of the 'CSS.trackComputedStyleUpdates' command.
+data PCSSTrackComputedStyleUpdates = PCSSTrackComputedStyleUpdates
+  {
+    pCSSTrackComputedStyleUpdatesPropertiesToTrack :: [CSSCSSComputedStyleProperty]
+  }
+  deriving (Eq, Show)
+pCSSTrackComputedStyleUpdates
+  :: [CSSCSSComputedStyleProperty]
+  -> PCSSTrackComputedStyleUpdates
+pCSSTrackComputedStyleUpdates
+  arg_pCSSTrackComputedStyleUpdatesPropertiesToTrack
+  = PCSSTrackComputedStyleUpdates
+    arg_pCSSTrackComputedStyleUpdatesPropertiesToTrack
+instance ToJSON PCSSTrackComputedStyleUpdates where
+  toJSON p = A.object $ catMaybes [
+    ("propertiesToTrack" A..=) <$> Just (pCSSTrackComputedStyleUpdatesPropertiesToTrack p)
+    ]
+instance Command PCSSTrackComputedStyleUpdates where
+  type CommandResponse PCSSTrackComputedStyleUpdates = ()
+  commandName _ = "CSS.trackComputedStyleUpdates"
+  fromJSON = const . A.Success . const ()
+
+-- | Polls the next batch of computed style updates.
+
+-- | Parameters of the 'CSS.takeComputedStyleUpdates' command.
+data PCSSTakeComputedStyleUpdates = PCSSTakeComputedStyleUpdates
+  deriving (Eq, Show)
+pCSSTakeComputedStyleUpdates
+  :: PCSSTakeComputedStyleUpdates
+pCSSTakeComputedStyleUpdates
+  = PCSSTakeComputedStyleUpdates
+instance ToJSON PCSSTakeComputedStyleUpdates where
+  toJSON _ = A.Null
+data CSSTakeComputedStyleUpdates = CSSTakeComputedStyleUpdates
+  {
+    -- | The list of node Ids that have their tracked computed styles updated
+    cSSTakeComputedStyleUpdatesNodeIds :: [DOMPageNetworkEmulationSecurity.DOMNodeId]
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSTakeComputedStyleUpdates where
+  parseJSON = A.withObject "CSSTakeComputedStyleUpdates" $ \o -> CSSTakeComputedStyleUpdates
+    <$> o A..: "nodeIds"
+instance Command PCSSTakeComputedStyleUpdates where
+  type CommandResponse PCSSTakeComputedStyleUpdates = CSSTakeComputedStyleUpdates
+  commandName _ = "CSS.takeComputedStyleUpdates"
+
+-- | Find a rule with the given active property for the given node and set the new value for this
+--   property
+
+-- | Parameters of the 'CSS.setEffectivePropertyValueForNode' command.
+data PCSSSetEffectivePropertyValueForNode = PCSSSetEffectivePropertyValueForNode
+  {
+    -- | The element id for which to set property.
+    pCSSSetEffectivePropertyValueForNodeNodeId :: DOMPageNetworkEmulationSecurity.DOMNodeId,
+    pCSSSetEffectivePropertyValueForNodePropertyName :: T.Text,
+    pCSSSetEffectivePropertyValueForNodeValue :: T.Text
+  }
+  deriving (Eq, Show)
+pCSSSetEffectivePropertyValueForNode
+  {-
+  -- | The element id for which to set property.
+  -}
+  :: DOMPageNetworkEmulationSecurity.DOMNodeId
+  -> T.Text
+  -> T.Text
+  -> PCSSSetEffectivePropertyValueForNode
+pCSSSetEffectivePropertyValueForNode
+  arg_pCSSSetEffectivePropertyValueForNodeNodeId
+  arg_pCSSSetEffectivePropertyValueForNodePropertyName
+  arg_pCSSSetEffectivePropertyValueForNodeValue
+  = PCSSSetEffectivePropertyValueForNode
+    arg_pCSSSetEffectivePropertyValueForNodeNodeId
+    arg_pCSSSetEffectivePropertyValueForNodePropertyName
+    arg_pCSSSetEffectivePropertyValueForNodeValue
+instance ToJSON PCSSSetEffectivePropertyValueForNode where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> Just (pCSSSetEffectivePropertyValueForNodeNodeId p),
+    ("propertyName" A..=) <$> Just (pCSSSetEffectivePropertyValueForNodePropertyName p),
+    ("value" A..=) <$> Just (pCSSSetEffectivePropertyValueForNodeValue p)
+    ]
+instance Command PCSSSetEffectivePropertyValueForNode where
+  type CommandResponse PCSSSetEffectivePropertyValueForNode = ()
+  commandName _ = "CSS.setEffectivePropertyValueForNode"
+  fromJSON = const . A.Success . const ()
+
+-- | Modifies the keyframe rule key text.
+
+-- | Parameters of the 'CSS.setKeyframeKey' command.
+data PCSSSetKeyframeKey = PCSSSetKeyframeKey
+  {
+    pCSSSetKeyframeKeyStyleSheetId :: CSSStyleSheetId,
+    pCSSSetKeyframeKeyRange :: CSSSourceRange,
+    pCSSSetKeyframeKeyKeyText :: T.Text
+  }
+  deriving (Eq, Show)
+pCSSSetKeyframeKey
+  :: CSSStyleSheetId
+  -> CSSSourceRange
+  -> T.Text
+  -> PCSSSetKeyframeKey
+pCSSSetKeyframeKey
+  arg_pCSSSetKeyframeKeyStyleSheetId
+  arg_pCSSSetKeyframeKeyRange
+  arg_pCSSSetKeyframeKeyKeyText
+  = PCSSSetKeyframeKey
+    arg_pCSSSetKeyframeKeyStyleSheetId
+    arg_pCSSSetKeyframeKeyRange
+    arg_pCSSSetKeyframeKeyKeyText
+instance ToJSON PCSSSetKeyframeKey where
+  toJSON p = A.object $ catMaybes [
+    ("styleSheetId" A..=) <$> Just (pCSSSetKeyframeKeyStyleSheetId p),
+    ("range" A..=) <$> Just (pCSSSetKeyframeKeyRange p),
+    ("keyText" A..=) <$> Just (pCSSSetKeyframeKeyKeyText p)
+    ]
+data CSSSetKeyframeKey = CSSSetKeyframeKey
+  {
+    -- | The resulting key text after modification.
+    cSSSetKeyframeKeyKeyText :: CSSValue
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSSetKeyframeKey where
+  parseJSON = A.withObject "CSSSetKeyframeKey" $ \o -> CSSSetKeyframeKey
+    <$> o A..: "keyText"
+instance Command PCSSSetKeyframeKey where
+  type CommandResponse PCSSSetKeyframeKey = CSSSetKeyframeKey
+  commandName _ = "CSS.setKeyframeKey"
+
+-- | Modifies the rule selector.
+
+-- | Parameters of the 'CSS.setMediaText' command.
+data PCSSSetMediaText = PCSSSetMediaText
+  {
+    pCSSSetMediaTextStyleSheetId :: CSSStyleSheetId,
+    pCSSSetMediaTextRange :: CSSSourceRange,
+    pCSSSetMediaTextText :: T.Text
+  }
+  deriving (Eq, Show)
+pCSSSetMediaText
+  :: CSSStyleSheetId
+  -> CSSSourceRange
+  -> T.Text
+  -> PCSSSetMediaText
+pCSSSetMediaText
+  arg_pCSSSetMediaTextStyleSheetId
+  arg_pCSSSetMediaTextRange
+  arg_pCSSSetMediaTextText
+  = PCSSSetMediaText
+    arg_pCSSSetMediaTextStyleSheetId
+    arg_pCSSSetMediaTextRange
+    arg_pCSSSetMediaTextText
+instance ToJSON PCSSSetMediaText where
+  toJSON p = A.object $ catMaybes [
+    ("styleSheetId" A..=) <$> Just (pCSSSetMediaTextStyleSheetId p),
+    ("range" A..=) <$> Just (pCSSSetMediaTextRange p),
+    ("text" A..=) <$> Just (pCSSSetMediaTextText p)
+    ]
+data CSSSetMediaText = CSSSetMediaText
+  {
+    -- | The resulting CSS media rule after modification.
+    cSSSetMediaTextMedia :: CSSCSSMedia
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSSetMediaText where
+  parseJSON = A.withObject "CSSSetMediaText" $ \o -> CSSSetMediaText
+    <$> o A..: "media"
+instance Command PCSSSetMediaText where
+  type CommandResponse PCSSSetMediaText = CSSSetMediaText
+  commandName _ = "CSS.setMediaText"
+
+-- | Modifies the expression of a container query.
+
+-- | Parameters of the 'CSS.setContainerQueryText' command.
+data PCSSSetContainerQueryText = PCSSSetContainerQueryText
+  {
+    pCSSSetContainerQueryTextStyleSheetId :: CSSStyleSheetId,
+    pCSSSetContainerQueryTextRange :: CSSSourceRange,
+    pCSSSetContainerQueryTextText :: T.Text
+  }
+  deriving (Eq, Show)
+pCSSSetContainerQueryText
+  :: CSSStyleSheetId
+  -> CSSSourceRange
+  -> T.Text
+  -> PCSSSetContainerQueryText
+pCSSSetContainerQueryText
+  arg_pCSSSetContainerQueryTextStyleSheetId
+  arg_pCSSSetContainerQueryTextRange
+  arg_pCSSSetContainerQueryTextText
+  = PCSSSetContainerQueryText
+    arg_pCSSSetContainerQueryTextStyleSheetId
+    arg_pCSSSetContainerQueryTextRange
+    arg_pCSSSetContainerQueryTextText
+instance ToJSON PCSSSetContainerQueryText where
+  toJSON p = A.object $ catMaybes [
+    ("styleSheetId" A..=) <$> Just (pCSSSetContainerQueryTextStyleSheetId p),
+    ("range" A..=) <$> Just (pCSSSetContainerQueryTextRange p),
+    ("text" A..=) <$> Just (pCSSSetContainerQueryTextText p)
+    ]
+data CSSSetContainerQueryText = CSSSetContainerQueryText
+  {
+    -- | The resulting CSS container query rule after modification.
+    cSSSetContainerQueryTextContainerQuery :: CSSCSSContainerQuery
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSSetContainerQueryText where
+  parseJSON = A.withObject "CSSSetContainerQueryText" $ \o -> CSSSetContainerQueryText
+    <$> o A..: "containerQuery"
+instance Command PCSSSetContainerQueryText where
+  type CommandResponse PCSSSetContainerQueryText = CSSSetContainerQueryText
+  commandName _ = "CSS.setContainerQueryText"
+
+-- | Modifies the expression of a supports at-rule.
+
+-- | Parameters of the 'CSS.setSupportsText' command.
+data PCSSSetSupportsText = PCSSSetSupportsText
+  {
+    pCSSSetSupportsTextStyleSheetId :: CSSStyleSheetId,
+    pCSSSetSupportsTextRange :: CSSSourceRange,
+    pCSSSetSupportsTextText :: T.Text
+  }
+  deriving (Eq, Show)
+pCSSSetSupportsText
+  :: CSSStyleSheetId
+  -> CSSSourceRange
+  -> T.Text
+  -> PCSSSetSupportsText
+pCSSSetSupportsText
+  arg_pCSSSetSupportsTextStyleSheetId
+  arg_pCSSSetSupportsTextRange
+  arg_pCSSSetSupportsTextText
+  = PCSSSetSupportsText
+    arg_pCSSSetSupportsTextStyleSheetId
+    arg_pCSSSetSupportsTextRange
+    arg_pCSSSetSupportsTextText
+instance ToJSON PCSSSetSupportsText where
+  toJSON p = A.object $ catMaybes [
+    ("styleSheetId" A..=) <$> Just (pCSSSetSupportsTextStyleSheetId p),
+    ("range" A..=) <$> Just (pCSSSetSupportsTextRange p),
+    ("text" A..=) <$> Just (pCSSSetSupportsTextText p)
+    ]
+data CSSSetSupportsText = CSSSetSupportsText
+  {
+    -- | The resulting CSS Supports rule after modification.
+    cSSSetSupportsTextSupports :: CSSCSSSupports
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSSetSupportsText where
+  parseJSON = A.withObject "CSSSetSupportsText" $ \o -> CSSSetSupportsText
+    <$> o A..: "supports"
+instance Command PCSSSetSupportsText where
+  type CommandResponse PCSSSetSupportsText = CSSSetSupportsText
+  commandName _ = "CSS.setSupportsText"
+
+-- | Modifies the expression of a scope at-rule.
+
+-- | Parameters of the 'CSS.setScopeText' command.
+data PCSSSetScopeText = PCSSSetScopeText
+  {
+    pCSSSetScopeTextStyleSheetId :: CSSStyleSheetId,
+    pCSSSetScopeTextRange :: CSSSourceRange,
+    pCSSSetScopeTextText :: T.Text
+  }
+  deriving (Eq, Show)
+pCSSSetScopeText
+  :: CSSStyleSheetId
+  -> CSSSourceRange
+  -> T.Text
+  -> PCSSSetScopeText
+pCSSSetScopeText
+  arg_pCSSSetScopeTextStyleSheetId
+  arg_pCSSSetScopeTextRange
+  arg_pCSSSetScopeTextText
+  = PCSSSetScopeText
+    arg_pCSSSetScopeTextStyleSheetId
+    arg_pCSSSetScopeTextRange
+    arg_pCSSSetScopeTextText
+instance ToJSON PCSSSetScopeText where
+  toJSON p = A.object $ catMaybes [
+    ("styleSheetId" A..=) <$> Just (pCSSSetScopeTextStyleSheetId p),
+    ("range" A..=) <$> Just (pCSSSetScopeTextRange p),
+    ("text" A..=) <$> Just (pCSSSetScopeTextText p)
+    ]
+data CSSSetScopeText = CSSSetScopeText
+  {
+    -- | The resulting CSS Scope rule after modification.
+    cSSSetScopeTextScope :: CSSCSSScope
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSSetScopeText where
+  parseJSON = A.withObject "CSSSetScopeText" $ \o -> CSSSetScopeText
+    <$> o A..: "scope"
+instance Command PCSSSetScopeText where
+  type CommandResponse PCSSSetScopeText = CSSSetScopeText
+  commandName _ = "CSS.setScopeText"
+
+-- | Modifies the rule selector.
+
+-- | Parameters of the 'CSS.setRuleSelector' command.
+data PCSSSetRuleSelector = PCSSSetRuleSelector
+  {
+    pCSSSetRuleSelectorStyleSheetId :: CSSStyleSheetId,
+    pCSSSetRuleSelectorRange :: CSSSourceRange,
+    pCSSSetRuleSelectorSelector :: T.Text
+  }
+  deriving (Eq, Show)
+pCSSSetRuleSelector
+  :: CSSStyleSheetId
+  -> CSSSourceRange
+  -> T.Text
+  -> PCSSSetRuleSelector
+pCSSSetRuleSelector
+  arg_pCSSSetRuleSelectorStyleSheetId
+  arg_pCSSSetRuleSelectorRange
+  arg_pCSSSetRuleSelectorSelector
+  = PCSSSetRuleSelector
+    arg_pCSSSetRuleSelectorStyleSheetId
+    arg_pCSSSetRuleSelectorRange
+    arg_pCSSSetRuleSelectorSelector
+instance ToJSON PCSSSetRuleSelector where
+  toJSON p = A.object $ catMaybes [
+    ("styleSheetId" A..=) <$> Just (pCSSSetRuleSelectorStyleSheetId p),
+    ("range" A..=) <$> Just (pCSSSetRuleSelectorRange p),
+    ("selector" A..=) <$> Just (pCSSSetRuleSelectorSelector p)
+    ]
+data CSSSetRuleSelector = CSSSetRuleSelector
+  {
+    -- | The resulting selector list after modification.
+    cSSSetRuleSelectorSelectorList :: CSSSelectorList
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSSetRuleSelector where
+  parseJSON = A.withObject "CSSSetRuleSelector" $ \o -> CSSSetRuleSelector
+    <$> o A..: "selectorList"
+instance Command PCSSSetRuleSelector where
+  type CommandResponse PCSSSetRuleSelector = CSSSetRuleSelector
+  commandName _ = "CSS.setRuleSelector"
+
+-- | Sets the new stylesheet text.
+
+-- | Parameters of the 'CSS.setStyleSheetText' command.
+data PCSSSetStyleSheetText = PCSSSetStyleSheetText
+  {
+    pCSSSetStyleSheetTextStyleSheetId :: CSSStyleSheetId,
+    pCSSSetStyleSheetTextText :: T.Text
+  }
+  deriving (Eq, Show)
+pCSSSetStyleSheetText
+  :: CSSStyleSheetId
+  -> T.Text
+  -> PCSSSetStyleSheetText
+pCSSSetStyleSheetText
+  arg_pCSSSetStyleSheetTextStyleSheetId
+  arg_pCSSSetStyleSheetTextText
+  = PCSSSetStyleSheetText
+    arg_pCSSSetStyleSheetTextStyleSheetId
+    arg_pCSSSetStyleSheetTextText
+instance ToJSON PCSSSetStyleSheetText where
+  toJSON p = A.object $ catMaybes [
+    ("styleSheetId" A..=) <$> Just (pCSSSetStyleSheetTextStyleSheetId p),
+    ("text" A..=) <$> Just (pCSSSetStyleSheetTextText p)
+    ]
+data CSSSetStyleSheetText = CSSSetStyleSheetText
+  {
+    -- | URL of source map associated with script (if any).
+    cSSSetStyleSheetTextSourceMapURL :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSSetStyleSheetText where
+  parseJSON = A.withObject "CSSSetStyleSheetText" $ \o -> CSSSetStyleSheetText
+    <$> o A..:? "sourceMapURL"
+instance Command PCSSSetStyleSheetText where
+  type CommandResponse PCSSSetStyleSheetText = CSSSetStyleSheetText
+  commandName _ = "CSS.setStyleSheetText"
+
+-- | Applies specified style edits one after another in the given order.
+
+-- | Parameters of the 'CSS.setStyleTexts' command.
+data PCSSSetStyleTexts = PCSSSetStyleTexts
+  {
+    pCSSSetStyleTextsEdits :: [CSSStyleDeclarationEdit]
+  }
+  deriving (Eq, Show)
+pCSSSetStyleTexts
+  :: [CSSStyleDeclarationEdit]
+  -> PCSSSetStyleTexts
+pCSSSetStyleTexts
+  arg_pCSSSetStyleTextsEdits
+  = PCSSSetStyleTexts
+    arg_pCSSSetStyleTextsEdits
+instance ToJSON PCSSSetStyleTexts where
+  toJSON p = A.object $ catMaybes [
+    ("edits" A..=) <$> Just (pCSSSetStyleTextsEdits p)
+    ]
+data CSSSetStyleTexts = CSSSetStyleTexts
+  {
+    -- | The resulting styles after modification.
+    cSSSetStyleTextsStyles :: [CSSCSSStyle]
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSSetStyleTexts where
+  parseJSON = A.withObject "CSSSetStyleTexts" $ \o -> CSSSetStyleTexts
+    <$> o A..: "styles"
+instance Command PCSSSetStyleTexts where
+  type CommandResponse PCSSSetStyleTexts = CSSSetStyleTexts
+  commandName _ = "CSS.setStyleTexts"
+
+-- | Enables the selector recording.
+
+-- | Parameters of the 'CSS.startRuleUsageTracking' command.
+data PCSSStartRuleUsageTracking = PCSSStartRuleUsageTracking
+  deriving (Eq, Show)
+pCSSStartRuleUsageTracking
+  :: PCSSStartRuleUsageTracking
+pCSSStartRuleUsageTracking
+  = PCSSStartRuleUsageTracking
+instance ToJSON PCSSStartRuleUsageTracking where
+  toJSON _ = A.Null
+instance Command PCSSStartRuleUsageTracking where
+  type CommandResponse PCSSStartRuleUsageTracking = ()
+  commandName _ = "CSS.startRuleUsageTracking"
+  fromJSON = const . A.Success . const ()
+
+-- | Stop tracking rule usage and return the list of rules that were used since last call to
+--   `takeCoverageDelta` (or since start of coverage instrumentation)
+
+-- | Parameters of the 'CSS.stopRuleUsageTracking' command.
+data PCSSStopRuleUsageTracking = PCSSStopRuleUsageTracking
+  deriving (Eq, Show)
+pCSSStopRuleUsageTracking
+  :: PCSSStopRuleUsageTracking
+pCSSStopRuleUsageTracking
+  = PCSSStopRuleUsageTracking
+instance ToJSON PCSSStopRuleUsageTracking where
+  toJSON _ = A.Null
+data CSSStopRuleUsageTracking = CSSStopRuleUsageTracking
+  {
+    cSSStopRuleUsageTrackingRuleUsage :: [CSSRuleUsage]
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSStopRuleUsageTracking where
+  parseJSON = A.withObject "CSSStopRuleUsageTracking" $ \o -> CSSStopRuleUsageTracking
+    <$> o A..: "ruleUsage"
+instance Command PCSSStopRuleUsageTracking where
+  type CommandResponse PCSSStopRuleUsageTracking = CSSStopRuleUsageTracking
+  commandName _ = "CSS.stopRuleUsageTracking"
+
+-- | Obtain list of rules that became used since last call to this method (or since start of coverage
+--   instrumentation)
+
+-- | Parameters of the 'CSS.takeCoverageDelta' command.
+data PCSSTakeCoverageDelta = PCSSTakeCoverageDelta
+  deriving (Eq, Show)
+pCSSTakeCoverageDelta
+  :: PCSSTakeCoverageDelta
+pCSSTakeCoverageDelta
+  = PCSSTakeCoverageDelta
+instance ToJSON PCSSTakeCoverageDelta where
+  toJSON _ = A.Null
+data CSSTakeCoverageDelta = CSSTakeCoverageDelta
+  {
+    cSSTakeCoverageDeltaCoverage :: [CSSRuleUsage],
+    -- | Monotonically increasing time, in seconds.
+    cSSTakeCoverageDeltaTimestamp :: Double
+  }
+  deriving (Eq, Show)
+instance FromJSON CSSTakeCoverageDelta where
+  parseJSON = A.withObject "CSSTakeCoverageDelta" $ \o -> CSSTakeCoverageDelta
+    <$> o A..: "coverage"
+    <*> o A..: "timestamp"
+instance Command PCSSTakeCoverageDelta where
+  type CommandResponse PCSSTakeCoverageDelta = CSSTakeCoverageDelta
+  commandName _ = "CSS.takeCoverageDelta"
+
+-- | Enables/disables rendering of local CSS fonts (enabled by default).
+
+-- | Parameters of the 'CSS.setLocalFontsEnabled' command.
+data PCSSSetLocalFontsEnabled = PCSSSetLocalFontsEnabled
+  {
+    -- | Whether rendering of local fonts is enabled.
+    pCSSSetLocalFontsEnabledEnabled :: Bool
+  }
+  deriving (Eq, Show)
+pCSSSetLocalFontsEnabled
+  {-
+  -- | Whether rendering of local fonts is enabled.
+  -}
+  :: Bool
+  -> PCSSSetLocalFontsEnabled
+pCSSSetLocalFontsEnabled
+  arg_pCSSSetLocalFontsEnabledEnabled
+  = PCSSSetLocalFontsEnabled
+    arg_pCSSSetLocalFontsEnabledEnabled
+instance ToJSON PCSSSetLocalFontsEnabled where
+  toJSON p = A.object $ catMaybes [
+    ("enabled" A..=) <$> Just (pCSSSetLocalFontsEnabledEnabled p)
+    ]
+instance Command PCSSSetLocalFontsEnabled where
+  type CommandResponse PCSSSetLocalFontsEnabled = ()
+  commandName _ = "CSS.setLocalFontsEnabled"
+  fromJSON = const . A.Success . const ()
+
diff --git a/src/CDP/Domains/CacheStorage.hs b/src/CDP/Domains/CacheStorage.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains/CacheStorage.hs
@@ -0,0 +1,383 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+
+
+{- |
+= CacheStorage
+
+-}
+
+
+module CDP.Domains.CacheStorage (module CDP.Domains.CacheStorage) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+
+
+
+-- | Type 'CacheStorage.CacheId'.
+--   Unique identifier of the Cache object.
+type CacheStorageCacheId = T.Text
+
+-- | Type 'CacheStorage.CachedResponseType'.
+--   type of HTTP response cached
+data CacheStorageCachedResponseType = CacheStorageCachedResponseTypeBasic | CacheStorageCachedResponseTypeCors | CacheStorageCachedResponseTypeDefault | CacheStorageCachedResponseTypeError | CacheStorageCachedResponseTypeOpaqueResponse | CacheStorageCachedResponseTypeOpaqueRedirect
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON CacheStorageCachedResponseType where
+  parseJSON = A.withText "CacheStorageCachedResponseType" $ \v -> case v of
+    "basic" -> pure CacheStorageCachedResponseTypeBasic
+    "cors" -> pure CacheStorageCachedResponseTypeCors
+    "default" -> pure CacheStorageCachedResponseTypeDefault
+    "error" -> pure CacheStorageCachedResponseTypeError
+    "opaqueResponse" -> pure CacheStorageCachedResponseTypeOpaqueResponse
+    "opaqueRedirect" -> pure CacheStorageCachedResponseTypeOpaqueRedirect
+    "_" -> fail "failed to parse CacheStorageCachedResponseType"
+instance ToJSON CacheStorageCachedResponseType where
+  toJSON v = A.String $ case v of
+    CacheStorageCachedResponseTypeBasic -> "basic"
+    CacheStorageCachedResponseTypeCors -> "cors"
+    CacheStorageCachedResponseTypeDefault -> "default"
+    CacheStorageCachedResponseTypeError -> "error"
+    CacheStorageCachedResponseTypeOpaqueResponse -> "opaqueResponse"
+    CacheStorageCachedResponseTypeOpaqueRedirect -> "opaqueRedirect"
+
+-- | Type 'CacheStorage.DataEntry'.
+--   Data entry.
+data CacheStorageDataEntry = CacheStorageDataEntry
+  {
+    -- | Request URL.
+    cacheStorageDataEntryRequestURL :: T.Text,
+    -- | Request method.
+    cacheStorageDataEntryRequestMethod :: T.Text,
+    -- | Request headers
+    cacheStorageDataEntryRequestHeaders :: [CacheStorageHeader],
+    -- | Number of seconds since epoch.
+    cacheStorageDataEntryResponseTime :: Double,
+    -- | HTTP response status code.
+    cacheStorageDataEntryResponseStatus :: Int,
+    -- | HTTP response status text.
+    cacheStorageDataEntryResponseStatusText :: T.Text,
+    -- | HTTP response type
+    cacheStorageDataEntryResponseType :: CacheStorageCachedResponseType,
+    -- | Response headers
+    cacheStorageDataEntryResponseHeaders :: [CacheStorageHeader]
+  }
+  deriving (Eq, Show)
+instance FromJSON CacheStorageDataEntry where
+  parseJSON = A.withObject "CacheStorageDataEntry" $ \o -> CacheStorageDataEntry
+    <$> o A..: "requestURL"
+    <*> o A..: "requestMethod"
+    <*> o A..: "requestHeaders"
+    <*> o A..: "responseTime"
+    <*> o A..: "responseStatus"
+    <*> o A..: "responseStatusText"
+    <*> o A..: "responseType"
+    <*> o A..: "responseHeaders"
+instance ToJSON CacheStorageDataEntry where
+  toJSON p = A.object $ catMaybes [
+    ("requestURL" A..=) <$> Just (cacheStorageDataEntryRequestURL p),
+    ("requestMethod" A..=) <$> Just (cacheStorageDataEntryRequestMethod p),
+    ("requestHeaders" A..=) <$> Just (cacheStorageDataEntryRequestHeaders p),
+    ("responseTime" A..=) <$> Just (cacheStorageDataEntryResponseTime p),
+    ("responseStatus" A..=) <$> Just (cacheStorageDataEntryResponseStatus p),
+    ("responseStatusText" A..=) <$> Just (cacheStorageDataEntryResponseStatusText p),
+    ("responseType" A..=) <$> Just (cacheStorageDataEntryResponseType p),
+    ("responseHeaders" A..=) <$> Just (cacheStorageDataEntryResponseHeaders p)
+    ]
+
+-- | Type 'CacheStorage.Cache'.
+--   Cache identifier.
+data CacheStorageCache = CacheStorageCache
+  {
+    -- | An opaque unique id of the cache.
+    cacheStorageCacheCacheId :: CacheStorageCacheId,
+    -- | Security origin of the cache.
+    cacheStorageCacheSecurityOrigin :: T.Text,
+    -- | The name of the cache.
+    cacheStorageCacheCacheName :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON CacheStorageCache where
+  parseJSON = A.withObject "CacheStorageCache" $ \o -> CacheStorageCache
+    <$> o A..: "cacheId"
+    <*> o A..: "securityOrigin"
+    <*> o A..: "cacheName"
+instance ToJSON CacheStorageCache where
+  toJSON p = A.object $ catMaybes [
+    ("cacheId" A..=) <$> Just (cacheStorageCacheCacheId p),
+    ("securityOrigin" A..=) <$> Just (cacheStorageCacheSecurityOrigin p),
+    ("cacheName" A..=) <$> Just (cacheStorageCacheCacheName p)
+    ]
+
+-- | Type 'CacheStorage.Header'.
+data CacheStorageHeader = CacheStorageHeader
+  {
+    cacheStorageHeaderName :: T.Text,
+    cacheStorageHeaderValue :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON CacheStorageHeader where
+  parseJSON = A.withObject "CacheStorageHeader" $ \o -> CacheStorageHeader
+    <$> o A..: "name"
+    <*> o A..: "value"
+instance ToJSON CacheStorageHeader where
+  toJSON p = A.object $ catMaybes [
+    ("name" A..=) <$> Just (cacheStorageHeaderName p),
+    ("value" A..=) <$> Just (cacheStorageHeaderValue p)
+    ]
+
+-- | Type 'CacheStorage.CachedResponse'.
+--   Cached response
+data CacheStorageCachedResponse = CacheStorageCachedResponse
+  {
+    -- | Entry content, base64-encoded. (Encoded as a base64 string when passed over JSON)
+    cacheStorageCachedResponseBody :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON CacheStorageCachedResponse where
+  parseJSON = A.withObject "CacheStorageCachedResponse" $ \o -> CacheStorageCachedResponse
+    <$> o A..: "body"
+instance ToJSON CacheStorageCachedResponse where
+  toJSON p = A.object $ catMaybes [
+    ("body" A..=) <$> Just (cacheStorageCachedResponseBody p)
+    ]
+
+-- | Deletes a cache.
+
+-- | Parameters of the 'CacheStorage.deleteCache' command.
+data PCacheStorageDeleteCache = PCacheStorageDeleteCache
+  {
+    -- | Id of cache for deletion.
+    pCacheStorageDeleteCacheCacheId :: CacheStorageCacheId
+  }
+  deriving (Eq, Show)
+pCacheStorageDeleteCache
+  {-
+  -- | Id of cache for deletion.
+  -}
+  :: CacheStorageCacheId
+  -> PCacheStorageDeleteCache
+pCacheStorageDeleteCache
+  arg_pCacheStorageDeleteCacheCacheId
+  = PCacheStorageDeleteCache
+    arg_pCacheStorageDeleteCacheCacheId
+instance ToJSON PCacheStorageDeleteCache where
+  toJSON p = A.object $ catMaybes [
+    ("cacheId" A..=) <$> Just (pCacheStorageDeleteCacheCacheId p)
+    ]
+instance Command PCacheStorageDeleteCache where
+  type CommandResponse PCacheStorageDeleteCache = ()
+  commandName _ = "CacheStorage.deleteCache"
+  fromJSON = const . A.Success . const ()
+
+-- | Deletes a cache entry.
+
+-- | Parameters of the 'CacheStorage.deleteEntry' command.
+data PCacheStorageDeleteEntry = PCacheStorageDeleteEntry
+  {
+    -- | Id of cache where the entry will be deleted.
+    pCacheStorageDeleteEntryCacheId :: CacheStorageCacheId,
+    -- | URL spec of the request.
+    pCacheStorageDeleteEntryRequest :: T.Text
+  }
+  deriving (Eq, Show)
+pCacheStorageDeleteEntry
+  {-
+  -- | Id of cache where the entry will be deleted.
+  -}
+  :: CacheStorageCacheId
+  {-
+  -- | URL spec of the request.
+  -}
+  -> T.Text
+  -> PCacheStorageDeleteEntry
+pCacheStorageDeleteEntry
+  arg_pCacheStorageDeleteEntryCacheId
+  arg_pCacheStorageDeleteEntryRequest
+  = PCacheStorageDeleteEntry
+    arg_pCacheStorageDeleteEntryCacheId
+    arg_pCacheStorageDeleteEntryRequest
+instance ToJSON PCacheStorageDeleteEntry where
+  toJSON p = A.object $ catMaybes [
+    ("cacheId" A..=) <$> Just (pCacheStorageDeleteEntryCacheId p),
+    ("request" A..=) <$> Just (pCacheStorageDeleteEntryRequest p)
+    ]
+instance Command PCacheStorageDeleteEntry where
+  type CommandResponse PCacheStorageDeleteEntry = ()
+  commandName _ = "CacheStorage.deleteEntry"
+  fromJSON = const . A.Success . const ()
+
+-- | Requests cache names.
+
+-- | Parameters of the 'CacheStorage.requestCacheNames' command.
+data PCacheStorageRequestCacheNames = PCacheStorageRequestCacheNames
+  {
+    -- | Security origin.
+    pCacheStorageRequestCacheNamesSecurityOrigin :: T.Text
+  }
+  deriving (Eq, Show)
+pCacheStorageRequestCacheNames
+  {-
+  -- | Security origin.
+  -}
+  :: T.Text
+  -> PCacheStorageRequestCacheNames
+pCacheStorageRequestCacheNames
+  arg_pCacheStorageRequestCacheNamesSecurityOrigin
+  = PCacheStorageRequestCacheNames
+    arg_pCacheStorageRequestCacheNamesSecurityOrigin
+instance ToJSON PCacheStorageRequestCacheNames where
+  toJSON p = A.object $ catMaybes [
+    ("securityOrigin" A..=) <$> Just (pCacheStorageRequestCacheNamesSecurityOrigin p)
+    ]
+data CacheStorageRequestCacheNames = CacheStorageRequestCacheNames
+  {
+    -- | Caches for the security origin.
+    cacheStorageRequestCacheNamesCaches :: [CacheStorageCache]
+  }
+  deriving (Eq, Show)
+instance FromJSON CacheStorageRequestCacheNames where
+  parseJSON = A.withObject "CacheStorageRequestCacheNames" $ \o -> CacheStorageRequestCacheNames
+    <$> o A..: "caches"
+instance Command PCacheStorageRequestCacheNames where
+  type CommandResponse PCacheStorageRequestCacheNames = CacheStorageRequestCacheNames
+  commandName _ = "CacheStorage.requestCacheNames"
+
+-- | Fetches cache entry.
+
+-- | Parameters of the 'CacheStorage.requestCachedResponse' command.
+data PCacheStorageRequestCachedResponse = PCacheStorageRequestCachedResponse
+  {
+    -- | Id of cache that contains the entry.
+    pCacheStorageRequestCachedResponseCacheId :: CacheStorageCacheId,
+    -- | URL spec of the request.
+    pCacheStorageRequestCachedResponseRequestURL :: T.Text,
+    -- | headers of the request.
+    pCacheStorageRequestCachedResponseRequestHeaders :: [CacheStorageHeader]
+  }
+  deriving (Eq, Show)
+pCacheStorageRequestCachedResponse
+  {-
+  -- | Id of cache that contains the entry.
+  -}
+  :: CacheStorageCacheId
+  {-
+  -- | URL spec of the request.
+  -}
+  -> T.Text
+  {-
+  -- | headers of the request.
+  -}
+  -> [CacheStorageHeader]
+  -> PCacheStorageRequestCachedResponse
+pCacheStorageRequestCachedResponse
+  arg_pCacheStorageRequestCachedResponseCacheId
+  arg_pCacheStorageRequestCachedResponseRequestURL
+  arg_pCacheStorageRequestCachedResponseRequestHeaders
+  = PCacheStorageRequestCachedResponse
+    arg_pCacheStorageRequestCachedResponseCacheId
+    arg_pCacheStorageRequestCachedResponseRequestURL
+    arg_pCacheStorageRequestCachedResponseRequestHeaders
+instance ToJSON PCacheStorageRequestCachedResponse where
+  toJSON p = A.object $ catMaybes [
+    ("cacheId" A..=) <$> Just (pCacheStorageRequestCachedResponseCacheId p),
+    ("requestURL" A..=) <$> Just (pCacheStorageRequestCachedResponseRequestURL p),
+    ("requestHeaders" A..=) <$> Just (pCacheStorageRequestCachedResponseRequestHeaders p)
+    ]
+data CacheStorageRequestCachedResponse = CacheStorageRequestCachedResponse
+  {
+    -- | Response read from the cache.
+    cacheStorageRequestCachedResponseResponse :: CacheStorageCachedResponse
+  }
+  deriving (Eq, Show)
+instance FromJSON CacheStorageRequestCachedResponse where
+  parseJSON = A.withObject "CacheStorageRequestCachedResponse" $ \o -> CacheStorageRequestCachedResponse
+    <$> o A..: "response"
+instance Command PCacheStorageRequestCachedResponse where
+  type CommandResponse PCacheStorageRequestCachedResponse = CacheStorageRequestCachedResponse
+  commandName _ = "CacheStorage.requestCachedResponse"
+
+-- | Requests data from cache.
+
+-- | Parameters of the 'CacheStorage.requestEntries' command.
+data PCacheStorageRequestEntries = PCacheStorageRequestEntries
+  {
+    -- | ID of cache to get entries from.
+    pCacheStorageRequestEntriesCacheId :: CacheStorageCacheId,
+    -- | Number of records to skip.
+    pCacheStorageRequestEntriesSkipCount :: Maybe Int,
+    -- | Number of records to fetch.
+    pCacheStorageRequestEntriesPageSize :: Maybe Int,
+    -- | If present, only return the entries containing this substring in the path
+    pCacheStorageRequestEntriesPathFilter :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+pCacheStorageRequestEntries
+  {-
+  -- | ID of cache to get entries from.
+  -}
+  :: CacheStorageCacheId
+  -> PCacheStorageRequestEntries
+pCacheStorageRequestEntries
+  arg_pCacheStorageRequestEntriesCacheId
+  = PCacheStorageRequestEntries
+    arg_pCacheStorageRequestEntriesCacheId
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PCacheStorageRequestEntries where
+  toJSON p = A.object $ catMaybes [
+    ("cacheId" A..=) <$> Just (pCacheStorageRequestEntriesCacheId p),
+    ("skipCount" A..=) <$> (pCacheStorageRequestEntriesSkipCount p),
+    ("pageSize" A..=) <$> (pCacheStorageRequestEntriesPageSize p),
+    ("pathFilter" A..=) <$> (pCacheStorageRequestEntriesPathFilter p)
+    ]
+data CacheStorageRequestEntries = CacheStorageRequestEntries
+  {
+    -- | Array of object store data entries.
+    cacheStorageRequestEntriesCacheDataEntries :: [CacheStorageDataEntry],
+    -- | Count of returned entries from this storage. If pathFilter is empty, it
+    --   is the count of all entries from this storage.
+    cacheStorageRequestEntriesReturnCount :: Double
+  }
+  deriving (Eq, Show)
+instance FromJSON CacheStorageRequestEntries where
+  parseJSON = A.withObject "CacheStorageRequestEntries" $ \o -> CacheStorageRequestEntries
+    <$> o A..: "cacheDataEntries"
+    <*> o A..: "returnCount"
+instance Command PCacheStorageRequestEntries where
+  type CommandResponse PCacheStorageRequestEntries = CacheStorageRequestEntries
+  commandName _ = "CacheStorage.requestEntries"
+
diff --git a/src/CDP/Domains/Cast.hs b/src/CDP/Domains/Cast.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains/Cast.hs
@@ -0,0 +1,236 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+
+
+{- |
+= Cast
+
+A domain for interacting with Cast, Presentation API, and Remote Playback API
+functionalities.
+-}
+
+
+module CDP.Domains.Cast (module CDP.Domains.Cast) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+
+
+
+-- | Type 'Cast.Sink'.
+data CastSink = CastSink
+  {
+    castSinkName :: T.Text,
+    castSinkId :: T.Text,
+    -- | Text describing the current session. Present only if there is an active
+    --   session on the sink.
+    castSinkSession :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON CastSink where
+  parseJSON = A.withObject "CastSink" $ \o -> CastSink
+    <$> o A..: "name"
+    <*> o A..: "id"
+    <*> o A..:? "session"
+instance ToJSON CastSink where
+  toJSON p = A.object $ catMaybes [
+    ("name" A..=) <$> Just (castSinkName p),
+    ("id" A..=) <$> Just (castSinkId p),
+    ("session" A..=) <$> (castSinkSession p)
+    ]
+
+-- | Type of the 'Cast.sinksUpdated' event.
+data CastSinksUpdated = CastSinksUpdated
+  {
+    castSinksUpdatedSinks :: [CastSink]
+  }
+  deriving (Eq, Show)
+instance FromJSON CastSinksUpdated where
+  parseJSON = A.withObject "CastSinksUpdated" $ \o -> CastSinksUpdated
+    <$> o A..: "sinks"
+instance Event CastSinksUpdated where
+  eventName _ = "Cast.sinksUpdated"
+
+-- | Type of the 'Cast.issueUpdated' event.
+data CastIssueUpdated = CastIssueUpdated
+  {
+    castIssueUpdatedIssueMessage :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON CastIssueUpdated where
+  parseJSON = A.withObject "CastIssueUpdated" $ \o -> CastIssueUpdated
+    <$> o A..: "issueMessage"
+instance Event CastIssueUpdated where
+  eventName _ = "Cast.issueUpdated"
+
+-- | Starts observing for sinks that can be used for tab mirroring, and if set,
+--   sinks compatible with |presentationUrl| as well. When sinks are found, a
+--   |sinksUpdated| event is fired.
+--   Also starts observing for issue messages. When an issue is added or removed,
+--   an |issueUpdated| event is fired.
+
+-- | Parameters of the 'Cast.enable' command.
+data PCastEnable = PCastEnable
+  {
+    pCastEnablePresentationUrl :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+pCastEnable
+  :: PCastEnable
+pCastEnable
+  = PCastEnable
+    Nothing
+instance ToJSON PCastEnable where
+  toJSON p = A.object $ catMaybes [
+    ("presentationUrl" A..=) <$> (pCastEnablePresentationUrl p)
+    ]
+instance Command PCastEnable where
+  type CommandResponse PCastEnable = ()
+  commandName _ = "Cast.enable"
+  fromJSON = const . A.Success . const ()
+
+-- | Stops observing for sinks and issues.
+
+-- | Parameters of the 'Cast.disable' command.
+data PCastDisable = PCastDisable
+  deriving (Eq, Show)
+pCastDisable
+  :: PCastDisable
+pCastDisable
+  = PCastDisable
+instance ToJSON PCastDisable where
+  toJSON _ = A.Null
+instance Command PCastDisable where
+  type CommandResponse PCastDisable = ()
+  commandName _ = "Cast.disable"
+  fromJSON = const . A.Success . const ()
+
+-- | Sets a sink to be used when the web page requests the browser to choose a
+--   sink via Presentation API, Remote Playback API, or Cast SDK.
+
+-- | Parameters of the 'Cast.setSinkToUse' command.
+data PCastSetSinkToUse = PCastSetSinkToUse
+  {
+    pCastSetSinkToUseSinkName :: T.Text
+  }
+  deriving (Eq, Show)
+pCastSetSinkToUse
+  :: T.Text
+  -> PCastSetSinkToUse
+pCastSetSinkToUse
+  arg_pCastSetSinkToUseSinkName
+  = PCastSetSinkToUse
+    arg_pCastSetSinkToUseSinkName
+instance ToJSON PCastSetSinkToUse where
+  toJSON p = A.object $ catMaybes [
+    ("sinkName" A..=) <$> Just (pCastSetSinkToUseSinkName p)
+    ]
+instance Command PCastSetSinkToUse where
+  type CommandResponse PCastSetSinkToUse = ()
+  commandName _ = "Cast.setSinkToUse"
+  fromJSON = const . A.Success . const ()
+
+-- | Starts mirroring the desktop to the sink.
+
+-- | Parameters of the 'Cast.startDesktopMirroring' command.
+data PCastStartDesktopMirroring = PCastStartDesktopMirroring
+  {
+    pCastStartDesktopMirroringSinkName :: T.Text
+  }
+  deriving (Eq, Show)
+pCastStartDesktopMirroring
+  :: T.Text
+  -> PCastStartDesktopMirroring
+pCastStartDesktopMirroring
+  arg_pCastStartDesktopMirroringSinkName
+  = PCastStartDesktopMirroring
+    arg_pCastStartDesktopMirroringSinkName
+instance ToJSON PCastStartDesktopMirroring where
+  toJSON p = A.object $ catMaybes [
+    ("sinkName" A..=) <$> Just (pCastStartDesktopMirroringSinkName p)
+    ]
+instance Command PCastStartDesktopMirroring where
+  type CommandResponse PCastStartDesktopMirroring = ()
+  commandName _ = "Cast.startDesktopMirroring"
+  fromJSON = const . A.Success . const ()
+
+-- | Starts mirroring the tab to the sink.
+
+-- | Parameters of the 'Cast.startTabMirroring' command.
+data PCastStartTabMirroring = PCastStartTabMirroring
+  {
+    pCastStartTabMirroringSinkName :: T.Text
+  }
+  deriving (Eq, Show)
+pCastStartTabMirroring
+  :: T.Text
+  -> PCastStartTabMirroring
+pCastStartTabMirroring
+  arg_pCastStartTabMirroringSinkName
+  = PCastStartTabMirroring
+    arg_pCastStartTabMirroringSinkName
+instance ToJSON PCastStartTabMirroring where
+  toJSON p = A.object $ catMaybes [
+    ("sinkName" A..=) <$> Just (pCastStartTabMirroringSinkName p)
+    ]
+instance Command PCastStartTabMirroring where
+  type CommandResponse PCastStartTabMirroring = ()
+  commandName _ = "Cast.startTabMirroring"
+  fromJSON = const . A.Success . const ()
+
+-- | Stops the active Cast session on the sink.
+
+-- | Parameters of the 'Cast.stopCasting' command.
+data PCastStopCasting = PCastStopCasting
+  {
+    pCastStopCastingSinkName :: T.Text
+  }
+  deriving (Eq, Show)
+pCastStopCasting
+  :: T.Text
+  -> PCastStopCasting
+pCastStopCasting
+  arg_pCastStopCastingSinkName
+  = PCastStopCasting
+    arg_pCastStopCastingSinkName
+instance ToJSON PCastStopCasting where
+  toJSON p = A.object $ catMaybes [
+    ("sinkName" A..=) <$> Just (pCastStopCastingSinkName p)
+    ]
+instance Command PCastStopCasting where
+  type CommandResponse PCastStopCasting = ()
+  commandName _ = "Cast.stopCasting"
+  fromJSON = const . A.Success . const ()
+
diff --git a/src/CDP/Domains/DOMDebugger.hs b/src/CDP/Domains/DOMDebugger.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains/DOMDebugger.hs
@@ -0,0 +1,460 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+
+
+{- |
+= DOMDebugger
+
+DOM debugging allows setting breakpoints on particular DOM operations and events. JavaScript
+execution will stop on these operations as if there was a regular breakpoint set.
+-}
+
+
+module CDP.Domains.DOMDebugger (module CDP.Domains.DOMDebugger) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+
+import CDP.Domains.DOMPageNetworkEmulationSecurity as DOMPageNetworkEmulationSecurity
+import CDP.Domains.Runtime as Runtime
+
+
+-- | Type 'DOMDebugger.DOMBreakpointType'.
+--   DOM breakpoint type.
+data DOMDebuggerDOMBreakpointType = DOMDebuggerDOMBreakpointTypeSubtreeModified | DOMDebuggerDOMBreakpointTypeAttributeModified | DOMDebuggerDOMBreakpointTypeNodeRemoved
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON DOMDebuggerDOMBreakpointType where
+  parseJSON = A.withText "DOMDebuggerDOMBreakpointType" $ \v -> case v of
+    "subtree-modified" -> pure DOMDebuggerDOMBreakpointTypeSubtreeModified
+    "attribute-modified" -> pure DOMDebuggerDOMBreakpointTypeAttributeModified
+    "node-removed" -> pure DOMDebuggerDOMBreakpointTypeNodeRemoved
+    "_" -> fail "failed to parse DOMDebuggerDOMBreakpointType"
+instance ToJSON DOMDebuggerDOMBreakpointType where
+  toJSON v = A.String $ case v of
+    DOMDebuggerDOMBreakpointTypeSubtreeModified -> "subtree-modified"
+    DOMDebuggerDOMBreakpointTypeAttributeModified -> "attribute-modified"
+    DOMDebuggerDOMBreakpointTypeNodeRemoved -> "node-removed"
+
+-- | Type 'DOMDebugger.CSPViolationType'.
+--   CSP Violation type.
+data DOMDebuggerCSPViolationType = DOMDebuggerCSPViolationTypeTrustedtypeSinkViolation | DOMDebuggerCSPViolationTypeTrustedtypePolicyViolation
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON DOMDebuggerCSPViolationType where
+  parseJSON = A.withText "DOMDebuggerCSPViolationType" $ \v -> case v of
+    "trustedtype-sink-violation" -> pure DOMDebuggerCSPViolationTypeTrustedtypeSinkViolation
+    "trustedtype-policy-violation" -> pure DOMDebuggerCSPViolationTypeTrustedtypePolicyViolation
+    "_" -> fail "failed to parse DOMDebuggerCSPViolationType"
+instance ToJSON DOMDebuggerCSPViolationType where
+  toJSON v = A.String $ case v of
+    DOMDebuggerCSPViolationTypeTrustedtypeSinkViolation -> "trustedtype-sink-violation"
+    DOMDebuggerCSPViolationTypeTrustedtypePolicyViolation -> "trustedtype-policy-violation"
+
+-- | Type 'DOMDebugger.EventListener'.
+--   Object event listener.
+data DOMDebuggerEventListener = DOMDebuggerEventListener
+  {
+    -- | `EventListener`'s type.
+    dOMDebuggerEventListenerType :: T.Text,
+    -- | `EventListener`'s useCapture.
+    dOMDebuggerEventListenerUseCapture :: Bool,
+    -- | `EventListener`'s passive flag.
+    dOMDebuggerEventListenerPassive :: Bool,
+    -- | `EventListener`'s once flag.
+    dOMDebuggerEventListenerOnce :: Bool,
+    -- | Script id of the handler code.
+    dOMDebuggerEventListenerScriptId :: Runtime.RuntimeScriptId,
+    -- | Line number in the script (0-based).
+    dOMDebuggerEventListenerLineNumber :: Int,
+    -- | Column number in the script (0-based).
+    dOMDebuggerEventListenerColumnNumber :: Int,
+    -- | Event handler function value.
+    dOMDebuggerEventListenerHandler :: Maybe Runtime.RuntimeRemoteObject,
+    -- | Event original handler function value.
+    dOMDebuggerEventListenerOriginalHandler :: Maybe Runtime.RuntimeRemoteObject,
+    -- | Node the listener is added to (if any).
+    dOMDebuggerEventListenerBackendNodeId :: Maybe DOMPageNetworkEmulationSecurity.DOMBackendNodeId
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMDebuggerEventListener where
+  parseJSON = A.withObject "DOMDebuggerEventListener" $ \o -> DOMDebuggerEventListener
+    <$> o A..: "type"
+    <*> o A..: "useCapture"
+    <*> o A..: "passive"
+    <*> o A..: "once"
+    <*> o A..: "scriptId"
+    <*> o A..: "lineNumber"
+    <*> o A..: "columnNumber"
+    <*> o A..:? "handler"
+    <*> o A..:? "originalHandler"
+    <*> o A..:? "backendNodeId"
+instance ToJSON DOMDebuggerEventListener where
+  toJSON p = A.object $ catMaybes [
+    ("type" A..=) <$> Just (dOMDebuggerEventListenerType p),
+    ("useCapture" A..=) <$> Just (dOMDebuggerEventListenerUseCapture p),
+    ("passive" A..=) <$> Just (dOMDebuggerEventListenerPassive p),
+    ("once" A..=) <$> Just (dOMDebuggerEventListenerOnce p),
+    ("scriptId" A..=) <$> Just (dOMDebuggerEventListenerScriptId p),
+    ("lineNumber" A..=) <$> Just (dOMDebuggerEventListenerLineNumber p),
+    ("columnNumber" A..=) <$> Just (dOMDebuggerEventListenerColumnNumber p),
+    ("handler" A..=) <$> (dOMDebuggerEventListenerHandler p),
+    ("originalHandler" A..=) <$> (dOMDebuggerEventListenerOriginalHandler p),
+    ("backendNodeId" A..=) <$> (dOMDebuggerEventListenerBackendNodeId p)
+    ]
+
+-- | Returns event listeners of the given object.
+
+-- | Parameters of the 'DOMDebugger.getEventListeners' command.
+data PDOMDebuggerGetEventListeners = PDOMDebuggerGetEventListeners
+  {
+    -- | Identifier of the object to return listeners for.
+    pDOMDebuggerGetEventListenersObjectId :: Runtime.RuntimeRemoteObjectId,
+    -- | The maximum depth at which Node children should be retrieved, defaults to 1. Use -1 for the
+    --   entire subtree or provide an integer larger than 0.
+    pDOMDebuggerGetEventListenersDepth :: Maybe Int,
+    -- | Whether or not iframes and shadow roots should be traversed when returning the subtree
+    --   (default is false). Reports listeners for all contexts if pierce is enabled.
+    pDOMDebuggerGetEventListenersPierce :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pDOMDebuggerGetEventListeners
+  {-
+  -- | Identifier of the object to return listeners for.
+  -}
+  :: Runtime.RuntimeRemoteObjectId
+  -> PDOMDebuggerGetEventListeners
+pDOMDebuggerGetEventListeners
+  arg_pDOMDebuggerGetEventListenersObjectId
+  = PDOMDebuggerGetEventListeners
+    arg_pDOMDebuggerGetEventListenersObjectId
+    Nothing
+    Nothing
+instance ToJSON PDOMDebuggerGetEventListeners where
+  toJSON p = A.object $ catMaybes [
+    ("objectId" A..=) <$> Just (pDOMDebuggerGetEventListenersObjectId p),
+    ("depth" A..=) <$> (pDOMDebuggerGetEventListenersDepth p),
+    ("pierce" A..=) <$> (pDOMDebuggerGetEventListenersPierce p)
+    ]
+data DOMDebuggerGetEventListeners = DOMDebuggerGetEventListeners
+  {
+    -- | Array of relevant listeners.
+    dOMDebuggerGetEventListenersListeners :: [DOMDebuggerEventListener]
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMDebuggerGetEventListeners where
+  parseJSON = A.withObject "DOMDebuggerGetEventListeners" $ \o -> DOMDebuggerGetEventListeners
+    <$> o A..: "listeners"
+instance Command PDOMDebuggerGetEventListeners where
+  type CommandResponse PDOMDebuggerGetEventListeners = DOMDebuggerGetEventListeners
+  commandName _ = "DOMDebugger.getEventListeners"
+
+-- | Removes DOM breakpoint that was set using `setDOMBreakpoint`.
+
+-- | Parameters of the 'DOMDebugger.removeDOMBreakpoint' command.
+data PDOMDebuggerRemoveDOMBreakpoint = PDOMDebuggerRemoveDOMBreakpoint
+  {
+    -- | Identifier of the node to remove breakpoint from.
+    pDOMDebuggerRemoveDOMBreakpointNodeId :: DOMPageNetworkEmulationSecurity.DOMNodeId,
+    -- | Type of the breakpoint to remove.
+    pDOMDebuggerRemoveDOMBreakpointType :: DOMDebuggerDOMBreakpointType
+  }
+  deriving (Eq, Show)
+pDOMDebuggerRemoveDOMBreakpoint
+  {-
+  -- | Identifier of the node to remove breakpoint from.
+  -}
+  :: DOMPageNetworkEmulationSecurity.DOMNodeId
+  {-
+  -- | Type of the breakpoint to remove.
+  -}
+  -> DOMDebuggerDOMBreakpointType
+  -> PDOMDebuggerRemoveDOMBreakpoint
+pDOMDebuggerRemoveDOMBreakpoint
+  arg_pDOMDebuggerRemoveDOMBreakpointNodeId
+  arg_pDOMDebuggerRemoveDOMBreakpointType
+  = PDOMDebuggerRemoveDOMBreakpoint
+    arg_pDOMDebuggerRemoveDOMBreakpointNodeId
+    arg_pDOMDebuggerRemoveDOMBreakpointType
+instance ToJSON PDOMDebuggerRemoveDOMBreakpoint where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> Just (pDOMDebuggerRemoveDOMBreakpointNodeId p),
+    ("type" A..=) <$> Just (pDOMDebuggerRemoveDOMBreakpointType p)
+    ]
+instance Command PDOMDebuggerRemoveDOMBreakpoint where
+  type CommandResponse PDOMDebuggerRemoveDOMBreakpoint = ()
+  commandName _ = "DOMDebugger.removeDOMBreakpoint"
+  fromJSON = const . A.Success . const ()
+
+-- | Removes breakpoint on particular DOM event.
+
+-- | Parameters of the 'DOMDebugger.removeEventListenerBreakpoint' command.
+data PDOMDebuggerRemoveEventListenerBreakpoint = PDOMDebuggerRemoveEventListenerBreakpoint
+  {
+    -- | Event name.
+    pDOMDebuggerRemoveEventListenerBreakpointEventName :: T.Text,
+    -- | EventTarget interface name.
+    pDOMDebuggerRemoveEventListenerBreakpointTargetName :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+pDOMDebuggerRemoveEventListenerBreakpoint
+  {-
+  -- | Event name.
+  -}
+  :: T.Text
+  -> PDOMDebuggerRemoveEventListenerBreakpoint
+pDOMDebuggerRemoveEventListenerBreakpoint
+  arg_pDOMDebuggerRemoveEventListenerBreakpointEventName
+  = PDOMDebuggerRemoveEventListenerBreakpoint
+    arg_pDOMDebuggerRemoveEventListenerBreakpointEventName
+    Nothing
+instance ToJSON PDOMDebuggerRemoveEventListenerBreakpoint where
+  toJSON p = A.object $ catMaybes [
+    ("eventName" A..=) <$> Just (pDOMDebuggerRemoveEventListenerBreakpointEventName p),
+    ("targetName" A..=) <$> (pDOMDebuggerRemoveEventListenerBreakpointTargetName p)
+    ]
+instance Command PDOMDebuggerRemoveEventListenerBreakpoint where
+  type CommandResponse PDOMDebuggerRemoveEventListenerBreakpoint = ()
+  commandName _ = "DOMDebugger.removeEventListenerBreakpoint"
+  fromJSON = const . A.Success . const ()
+
+-- | Removes breakpoint on particular native event.
+
+-- | Parameters of the 'DOMDebugger.removeInstrumentationBreakpoint' command.
+data PDOMDebuggerRemoveInstrumentationBreakpoint = PDOMDebuggerRemoveInstrumentationBreakpoint
+  {
+    -- | Instrumentation name to stop on.
+    pDOMDebuggerRemoveInstrumentationBreakpointEventName :: T.Text
+  }
+  deriving (Eq, Show)
+pDOMDebuggerRemoveInstrumentationBreakpoint
+  {-
+  -- | Instrumentation name to stop on.
+  -}
+  :: T.Text
+  -> PDOMDebuggerRemoveInstrumentationBreakpoint
+pDOMDebuggerRemoveInstrumentationBreakpoint
+  arg_pDOMDebuggerRemoveInstrumentationBreakpointEventName
+  = PDOMDebuggerRemoveInstrumentationBreakpoint
+    arg_pDOMDebuggerRemoveInstrumentationBreakpointEventName
+instance ToJSON PDOMDebuggerRemoveInstrumentationBreakpoint where
+  toJSON p = A.object $ catMaybes [
+    ("eventName" A..=) <$> Just (pDOMDebuggerRemoveInstrumentationBreakpointEventName p)
+    ]
+instance Command PDOMDebuggerRemoveInstrumentationBreakpoint where
+  type CommandResponse PDOMDebuggerRemoveInstrumentationBreakpoint = ()
+  commandName _ = "DOMDebugger.removeInstrumentationBreakpoint"
+  fromJSON = const . A.Success . const ()
+
+-- | Removes breakpoint from XMLHttpRequest.
+
+-- | Parameters of the 'DOMDebugger.removeXHRBreakpoint' command.
+data PDOMDebuggerRemoveXHRBreakpoint = PDOMDebuggerRemoveXHRBreakpoint
+  {
+    -- | Resource URL substring.
+    pDOMDebuggerRemoveXHRBreakpointUrl :: T.Text
+  }
+  deriving (Eq, Show)
+pDOMDebuggerRemoveXHRBreakpoint
+  {-
+  -- | Resource URL substring.
+  -}
+  :: T.Text
+  -> PDOMDebuggerRemoveXHRBreakpoint
+pDOMDebuggerRemoveXHRBreakpoint
+  arg_pDOMDebuggerRemoveXHRBreakpointUrl
+  = PDOMDebuggerRemoveXHRBreakpoint
+    arg_pDOMDebuggerRemoveXHRBreakpointUrl
+instance ToJSON PDOMDebuggerRemoveXHRBreakpoint where
+  toJSON p = A.object $ catMaybes [
+    ("url" A..=) <$> Just (pDOMDebuggerRemoveXHRBreakpointUrl p)
+    ]
+instance Command PDOMDebuggerRemoveXHRBreakpoint where
+  type CommandResponse PDOMDebuggerRemoveXHRBreakpoint = ()
+  commandName _ = "DOMDebugger.removeXHRBreakpoint"
+  fromJSON = const . A.Success . const ()
+
+-- | Sets breakpoint on particular CSP violations.
+
+-- | Parameters of the 'DOMDebugger.setBreakOnCSPViolation' command.
+data PDOMDebuggerSetBreakOnCSPViolation = PDOMDebuggerSetBreakOnCSPViolation
+  {
+    -- | CSP Violations to stop upon.
+    pDOMDebuggerSetBreakOnCSPViolationViolationTypes :: [DOMDebuggerCSPViolationType]
+  }
+  deriving (Eq, Show)
+pDOMDebuggerSetBreakOnCSPViolation
+  {-
+  -- | CSP Violations to stop upon.
+  -}
+  :: [DOMDebuggerCSPViolationType]
+  -> PDOMDebuggerSetBreakOnCSPViolation
+pDOMDebuggerSetBreakOnCSPViolation
+  arg_pDOMDebuggerSetBreakOnCSPViolationViolationTypes
+  = PDOMDebuggerSetBreakOnCSPViolation
+    arg_pDOMDebuggerSetBreakOnCSPViolationViolationTypes
+instance ToJSON PDOMDebuggerSetBreakOnCSPViolation where
+  toJSON p = A.object $ catMaybes [
+    ("violationTypes" A..=) <$> Just (pDOMDebuggerSetBreakOnCSPViolationViolationTypes p)
+    ]
+instance Command PDOMDebuggerSetBreakOnCSPViolation where
+  type CommandResponse PDOMDebuggerSetBreakOnCSPViolation = ()
+  commandName _ = "DOMDebugger.setBreakOnCSPViolation"
+  fromJSON = const . A.Success . const ()
+
+-- | Sets breakpoint on particular operation with DOM.
+
+-- | Parameters of the 'DOMDebugger.setDOMBreakpoint' command.
+data PDOMDebuggerSetDOMBreakpoint = PDOMDebuggerSetDOMBreakpoint
+  {
+    -- | Identifier of the node to set breakpoint on.
+    pDOMDebuggerSetDOMBreakpointNodeId :: DOMPageNetworkEmulationSecurity.DOMNodeId,
+    -- | Type of the operation to stop upon.
+    pDOMDebuggerSetDOMBreakpointType :: DOMDebuggerDOMBreakpointType
+  }
+  deriving (Eq, Show)
+pDOMDebuggerSetDOMBreakpoint
+  {-
+  -- | Identifier of the node to set breakpoint on.
+  -}
+  :: DOMPageNetworkEmulationSecurity.DOMNodeId
+  {-
+  -- | Type of the operation to stop upon.
+  -}
+  -> DOMDebuggerDOMBreakpointType
+  -> PDOMDebuggerSetDOMBreakpoint
+pDOMDebuggerSetDOMBreakpoint
+  arg_pDOMDebuggerSetDOMBreakpointNodeId
+  arg_pDOMDebuggerSetDOMBreakpointType
+  = PDOMDebuggerSetDOMBreakpoint
+    arg_pDOMDebuggerSetDOMBreakpointNodeId
+    arg_pDOMDebuggerSetDOMBreakpointType
+instance ToJSON PDOMDebuggerSetDOMBreakpoint where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> Just (pDOMDebuggerSetDOMBreakpointNodeId p),
+    ("type" A..=) <$> Just (pDOMDebuggerSetDOMBreakpointType p)
+    ]
+instance Command PDOMDebuggerSetDOMBreakpoint where
+  type CommandResponse PDOMDebuggerSetDOMBreakpoint = ()
+  commandName _ = "DOMDebugger.setDOMBreakpoint"
+  fromJSON = const . A.Success . const ()
+
+-- | Sets breakpoint on particular DOM event.
+
+-- | Parameters of the 'DOMDebugger.setEventListenerBreakpoint' command.
+data PDOMDebuggerSetEventListenerBreakpoint = PDOMDebuggerSetEventListenerBreakpoint
+  {
+    -- | DOM Event name to stop on (any DOM event will do).
+    pDOMDebuggerSetEventListenerBreakpointEventName :: T.Text,
+    -- | EventTarget interface name to stop on. If equal to `"*"` or not provided, will stop on any
+    --   EventTarget.
+    pDOMDebuggerSetEventListenerBreakpointTargetName :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+pDOMDebuggerSetEventListenerBreakpoint
+  {-
+  -- | DOM Event name to stop on (any DOM event will do).
+  -}
+  :: T.Text
+  -> PDOMDebuggerSetEventListenerBreakpoint
+pDOMDebuggerSetEventListenerBreakpoint
+  arg_pDOMDebuggerSetEventListenerBreakpointEventName
+  = PDOMDebuggerSetEventListenerBreakpoint
+    arg_pDOMDebuggerSetEventListenerBreakpointEventName
+    Nothing
+instance ToJSON PDOMDebuggerSetEventListenerBreakpoint where
+  toJSON p = A.object $ catMaybes [
+    ("eventName" A..=) <$> Just (pDOMDebuggerSetEventListenerBreakpointEventName p),
+    ("targetName" A..=) <$> (pDOMDebuggerSetEventListenerBreakpointTargetName p)
+    ]
+instance Command PDOMDebuggerSetEventListenerBreakpoint where
+  type CommandResponse PDOMDebuggerSetEventListenerBreakpoint = ()
+  commandName _ = "DOMDebugger.setEventListenerBreakpoint"
+  fromJSON = const . A.Success . const ()
+
+-- | Sets breakpoint on particular native event.
+
+-- | Parameters of the 'DOMDebugger.setInstrumentationBreakpoint' command.
+data PDOMDebuggerSetInstrumentationBreakpoint = PDOMDebuggerSetInstrumentationBreakpoint
+  {
+    -- | Instrumentation name to stop on.
+    pDOMDebuggerSetInstrumentationBreakpointEventName :: T.Text
+  }
+  deriving (Eq, Show)
+pDOMDebuggerSetInstrumentationBreakpoint
+  {-
+  -- | Instrumentation name to stop on.
+  -}
+  :: T.Text
+  -> PDOMDebuggerSetInstrumentationBreakpoint
+pDOMDebuggerSetInstrumentationBreakpoint
+  arg_pDOMDebuggerSetInstrumentationBreakpointEventName
+  = PDOMDebuggerSetInstrumentationBreakpoint
+    arg_pDOMDebuggerSetInstrumentationBreakpointEventName
+instance ToJSON PDOMDebuggerSetInstrumentationBreakpoint where
+  toJSON p = A.object $ catMaybes [
+    ("eventName" A..=) <$> Just (pDOMDebuggerSetInstrumentationBreakpointEventName p)
+    ]
+instance Command PDOMDebuggerSetInstrumentationBreakpoint where
+  type CommandResponse PDOMDebuggerSetInstrumentationBreakpoint = ()
+  commandName _ = "DOMDebugger.setInstrumentationBreakpoint"
+  fromJSON = const . A.Success . const ()
+
+-- | Sets breakpoint on XMLHttpRequest.
+
+-- | Parameters of the 'DOMDebugger.setXHRBreakpoint' command.
+data PDOMDebuggerSetXHRBreakpoint = PDOMDebuggerSetXHRBreakpoint
+  {
+    -- | Resource URL substring. All XHRs having this substring in the URL will get stopped upon.
+    pDOMDebuggerSetXHRBreakpointUrl :: T.Text
+  }
+  deriving (Eq, Show)
+pDOMDebuggerSetXHRBreakpoint
+  {-
+  -- | Resource URL substring. All XHRs having this substring in the URL will get stopped upon.
+  -}
+  :: T.Text
+  -> PDOMDebuggerSetXHRBreakpoint
+pDOMDebuggerSetXHRBreakpoint
+  arg_pDOMDebuggerSetXHRBreakpointUrl
+  = PDOMDebuggerSetXHRBreakpoint
+    arg_pDOMDebuggerSetXHRBreakpointUrl
+instance ToJSON PDOMDebuggerSetXHRBreakpoint where
+  toJSON p = A.object $ catMaybes [
+    ("url" A..=) <$> Just (pDOMDebuggerSetXHRBreakpointUrl p)
+    ]
+instance Command PDOMDebuggerSetXHRBreakpoint where
+  type CommandResponse PDOMDebuggerSetXHRBreakpoint = ()
+  commandName _ = "DOMDebugger.setXHRBreakpoint"
+  fromJSON = const . A.Success . const ()
+
diff --git a/src/CDP/Domains/DOMPageNetworkEmulationSecurity.hs b/src/CDP/Domains/DOMPageNetworkEmulationSecurity.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains/DOMPageNetworkEmulationSecurity.hs
@@ -0,0 +1,10707 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+
+
+{- |
+= DOM
+
+This domain exposes DOM read/write operations. Each DOM Node is represented with its mirror object
+that has an `id`. This `id` can be used to get additional information on the Node, resolve it into
+the JavaScript object wrapper, etc. It is important that client receives DOM events only for the
+nodes that are known to the client. Backend keeps track of the nodes that were sent to the client
+and never sends the same node twice. It is client's responsibility to collect information about
+the nodes that were sent to the client.<p>Note that `iframe` owner elements will return
+corresponding document elements as their child nodes.</p>
+= Emulation
+
+This domain emulates different environments for the page.
+= Network
+
+Network domain allows tracking network activities of the page. It exposes information about http,
+file, data and other requests and responses, their headers, bodies, timing, etc.
+= Page
+
+Actions and events related to the inspected page belong to the page domain.
+= Security
+
+Security
+-}
+
+
+module CDP.Domains.DOMPageNetworkEmulationSecurity (module CDP.Domains.DOMPageNetworkEmulationSecurity) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+
+import CDP.Domains.Debugger as Debugger
+import CDP.Domains.IO as IO
+import CDP.Domains.Runtime as Runtime
+
+
+-- | Type 'DOM.NodeId'.
+--   Unique DOM node identifier.
+type DOMNodeId = Int
+
+-- | Type 'DOM.BackendNodeId'.
+--   Unique DOM node identifier used to reference a node that may not have been pushed to the
+--   front-end.
+type DOMBackendNodeId = Int
+
+-- | Type 'DOM.BackendNode'.
+--   Backend node with a friendly name.
+data DOMBackendNode = DOMBackendNode
+  {
+    -- | `Node`'s nodeType.
+    dOMBackendNodeNodeType :: Int,
+    -- | `Node`'s nodeName.
+    dOMBackendNodeNodeName :: T.Text,
+    dOMBackendNodeBackendNodeId :: DOMBackendNodeId
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMBackendNode where
+  parseJSON = A.withObject "DOMBackendNode" $ \o -> DOMBackendNode
+    <$> o A..: "nodeType"
+    <*> o A..: "nodeName"
+    <*> o A..: "backendNodeId"
+instance ToJSON DOMBackendNode where
+  toJSON p = A.object $ catMaybes [
+    ("nodeType" A..=) <$> Just (dOMBackendNodeNodeType p),
+    ("nodeName" A..=) <$> Just (dOMBackendNodeNodeName p),
+    ("backendNodeId" A..=) <$> Just (dOMBackendNodeBackendNodeId p)
+    ]
+
+-- | Type 'DOM.PseudoType'.
+--   Pseudo element type.
+data DOMPseudoType = DOMPseudoTypeFirstLine | DOMPseudoTypeFirstLetter | DOMPseudoTypeBefore | DOMPseudoTypeAfter | DOMPseudoTypeMarker | DOMPseudoTypeBackdrop | DOMPseudoTypeSelection | DOMPseudoTypeTargetText | DOMPseudoTypeSpellingError | DOMPseudoTypeGrammarError | DOMPseudoTypeHighlight | DOMPseudoTypeFirstLineInherited | DOMPseudoTypeScrollbar | DOMPseudoTypeScrollbarThumb | DOMPseudoTypeScrollbarButton | DOMPseudoTypeScrollbarTrack | DOMPseudoTypeScrollbarTrackPiece | DOMPseudoTypeScrollbarCorner | DOMPseudoTypeResizer | DOMPseudoTypeInputListButton | DOMPseudoTypePageTransition | DOMPseudoTypePageTransitionContainer | DOMPseudoTypePageTransitionImageWrapper | DOMPseudoTypePageTransitionOutgoingImage | DOMPseudoTypePageTransitionIncomingImage
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON DOMPseudoType where
+  parseJSON = A.withText "DOMPseudoType" $ \v -> case v of
+    "first-line" -> pure DOMPseudoTypeFirstLine
+    "first-letter" -> pure DOMPseudoTypeFirstLetter
+    "before" -> pure DOMPseudoTypeBefore
+    "after" -> pure DOMPseudoTypeAfter
+    "marker" -> pure DOMPseudoTypeMarker
+    "backdrop" -> pure DOMPseudoTypeBackdrop
+    "selection" -> pure DOMPseudoTypeSelection
+    "target-text" -> pure DOMPseudoTypeTargetText
+    "spelling-error" -> pure DOMPseudoTypeSpellingError
+    "grammar-error" -> pure DOMPseudoTypeGrammarError
+    "highlight" -> pure DOMPseudoTypeHighlight
+    "first-line-inherited" -> pure DOMPseudoTypeFirstLineInherited
+    "scrollbar" -> pure DOMPseudoTypeScrollbar
+    "scrollbar-thumb" -> pure DOMPseudoTypeScrollbarThumb
+    "scrollbar-button" -> pure DOMPseudoTypeScrollbarButton
+    "scrollbar-track" -> pure DOMPseudoTypeScrollbarTrack
+    "scrollbar-track-piece" -> pure DOMPseudoTypeScrollbarTrackPiece
+    "scrollbar-corner" -> pure DOMPseudoTypeScrollbarCorner
+    "resizer" -> pure DOMPseudoTypeResizer
+    "input-list-button" -> pure DOMPseudoTypeInputListButton
+    "page-transition" -> pure DOMPseudoTypePageTransition
+    "page-transition-container" -> pure DOMPseudoTypePageTransitionContainer
+    "page-transition-image-wrapper" -> pure DOMPseudoTypePageTransitionImageWrapper
+    "page-transition-outgoing-image" -> pure DOMPseudoTypePageTransitionOutgoingImage
+    "page-transition-incoming-image" -> pure DOMPseudoTypePageTransitionIncomingImage
+    "_" -> fail "failed to parse DOMPseudoType"
+instance ToJSON DOMPseudoType where
+  toJSON v = A.String $ case v of
+    DOMPseudoTypeFirstLine -> "first-line"
+    DOMPseudoTypeFirstLetter -> "first-letter"
+    DOMPseudoTypeBefore -> "before"
+    DOMPseudoTypeAfter -> "after"
+    DOMPseudoTypeMarker -> "marker"
+    DOMPseudoTypeBackdrop -> "backdrop"
+    DOMPseudoTypeSelection -> "selection"
+    DOMPseudoTypeTargetText -> "target-text"
+    DOMPseudoTypeSpellingError -> "spelling-error"
+    DOMPseudoTypeGrammarError -> "grammar-error"
+    DOMPseudoTypeHighlight -> "highlight"
+    DOMPseudoTypeFirstLineInherited -> "first-line-inherited"
+    DOMPseudoTypeScrollbar -> "scrollbar"
+    DOMPseudoTypeScrollbarThumb -> "scrollbar-thumb"
+    DOMPseudoTypeScrollbarButton -> "scrollbar-button"
+    DOMPseudoTypeScrollbarTrack -> "scrollbar-track"
+    DOMPseudoTypeScrollbarTrackPiece -> "scrollbar-track-piece"
+    DOMPseudoTypeScrollbarCorner -> "scrollbar-corner"
+    DOMPseudoTypeResizer -> "resizer"
+    DOMPseudoTypeInputListButton -> "input-list-button"
+    DOMPseudoTypePageTransition -> "page-transition"
+    DOMPseudoTypePageTransitionContainer -> "page-transition-container"
+    DOMPseudoTypePageTransitionImageWrapper -> "page-transition-image-wrapper"
+    DOMPseudoTypePageTransitionOutgoingImage -> "page-transition-outgoing-image"
+    DOMPseudoTypePageTransitionIncomingImage -> "page-transition-incoming-image"
+
+-- | Type 'DOM.ShadowRootType'.
+--   Shadow root type.
+data DOMShadowRootType = DOMShadowRootTypeUserAgent | DOMShadowRootTypeOpen | DOMShadowRootTypeClosed
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON DOMShadowRootType where
+  parseJSON = A.withText "DOMShadowRootType" $ \v -> case v of
+    "user-agent" -> pure DOMShadowRootTypeUserAgent
+    "open" -> pure DOMShadowRootTypeOpen
+    "closed" -> pure DOMShadowRootTypeClosed
+    "_" -> fail "failed to parse DOMShadowRootType"
+instance ToJSON DOMShadowRootType where
+  toJSON v = A.String $ case v of
+    DOMShadowRootTypeUserAgent -> "user-agent"
+    DOMShadowRootTypeOpen -> "open"
+    DOMShadowRootTypeClosed -> "closed"
+
+-- | Type 'DOM.CompatibilityMode'.
+--   Document compatibility mode.
+data DOMCompatibilityMode = DOMCompatibilityModeQuirksMode | DOMCompatibilityModeLimitedQuirksMode | DOMCompatibilityModeNoQuirksMode
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON DOMCompatibilityMode where
+  parseJSON = A.withText "DOMCompatibilityMode" $ \v -> case v of
+    "QuirksMode" -> pure DOMCompatibilityModeQuirksMode
+    "LimitedQuirksMode" -> pure DOMCompatibilityModeLimitedQuirksMode
+    "NoQuirksMode" -> pure DOMCompatibilityModeNoQuirksMode
+    "_" -> fail "failed to parse DOMCompatibilityMode"
+instance ToJSON DOMCompatibilityMode where
+  toJSON v = A.String $ case v of
+    DOMCompatibilityModeQuirksMode -> "QuirksMode"
+    DOMCompatibilityModeLimitedQuirksMode -> "LimitedQuirksMode"
+    DOMCompatibilityModeNoQuirksMode -> "NoQuirksMode"
+
+-- | Type 'DOM.Node'.
+--   DOM interaction is implemented in terms of mirror objects that represent the actual DOM nodes.
+--   DOMNode is a base node mirror type.
+data DOMNode = DOMNode
+  {
+    -- | Node identifier that is passed into the rest of the DOM messages as the `nodeId`. Backend
+    --   will only push node with given `id` once. It is aware of all requested nodes and will only
+    --   fire DOM events for nodes known to the client.
+    dOMNodeNodeId :: DOMNodeId,
+    -- | The id of the parent node if any.
+    dOMNodeParentId :: Maybe DOMNodeId,
+    -- | The BackendNodeId for this node.
+    dOMNodeBackendNodeId :: DOMBackendNodeId,
+    -- | `Node`'s nodeType.
+    dOMNodeNodeType :: Int,
+    -- | `Node`'s nodeName.
+    dOMNodeNodeName :: T.Text,
+    -- | `Node`'s localName.
+    dOMNodeLocalName :: T.Text,
+    -- | `Node`'s nodeValue.
+    dOMNodeNodeValue :: T.Text,
+    -- | Child count for `Container` nodes.
+    dOMNodeChildNodeCount :: Maybe Int,
+    -- | Child nodes of this node when requested with children.
+    dOMNodeChildren :: Maybe [DOMNode],
+    -- | Attributes of the `Element` node in the form of flat array `[name1, value1, name2, value2]`.
+    dOMNodeAttributes :: Maybe [T.Text],
+    -- | Document URL that `Document` or `FrameOwner` node points to.
+    dOMNodeDocumentURL :: Maybe T.Text,
+    -- | Base URL that `Document` or `FrameOwner` node uses for URL completion.
+    dOMNodeBaseURL :: Maybe T.Text,
+    -- | `DocumentType`'s publicId.
+    dOMNodePublicId :: Maybe T.Text,
+    -- | `DocumentType`'s systemId.
+    dOMNodeSystemId :: Maybe T.Text,
+    -- | `DocumentType`'s internalSubset.
+    dOMNodeInternalSubset :: Maybe T.Text,
+    -- | `Document`'s XML version in case of XML documents.
+    dOMNodeXmlVersion :: Maybe T.Text,
+    -- | `Attr`'s name.
+    dOMNodeName :: Maybe T.Text,
+    -- | `Attr`'s value.
+    dOMNodeValue :: Maybe T.Text,
+    -- | Pseudo element type for this node.
+    dOMNodePseudoType :: Maybe DOMPseudoType,
+    -- | Pseudo element identifier for this node. Only present if there is a
+    --   valid pseudoType.
+    dOMNodePseudoIdentifier :: Maybe T.Text,
+    -- | Shadow root type.
+    dOMNodeShadowRootType :: Maybe DOMShadowRootType,
+    -- | Frame ID for frame owner elements.
+    dOMNodeFrameId :: Maybe PageFrameId,
+    -- | Content document for frame owner elements.
+    dOMNodeContentDocument :: Maybe DOMNode,
+    -- | Shadow root list for given element host.
+    dOMNodeShadowRoots :: Maybe [DOMNode],
+    -- | Content document fragment for template elements.
+    dOMNodeTemplateContent :: Maybe DOMNode,
+    -- | Pseudo elements associated with this node.
+    dOMNodePseudoElements :: Maybe [DOMNode],
+    -- | Distributed nodes for given insertion point.
+    dOMNodeDistributedNodes :: Maybe [DOMBackendNode],
+    -- | Whether the node is SVG.
+    dOMNodeIsSVG :: Maybe Bool,
+    dOMNodeCompatibilityMode :: Maybe DOMCompatibilityMode,
+    dOMNodeAssignedSlot :: Maybe DOMBackendNode
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMNode where
+  parseJSON = A.withObject "DOMNode" $ \o -> DOMNode
+    <$> o A..: "nodeId"
+    <*> o A..:? "parentId"
+    <*> o A..: "backendNodeId"
+    <*> o A..: "nodeType"
+    <*> o A..: "nodeName"
+    <*> o A..: "localName"
+    <*> o A..: "nodeValue"
+    <*> o A..:? "childNodeCount"
+    <*> o A..:? "children"
+    <*> o A..:? "attributes"
+    <*> o A..:? "documentURL"
+    <*> o A..:? "baseURL"
+    <*> o A..:? "publicId"
+    <*> o A..:? "systemId"
+    <*> o A..:? "internalSubset"
+    <*> o A..:? "xmlVersion"
+    <*> o A..:? "name"
+    <*> o A..:? "value"
+    <*> o A..:? "pseudoType"
+    <*> o A..:? "pseudoIdentifier"
+    <*> o A..:? "shadowRootType"
+    <*> o A..:? "frameId"
+    <*> o A..:? "contentDocument"
+    <*> o A..:? "shadowRoots"
+    <*> o A..:? "templateContent"
+    <*> o A..:? "pseudoElements"
+    <*> o A..:? "distributedNodes"
+    <*> o A..:? "isSVG"
+    <*> o A..:? "compatibilityMode"
+    <*> o A..:? "assignedSlot"
+instance ToJSON DOMNode where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> Just (dOMNodeNodeId p),
+    ("parentId" A..=) <$> (dOMNodeParentId p),
+    ("backendNodeId" A..=) <$> Just (dOMNodeBackendNodeId p),
+    ("nodeType" A..=) <$> Just (dOMNodeNodeType p),
+    ("nodeName" A..=) <$> Just (dOMNodeNodeName p),
+    ("localName" A..=) <$> Just (dOMNodeLocalName p),
+    ("nodeValue" A..=) <$> Just (dOMNodeNodeValue p),
+    ("childNodeCount" A..=) <$> (dOMNodeChildNodeCount p),
+    ("children" A..=) <$> (dOMNodeChildren p),
+    ("attributes" A..=) <$> (dOMNodeAttributes p),
+    ("documentURL" A..=) <$> (dOMNodeDocumentURL p),
+    ("baseURL" A..=) <$> (dOMNodeBaseURL p),
+    ("publicId" A..=) <$> (dOMNodePublicId p),
+    ("systemId" A..=) <$> (dOMNodeSystemId p),
+    ("internalSubset" A..=) <$> (dOMNodeInternalSubset p),
+    ("xmlVersion" A..=) <$> (dOMNodeXmlVersion p),
+    ("name" A..=) <$> (dOMNodeName p),
+    ("value" A..=) <$> (dOMNodeValue p),
+    ("pseudoType" A..=) <$> (dOMNodePseudoType p),
+    ("pseudoIdentifier" A..=) <$> (dOMNodePseudoIdentifier p),
+    ("shadowRootType" A..=) <$> (dOMNodeShadowRootType p),
+    ("frameId" A..=) <$> (dOMNodeFrameId p),
+    ("contentDocument" A..=) <$> (dOMNodeContentDocument p),
+    ("shadowRoots" A..=) <$> (dOMNodeShadowRoots p),
+    ("templateContent" A..=) <$> (dOMNodeTemplateContent p),
+    ("pseudoElements" A..=) <$> (dOMNodePseudoElements p),
+    ("distributedNodes" A..=) <$> (dOMNodeDistributedNodes p),
+    ("isSVG" A..=) <$> (dOMNodeIsSVG p),
+    ("compatibilityMode" A..=) <$> (dOMNodeCompatibilityMode p),
+    ("assignedSlot" A..=) <$> (dOMNodeAssignedSlot p)
+    ]
+
+-- | Type 'DOM.RGBA'.
+--   A structure holding an RGBA color.
+data DOMRGBA = DOMRGBA
+  {
+    -- | The red component, in the [0-255] range.
+    dOMRGBAR :: Int,
+    -- | The green component, in the [0-255] range.
+    dOMRGBAG :: Int,
+    -- | The blue component, in the [0-255] range.
+    dOMRGBAB :: Int,
+    -- | The alpha component, in the [0-1] range (default: 1).
+    dOMRGBAA :: Maybe Double
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMRGBA where
+  parseJSON = A.withObject "DOMRGBA" $ \o -> DOMRGBA
+    <$> o A..: "r"
+    <*> o A..: "g"
+    <*> o A..: "b"
+    <*> o A..:? "a"
+instance ToJSON DOMRGBA where
+  toJSON p = A.object $ catMaybes [
+    ("r" A..=) <$> Just (dOMRGBAR p),
+    ("g" A..=) <$> Just (dOMRGBAG p),
+    ("b" A..=) <$> Just (dOMRGBAB p),
+    ("a" A..=) <$> (dOMRGBAA p)
+    ]
+
+-- | Type 'DOM.Quad'.
+--   An array of quad vertices, x immediately followed by y for each point, points clock-wise.
+type DOMQuad = [Double]
+
+-- | Type 'DOM.BoxModel'.
+--   Box model.
+data DOMBoxModel = DOMBoxModel
+  {
+    -- | Content box
+    dOMBoxModelContent :: DOMQuad,
+    -- | Padding box
+    dOMBoxModelPadding :: DOMQuad,
+    -- | Border box
+    dOMBoxModelBorder :: DOMQuad,
+    -- | Margin box
+    dOMBoxModelMargin :: DOMQuad,
+    -- | Node width
+    dOMBoxModelWidth :: Int,
+    -- | Node height
+    dOMBoxModelHeight :: Int,
+    -- | Shape outside coordinates
+    dOMBoxModelShapeOutside :: Maybe DOMShapeOutsideInfo
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMBoxModel where
+  parseJSON = A.withObject "DOMBoxModel" $ \o -> DOMBoxModel
+    <$> o A..: "content"
+    <*> o A..: "padding"
+    <*> o A..: "border"
+    <*> o A..: "margin"
+    <*> o A..: "width"
+    <*> o A..: "height"
+    <*> o A..:? "shapeOutside"
+instance ToJSON DOMBoxModel where
+  toJSON p = A.object $ catMaybes [
+    ("content" A..=) <$> Just (dOMBoxModelContent p),
+    ("padding" A..=) <$> Just (dOMBoxModelPadding p),
+    ("border" A..=) <$> Just (dOMBoxModelBorder p),
+    ("margin" A..=) <$> Just (dOMBoxModelMargin p),
+    ("width" A..=) <$> Just (dOMBoxModelWidth p),
+    ("height" A..=) <$> Just (dOMBoxModelHeight p),
+    ("shapeOutside" A..=) <$> (dOMBoxModelShapeOutside p)
+    ]
+
+-- | Type 'DOM.ShapeOutsideInfo'.
+--   CSS Shape Outside details.
+data DOMShapeOutsideInfo = DOMShapeOutsideInfo
+  {
+    -- | Shape bounds
+    dOMShapeOutsideInfoBounds :: DOMQuad,
+    -- | Shape coordinate details
+    dOMShapeOutsideInfoShape :: [A.Value],
+    -- | Margin shape bounds
+    dOMShapeOutsideInfoMarginShape :: [A.Value]
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMShapeOutsideInfo where
+  parseJSON = A.withObject "DOMShapeOutsideInfo" $ \o -> DOMShapeOutsideInfo
+    <$> o A..: "bounds"
+    <*> o A..: "shape"
+    <*> o A..: "marginShape"
+instance ToJSON DOMShapeOutsideInfo where
+  toJSON p = A.object $ catMaybes [
+    ("bounds" A..=) <$> Just (dOMShapeOutsideInfoBounds p),
+    ("shape" A..=) <$> Just (dOMShapeOutsideInfoShape p),
+    ("marginShape" A..=) <$> Just (dOMShapeOutsideInfoMarginShape p)
+    ]
+
+-- | Type 'DOM.Rect'.
+--   Rectangle.
+data DOMRect = DOMRect
+  {
+    -- | X coordinate
+    dOMRectX :: Double,
+    -- | Y coordinate
+    dOMRectY :: Double,
+    -- | Rectangle width
+    dOMRectWidth :: Double,
+    -- | Rectangle height
+    dOMRectHeight :: Double
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMRect where
+  parseJSON = A.withObject "DOMRect" $ \o -> DOMRect
+    <$> o A..: "x"
+    <*> o A..: "y"
+    <*> o A..: "width"
+    <*> o A..: "height"
+instance ToJSON DOMRect where
+  toJSON p = A.object $ catMaybes [
+    ("x" A..=) <$> Just (dOMRectX p),
+    ("y" A..=) <$> Just (dOMRectY p),
+    ("width" A..=) <$> Just (dOMRectWidth p),
+    ("height" A..=) <$> Just (dOMRectHeight p)
+    ]
+
+-- | Type 'DOM.CSSComputedStyleProperty'.
+data DOMCSSComputedStyleProperty = DOMCSSComputedStyleProperty
+  {
+    -- | Computed style property name.
+    dOMCSSComputedStylePropertyName :: T.Text,
+    -- | Computed style property value.
+    dOMCSSComputedStylePropertyValue :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMCSSComputedStyleProperty where
+  parseJSON = A.withObject "DOMCSSComputedStyleProperty" $ \o -> DOMCSSComputedStyleProperty
+    <$> o A..: "name"
+    <*> o A..: "value"
+instance ToJSON DOMCSSComputedStyleProperty where
+  toJSON p = A.object $ catMaybes [
+    ("name" A..=) <$> Just (dOMCSSComputedStylePropertyName p),
+    ("value" A..=) <$> Just (dOMCSSComputedStylePropertyValue p)
+    ]
+
+-- | Type of the 'DOM.attributeModified' event.
+data DOMAttributeModified = DOMAttributeModified
+  {
+    -- | Id of the node that has changed.
+    dOMAttributeModifiedNodeId :: DOMNodeId,
+    -- | Attribute name.
+    dOMAttributeModifiedName :: T.Text,
+    -- | Attribute value.
+    dOMAttributeModifiedValue :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMAttributeModified where
+  parseJSON = A.withObject "DOMAttributeModified" $ \o -> DOMAttributeModified
+    <$> o A..: "nodeId"
+    <*> o A..: "name"
+    <*> o A..: "value"
+instance Event DOMAttributeModified where
+  eventName _ = "DOM.attributeModified"
+
+-- | Type of the 'DOM.attributeRemoved' event.
+data DOMAttributeRemoved = DOMAttributeRemoved
+  {
+    -- | Id of the node that has changed.
+    dOMAttributeRemovedNodeId :: DOMNodeId,
+    -- | A ttribute name.
+    dOMAttributeRemovedName :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMAttributeRemoved where
+  parseJSON = A.withObject "DOMAttributeRemoved" $ \o -> DOMAttributeRemoved
+    <$> o A..: "nodeId"
+    <*> o A..: "name"
+instance Event DOMAttributeRemoved where
+  eventName _ = "DOM.attributeRemoved"
+
+-- | Type of the 'DOM.characterDataModified' event.
+data DOMCharacterDataModified = DOMCharacterDataModified
+  {
+    -- | Id of the node that has changed.
+    dOMCharacterDataModifiedNodeId :: DOMNodeId,
+    -- | New text value.
+    dOMCharacterDataModifiedCharacterData :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMCharacterDataModified where
+  parseJSON = A.withObject "DOMCharacterDataModified" $ \o -> DOMCharacterDataModified
+    <$> o A..: "nodeId"
+    <*> o A..: "characterData"
+instance Event DOMCharacterDataModified where
+  eventName _ = "DOM.characterDataModified"
+
+-- | Type of the 'DOM.childNodeCountUpdated' event.
+data DOMChildNodeCountUpdated = DOMChildNodeCountUpdated
+  {
+    -- | Id of the node that has changed.
+    dOMChildNodeCountUpdatedNodeId :: DOMNodeId,
+    -- | New node count.
+    dOMChildNodeCountUpdatedChildNodeCount :: Int
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMChildNodeCountUpdated where
+  parseJSON = A.withObject "DOMChildNodeCountUpdated" $ \o -> DOMChildNodeCountUpdated
+    <$> o A..: "nodeId"
+    <*> o A..: "childNodeCount"
+instance Event DOMChildNodeCountUpdated where
+  eventName _ = "DOM.childNodeCountUpdated"
+
+-- | Type of the 'DOM.childNodeInserted' event.
+data DOMChildNodeInserted = DOMChildNodeInserted
+  {
+    -- | Id of the node that has changed.
+    dOMChildNodeInsertedParentNodeId :: DOMNodeId,
+    -- | Id of the previous sibling.
+    dOMChildNodeInsertedPreviousNodeId :: DOMNodeId,
+    -- | Inserted node data.
+    dOMChildNodeInsertedNode :: DOMNode
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMChildNodeInserted where
+  parseJSON = A.withObject "DOMChildNodeInserted" $ \o -> DOMChildNodeInserted
+    <$> o A..: "parentNodeId"
+    <*> o A..: "previousNodeId"
+    <*> o A..: "node"
+instance Event DOMChildNodeInserted where
+  eventName _ = "DOM.childNodeInserted"
+
+-- | Type of the 'DOM.childNodeRemoved' event.
+data DOMChildNodeRemoved = DOMChildNodeRemoved
+  {
+    -- | Parent id.
+    dOMChildNodeRemovedParentNodeId :: DOMNodeId,
+    -- | Id of the node that has been removed.
+    dOMChildNodeRemovedNodeId :: DOMNodeId
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMChildNodeRemoved where
+  parseJSON = A.withObject "DOMChildNodeRemoved" $ \o -> DOMChildNodeRemoved
+    <$> o A..: "parentNodeId"
+    <*> o A..: "nodeId"
+instance Event DOMChildNodeRemoved where
+  eventName _ = "DOM.childNodeRemoved"
+
+-- | Type of the 'DOM.distributedNodesUpdated' event.
+data DOMDistributedNodesUpdated = DOMDistributedNodesUpdated
+  {
+    -- | Insertion point where distributed nodes were updated.
+    dOMDistributedNodesUpdatedInsertionPointId :: DOMNodeId,
+    -- | Distributed nodes for given insertion point.
+    dOMDistributedNodesUpdatedDistributedNodes :: [DOMBackendNode]
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMDistributedNodesUpdated where
+  parseJSON = A.withObject "DOMDistributedNodesUpdated" $ \o -> DOMDistributedNodesUpdated
+    <$> o A..: "insertionPointId"
+    <*> o A..: "distributedNodes"
+instance Event DOMDistributedNodesUpdated where
+  eventName _ = "DOM.distributedNodesUpdated"
+
+-- | Type of the 'DOM.documentUpdated' event.
+data DOMDocumentUpdated = DOMDocumentUpdated
+  deriving (Eq, Show, Read)
+instance FromJSON DOMDocumentUpdated where
+  parseJSON _ = pure DOMDocumentUpdated
+instance Event DOMDocumentUpdated where
+  eventName _ = "DOM.documentUpdated"
+
+-- | Type of the 'DOM.inlineStyleInvalidated' event.
+data DOMInlineStyleInvalidated = DOMInlineStyleInvalidated
+  {
+    -- | Ids of the nodes for which the inline styles have been invalidated.
+    dOMInlineStyleInvalidatedNodeIds :: [DOMNodeId]
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMInlineStyleInvalidated where
+  parseJSON = A.withObject "DOMInlineStyleInvalidated" $ \o -> DOMInlineStyleInvalidated
+    <$> o A..: "nodeIds"
+instance Event DOMInlineStyleInvalidated where
+  eventName _ = "DOM.inlineStyleInvalidated"
+
+-- | Type of the 'DOM.pseudoElementAdded' event.
+data DOMPseudoElementAdded = DOMPseudoElementAdded
+  {
+    -- | Pseudo element's parent element id.
+    dOMPseudoElementAddedParentId :: DOMNodeId,
+    -- | The added pseudo element.
+    dOMPseudoElementAddedPseudoElement :: DOMNode
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMPseudoElementAdded where
+  parseJSON = A.withObject "DOMPseudoElementAdded" $ \o -> DOMPseudoElementAdded
+    <$> o A..: "parentId"
+    <*> o A..: "pseudoElement"
+instance Event DOMPseudoElementAdded where
+  eventName _ = "DOM.pseudoElementAdded"
+
+-- | Type of the 'DOM.topLayerElementsUpdated' event.
+data DOMTopLayerElementsUpdated = DOMTopLayerElementsUpdated
+  deriving (Eq, Show, Read)
+instance FromJSON DOMTopLayerElementsUpdated where
+  parseJSON _ = pure DOMTopLayerElementsUpdated
+instance Event DOMTopLayerElementsUpdated where
+  eventName _ = "DOM.topLayerElementsUpdated"
+
+-- | Type of the 'DOM.pseudoElementRemoved' event.
+data DOMPseudoElementRemoved = DOMPseudoElementRemoved
+  {
+    -- | Pseudo element's parent element id.
+    dOMPseudoElementRemovedParentId :: DOMNodeId,
+    -- | The removed pseudo element id.
+    dOMPseudoElementRemovedPseudoElementId :: DOMNodeId
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMPseudoElementRemoved where
+  parseJSON = A.withObject "DOMPseudoElementRemoved" $ \o -> DOMPseudoElementRemoved
+    <$> o A..: "parentId"
+    <*> o A..: "pseudoElementId"
+instance Event DOMPseudoElementRemoved where
+  eventName _ = "DOM.pseudoElementRemoved"
+
+-- | Type of the 'DOM.setChildNodes' event.
+data DOMSetChildNodes = DOMSetChildNodes
+  {
+    -- | Parent node id to populate with children.
+    dOMSetChildNodesParentId :: DOMNodeId,
+    -- | Child nodes array.
+    dOMSetChildNodesNodes :: [DOMNode]
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMSetChildNodes where
+  parseJSON = A.withObject "DOMSetChildNodes" $ \o -> DOMSetChildNodes
+    <$> o A..: "parentId"
+    <*> o A..: "nodes"
+instance Event DOMSetChildNodes where
+  eventName _ = "DOM.setChildNodes"
+
+-- | Type of the 'DOM.shadowRootPopped' event.
+data DOMShadowRootPopped = DOMShadowRootPopped
+  {
+    -- | Host element id.
+    dOMShadowRootPoppedHostId :: DOMNodeId,
+    -- | Shadow root id.
+    dOMShadowRootPoppedRootId :: DOMNodeId
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMShadowRootPopped where
+  parseJSON = A.withObject "DOMShadowRootPopped" $ \o -> DOMShadowRootPopped
+    <$> o A..: "hostId"
+    <*> o A..: "rootId"
+instance Event DOMShadowRootPopped where
+  eventName _ = "DOM.shadowRootPopped"
+
+-- | Type of the 'DOM.shadowRootPushed' event.
+data DOMShadowRootPushed = DOMShadowRootPushed
+  {
+    -- | Host element id.
+    dOMShadowRootPushedHostId :: DOMNodeId,
+    -- | Shadow root.
+    dOMShadowRootPushedRoot :: DOMNode
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMShadowRootPushed where
+  parseJSON = A.withObject "DOMShadowRootPushed" $ \o -> DOMShadowRootPushed
+    <$> o A..: "hostId"
+    <*> o A..: "root"
+instance Event DOMShadowRootPushed where
+  eventName _ = "DOM.shadowRootPushed"
+
+-- | Collects class names for the node with given id and all of it's child nodes.
+
+-- | Parameters of the 'DOM.collectClassNamesFromSubtree' command.
+data PDOMCollectClassNamesFromSubtree = PDOMCollectClassNamesFromSubtree
+  {
+    -- | Id of the node to collect class names.
+    pDOMCollectClassNamesFromSubtreeNodeId :: DOMNodeId
+  }
+  deriving (Eq, Show)
+pDOMCollectClassNamesFromSubtree
+  {-
+  -- | Id of the node to collect class names.
+  -}
+  :: DOMNodeId
+  -> PDOMCollectClassNamesFromSubtree
+pDOMCollectClassNamesFromSubtree
+  arg_pDOMCollectClassNamesFromSubtreeNodeId
+  = PDOMCollectClassNamesFromSubtree
+    arg_pDOMCollectClassNamesFromSubtreeNodeId
+instance ToJSON PDOMCollectClassNamesFromSubtree where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> Just (pDOMCollectClassNamesFromSubtreeNodeId p)
+    ]
+data DOMCollectClassNamesFromSubtree = DOMCollectClassNamesFromSubtree
+  {
+    -- | Class name list.
+    dOMCollectClassNamesFromSubtreeClassNames :: [T.Text]
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMCollectClassNamesFromSubtree where
+  parseJSON = A.withObject "DOMCollectClassNamesFromSubtree" $ \o -> DOMCollectClassNamesFromSubtree
+    <$> o A..: "classNames"
+instance Command PDOMCollectClassNamesFromSubtree where
+  type CommandResponse PDOMCollectClassNamesFromSubtree = DOMCollectClassNamesFromSubtree
+  commandName _ = "DOM.collectClassNamesFromSubtree"
+
+-- | Creates a deep copy of the specified node and places it into the target container before the
+--   given anchor.
+
+-- | Parameters of the 'DOM.copyTo' command.
+data PDOMCopyTo = PDOMCopyTo
+  {
+    -- | Id of the node to copy.
+    pDOMCopyToNodeId :: DOMNodeId,
+    -- | Id of the element to drop the copy into.
+    pDOMCopyToTargetNodeId :: DOMNodeId,
+    -- | Drop the copy before this node (if absent, the copy becomes the last child of
+    --   `targetNodeId`).
+    pDOMCopyToInsertBeforeNodeId :: Maybe DOMNodeId
+  }
+  deriving (Eq, Show)
+pDOMCopyTo
+  {-
+  -- | Id of the node to copy.
+  -}
+  :: DOMNodeId
+  {-
+  -- | Id of the element to drop the copy into.
+  -}
+  -> DOMNodeId
+  -> PDOMCopyTo
+pDOMCopyTo
+  arg_pDOMCopyToNodeId
+  arg_pDOMCopyToTargetNodeId
+  = PDOMCopyTo
+    arg_pDOMCopyToNodeId
+    arg_pDOMCopyToTargetNodeId
+    Nothing
+instance ToJSON PDOMCopyTo where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> Just (pDOMCopyToNodeId p),
+    ("targetNodeId" A..=) <$> Just (pDOMCopyToTargetNodeId p),
+    ("insertBeforeNodeId" A..=) <$> (pDOMCopyToInsertBeforeNodeId p)
+    ]
+data DOMCopyTo = DOMCopyTo
+  {
+    -- | Id of the node clone.
+    dOMCopyToNodeId :: DOMNodeId
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMCopyTo where
+  parseJSON = A.withObject "DOMCopyTo" $ \o -> DOMCopyTo
+    <$> o A..: "nodeId"
+instance Command PDOMCopyTo where
+  type CommandResponse PDOMCopyTo = DOMCopyTo
+  commandName _ = "DOM.copyTo"
+
+-- | Describes node given its id, does not require domain to be enabled. Does not start tracking any
+--   objects, can be used for automation.
+
+-- | Parameters of the 'DOM.describeNode' command.
+data PDOMDescribeNode = PDOMDescribeNode
+  {
+    -- | Identifier of the node.
+    pDOMDescribeNodeNodeId :: Maybe DOMNodeId,
+    -- | Identifier of the backend node.
+    pDOMDescribeNodeBackendNodeId :: Maybe DOMBackendNodeId,
+    -- | JavaScript object id of the node wrapper.
+    pDOMDescribeNodeObjectId :: Maybe Runtime.RuntimeRemoteObjectId,
+    -- | The maximum depth at which children should be retrieved, defaults to 1. Use -1 for the
+    --   entire subtree or provide an integer larger than 0.
+    pDOMDescribeNodeDepth :: Maybe Int,
+    -- | Whether or not iframes and shadow roots should be traversed when returning the subtree
+    --   (default is false).
+    pDOMDescribeNodePierce :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pDOMDescribeNode
+  :: PDOMDescribeNode
+pDOMDescribeNode
+  = PDOMDescribeNode
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PDOMDescribeNode where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> (pDOMDescribeNodeNodeId p),
+    ("backendNodeId" A..=) <$> (pDOMDescribeNodeBackendNodeId p),
+    ("objectId" A..=) <$> (pDOMDescribeNodeObjectId p),
+    ("depth" A..=) <$> (pDOMDescribeNodeDepth p),
+    ("pierce" A..=) <$> (pDOMDescribeNodePierce p)
+    ]
+data DOMDescribeNode = DOMDescribeNode
+  {
+    -- | Node description.
+    dOMDescribeNodeNode :: DOMNode
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMDescribeNode where
+  parseJSON = A.withObject "DOMDescribeNode" $ \o -> DOMDescribeNode
+    <$> o A..: "node"
+instance Command PDOMDescribeNode where
+  type CommandResponse PDOMDescribeNode = DOMDescribeNode
+  commandName _ = "DOM.describeNode"
+
+-- | Scrolls the specified rect of the given node into view if not already visible.
+--   Note: exactly one between nodeId, backendNodeId and objectId should be passed
+--   to identify the node.
+
+-- | Parameters of the 'DOM.scrollIntoViewIfNeeded' command.
+data PDOMScrollIntoViewIfNeeded = PDOMScrollIntoViewIfNeeded
+  {
+    -- | Identifier of the node.
+    pDOMScrollIntoViewIfNeededNodeId :: Maybe DOMNodeId,
+    -- | Identifier of the backend node.
+    pDOMScrollIntoViewIfNeededBackendNodeId :: Maybe DOMBackendNodeId,
+    -- | JavaScript object id of the node wrapper.
+    pDOMScrollIntoViewIfNeededObjectId :: Maybe Runtime.RuntimeRemoteObjectId,
+    -- | The rect to be scrolled into view, relative to the node's border box, in CSS pixels.
+    --   When omitted, center of the node will be used, similar to Element.scrollIntoView.
+    pDOMScrollIntoViewIfNeededRect :: Maybe DOMRect
+  }
+  deriving (Eq, Show)
+pDOMScrollIntoViewIfNeeded
+  :: PDOMScrollIntoViewIfNeeded
+pDOMScrollIntoViewIfNeeded
+  = PDOMScrollIntoViewIfNeeded
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PDOMScrollIntoViewIfNeeded where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> (pDOMScrollIntoViewIfNeededNodeId p),
+    ("backendNodeId" A..=) <$> (pDOMScrollIntoViewIfNeededBackendNodeId p),
+    ("objectId" A..=) <$> (pDOMScrollIntoViewIfNeededObjectId p),
+    ("rect" A..=) <$> (pDOMScrollIntoViewIfNeededRect p)
+    ]
+instance Command PDOMScrollIntoViewIfNeeded where
+  type CommandResponse PDOMScrollIntoViewIfNeeded = ()
+  commandName _ = "DOM.scrollIntoViewIfNeeded"
+  fromJSON = const . A.Success . const ()
+
+-- | Disables DOM agent for the given page.
+
+-- | Parameters of the 'DOM.disable' command.
+data PDOMDisable = PDOMDisable
+  deriving (Eq, Show)
+pDOMDisable
+  :: PDOMDisable
+pDOMDisable
+  = PDOMDisable
+instance ToJSON PDOMDisable where
+  toJSON _ = A.Null
+instance Command PDOMDisable where
+  type CommandResponse PDOMDisable = ()
+  commandName _ = "DOM.disable"
+  fromJSON = const . A.Success . const ()
+
+-- | Discards search results from the session with the given id. `getSearchResults` should no longer
+--   be called for that search.
+
+-- | Parameters of the 'DOM.discardSearchResults' command.
+data PDOMDiscardSearchResults = PDOMDiscardSearchResults
+  {
+    -- | Unique search session identifier.
+    pDOMDiscardSearchResultsSearchId :: T.Text
+  }
+  deriving (Eq, Show)
+pDOMDiscardSearchResults
+  {-
+  -- | Unique search session identifier.
+  -}
+  :: T.Text
+  -> PDOMDiscardSearchResults
+pDOMDiscardSearchResults
+  arg_pDOMDiscardSearchResultsSearchId
+  = PDOMDiscardSearchResults
+    arg_pDOMDiscardSearchResultsSearchId
+instance ToJSON PDOMDiscardSearchResults where
+  toJSON p = A.object $ catMaybes [
+    ("searchId" A..=) <$> Just (pDOMDiscardSearchResultsSearchId p)
+    ]
+instance Command PDOMDiscardSearchResults where
+  type CommandResponse PDOMDiscardSearchResults = ()
+  commandName _ = "DOM.discardSearchResults"
+  fromJSON = const . A.Success . const ()
+
+-- | Enables DOM agent for the given page.
+
+-- | Parameters of the 'DOM.enable' command.
+data PDOMEnableIncludeWhitespace = PDOMEnableIncludeWhitespaceNone | PDOMEnableIncludeWhitespaceAll
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PDOMEnableIncludeWhitespace where
+  parseJSON = A.withText "PDOMEnableIncludeWhitespace" $ \v -> case v of
+    "none" -> pure PDOMEnableIncludeWhitespaceNone
+    "all" -> pure PDOMEnableIncludeWhitespaceAll
+    "_" -> fail "failed to parse PDOMEnableIncludeWhitespace"
+instance ToJSON PDOMEnableIncludeWhitespace where
+  toJSON v = A.String $ case v of
+    PDOMEnableIncludeWhitespaceNone -> "none"
+    PDOMEnableIncludeWhitespaceAll -> "all"
+data PDOMEnable = PDOMEnable
+  {
+    -- | Whether to include whitespaces in the children array of returned Nodes.
+    pDOMEnableIncludeWhitespace :: Maybe PDOMEnableIncludeWhitespace
+  }
+  deriving (Eq, Show)
+pDOMEnable
+  :: PDOMEnable
+pDOMEnable
+  = PDOMEnable
+    Nothing
+instance ToJSON PDOMEnable where
+  toJSON p = A.object $ catMaybes [
+    ("includeWhitespace" A..=) <$> (pDOMEnableIncludeWhitespace p)
+    ]
+instance Command PDOMEnable where
+  type CommandResponse PDOMEnable = ()
+  commandName _ = "DOM.enable"
+  fromJSON = const . A.Success . const ()
+
+-- | Focuses the given element.
+
+-- | Parameters of the 'DOM.focus' command.
+data PDOMFocus = PDOMFocus
+  {
+    -- | Identifier of the node.
+    pDOMFocusNodeId :: Maybe DOMNodeId,
+    -- | Identifier of the backend node.
+    pDOMFocusBackendNodeId :: Maybe DOMBackendNodeId,
+    -- | JavaScript object id of the node wrapper.
+    pDOMFocusObjectId :: Maybe Runtime.RuntimeRemoteObjectId
+  }
+  deriving (Eq, Show)
+pDOMFocus
+  :: PDOMFocus
+pDOMFocus
+  = PDOMFocus
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PDOMFocus where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> (pDOMFocusNodeId p),
+    ("backendNodeId" A..=) <$> (pDOMFocusBackendNodeId p),
+    ("objectId" A..=) <$> (pDOMFocusObjectId p)
+    ]
+instance Command PDOMFocus where
+  type CommandResponse PDOMFocus = ()
+  commandName _ = "DOM.focus"
+  fromJSON = const . A.Success . const ()
+
+-- | Returns attributes for the specified node.
+
+-- | Parameters of the 'DOM.getAttributes' command.
+data PDOMGetAttributes = PDOMGetAttributes
+  {
+    -- | Id of the node to retrieve attibutes for.
+    pDOMGetAttributesNodeId :: DOMNodeId
+  }
+  deriving (Eq, Show)
+pDOMGetAttributes
+  {-
+  -- | Id of the node to retrieve attibutes for.
+  -}
+  :: DOMNodeId
+  -> PDOMGetAttributes
+pDOMGetAttributes
+  arg_pDOMGetAttributesNodeId
+  = PDOMGetAttributes
+    arg_pDOMGetAttributesNodeId
+instance ToJSON PDOMGetAttributes where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> Just (pDOMGetAttributesNodeId p)
+    ]
+data DOMGetAttributes = DOMGetAttributes
+  {
+    -- | An interleaved array of node attribute names and values.
+    dOMGetAttributesAttributes :: [T.Text]
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMGetAttributes where
+  parseJSON = A.withObject "DOMGetAttributes" $ \o -> DOMGetAttributes
+    <$> o A..: "attributes"
+instance Command PDOMGetAttributes where
+  type CommandResponse PDOMGetAttributes = DOMGetAttributes
+  commandName _ = "DOM.getAttributes"
+
+-- | Returns boxes for the given node.
+
+-- | Parameters of the 'DOM.getBoxModel' command.
+data PDOMGetBoxModel = PDOMGetBoxModel
+  {
+    -- | Identifier of the node.
+    pDOMGetBoxModelNodeId :: Maybe DOMNodeId,
+    -- | Identifier of the backend node.
+    pDOMGetBoxModelBackendNodeId :: Maybe DOMBackendNodeId,
+    -- | JavaScript object id of the node wrapper.
+    pDOMGetBoxModelObjectId :: Maybe Runtime.RuntimeRemoteObjectId
+  }
+  deriving (Eq, Show)
+pDOMGetBoxModel
+  :: PDOMGetBoxModel
+pDOMGetBoxModel
+  = PDOMGetBoxModel
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PDOMGetBoxModel where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> (pDOMGetBoxModelNodeId p),
+    ("backendNodeId" A..=) <$> (pDOMGetBoxModelBackendNodeId p),
+    ("objectId" A..=) <$> (pDOMGetBoxModelObjectId p)
+    ]
+data DOMGetBoxModel = DOMGetBoxModel
+  {
+    -- | Box model for the node.
+    dOMGetBoxModelModel :: DOMBoxModel
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMGetBoxModel where
+  parseJSON = A.withObject "DOMGetBoxModel" $ \o -> DOMGetBoxModel
+    <$> o A..: "model"
+instance Command PDOMGetBoxModel where
+  type CommandResponse PDOMGetBoxModel = DOMGetBoxModel
+  commandName _ = "DOM.getBoxModel"
+
+-- | Returns quads that describe node position on the page. This method
+--   might return multiple quads for inline nodes.
+
+-- | Parameters of the 'DOM.getContentQuads' command.
+data PDOMGetContentQuads = PDOMGetContentQuads
+  {
+    -- | Identifier of the node.
+    pDOMGetContentQuadsNodeId :: Maybe DOMNodeId,
+    -- | Identifier of the backend node.
+    pDOMGetContentQuadsBackendNodeId :: Maybe DOMBackendNodeId,
+    -- | JavaScript object id of the node wrapper.
+    pDOMGetContentQuadsObjectId :: Maybe Runtime.RuntimeRemoteObjectId
+  }
+  deriving (Eq, Show)
+pDOMGetContentQuads
+  :: PDOMGetContentQuads
+pDOMGetContentQuads
+  = PDOMGetContentQuads
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PDOMGetContentQuads where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> (pDOMGetContentQuadsNodeId p),
+    ("backendNodeId" A..=) <$> (pDOMGetContentQuadsBackendNodeId p),
+    ("objectId" A..=) <$> (pDOMGetContentQuadsObjectId p)
+    ]
+data DOMGetContentQuads = DOMGetContentQuads
+  {
+    -- | Quads that describe node layout relative to viewport.
+    dOMGetContentQuadsQuads :: [DOMQuad]
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMGetContentQuads where
+  parseJSON = A.withObject "DOMGetContentQuads" $ \o -> DOMGetContentQuads
+    <$> o A..: "quads"
+instance Command PDOMGetContentQuads where
+  type CommandResponse PDOMGetContentQuads = DOMGetContentQuads
+  commandName _ = "DOM.getContentQuads"
+
+-- | Returns the root DOM node (and optionally the subtree) to the caller.
+
+-- | Parameters of the 'DOM.getDocument' command.
+data PDOMGetDocument = PDOMGetDocument
+  {
+    -- | The maximum depth at which children should be retrieved, defaults to 1. Use -1 for the
+    --   entire subtree or provide an integer larger than 0.
+    pDOMGetDocumentDepth :: Maybe Int,
+    -- | Whether or not iframes and shadow roots should be traversed when returning the subtree
+    --   (default is false).
+    pDOMGetDocumentPierce :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pDOMGetDocument
+  :: PDOMGetDocument
+pDOMGetDocument
+  = PDOMGetDocument
+    Nothing
+    Nothing
+instance ToJSON PDOMGetDocument where
+  toJSON p = A.object $ catMaybes [
+    ("depth" A..=) <$> (pDOMGetDocumentDepth p),
+    ("pierce" A..=) <$> (pDOMGetDocumentPierce p)
+    ]
+data DOMGetDocument = DOMGetDocument
+  {
+    -- | Resulting node.
+    dOMGetDocumentRoot :: DOMNode
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMGetDocument where
+  parseJSON = A.withObject "DOMGetDocument" $ \o -> DOMGetDocument
+    <$> o A..: "root"
+instance Command PDOMGetDocument where
+  type CommandResponse PDOMGetDocument = DOMGetDocument
+  commandName _ = "DOM.getDocument"
+
+-- | Finds nodes with a given computed style in a subtree.
+
+-- | Parameters of the 'DOM.getNodesForSubtreeByStyle' command.
+data PDOMGetNodesForSubtreeByStyle = PDOMGetNodesForSubtreeByStyle
+  {
+    -- | Node ID pointing to the root of a subtree.
+    pDOMGetNodesForSubtreeByStyleNodeId :: DOMNodeId,
+    -- | The style to filter nodes by (includes nodes if any of properties matches).
+    pDOMGetNodesForSubtreeByStyleComputedStyles :: [DOMCSSComputedStyleProperty],
+    -- | Whether or not iframes and shadow roots in the same target should be traversed when returning the
+    --   results (default is false).
+    pDOMGetNodesForSubtreeByStylePierce :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pDOMGetNodesForSubtreeByStyle
+  {-
+  -- | Node ID pointing to the root of a subtree.
+  -}
+  :: DOMNodeId
+  {-
+  -- | The style to filter nodes by (includes nodes if any of properties matches).
+  -}
+  -> [DOMCSSComputedStyleProperty]
+  -> PDOMGetNodesForSubtreeByStyle
+pDOMGetNodesForSubtreeByStyle
+  arg_pDOMGetNodesForSubtreeByStyleNodeId
+  arg_pDOMGetNodesForSubtreeByStyleComputedStyles
+  = PDOMGetNodesForSubtreeByStyle
+    arg_pDOMGetNodesForSubtreeByStyleNodeId
+    arg_pDOMGetNodesForSubtreeByStyleComputedStyles
+    Nothing
+instance ToJSON PDOMGetNodesForSubtreeByStyle where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> Just (pDOMGetNodesForSubtreeByStyleNodeId p),
+    ("computedStyles" A..=) <$> Just (pDOMGetNodesForSubtreeByStyleComputedStyles p),
+    ("pierce" A..=) <$> (pDOMGetNodesForSubtreeByStylePierce p)
+    ]
+data DOMGetNodesForSubtreeByStyle = DOMGetNodesForSubtreeByStyle
+  {
+    -- | Resulting nodes.
+    dOMGetNodesForSubtreeByStyleNodeIds :: [DOMNodeId]
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMGetNodesForSubtreeByStyle where
+  parseJSON = A.withObject "DOMGetNodesForSubtreeByStyle" $ \o -> DOMGetNodesForSubtreeByStyle
+    <$> o A..: "nodeIds"
+instance Command PDOMGetNodesForSubtreeByStyle where
+  type CommandResponse PDOMGetNodesForSubtreeByStyle = DOMGetNodesForSubtreeByStyle
+  commandName _ = "DOM.getNodesForSubtreeByStyle"
+
+-- | Returns node id at given location. Depending on whether DOM domain is enabled, nodeId is
+--   either returned or not.
+
+-- | Parameters of the 'DOM.getNodeForLocation' command.
+data PDOMGetNodeForLocation = PDOMGetNodeForLocation
+  {
+    -- | X coordinate.
+    pDOMGetNodeForLocationX :: Int,
+    -- | Y coordinate.
+    pDOMGetNodeForLocationY :: Int,
+    -- | False to skip to the nearest non-UA shadow root ancestor (default: false).
+    pDOMGetNodeForLocationIncludeUserAgentShadowDOM :: Maybe Bool,
+    -- | Whether to ignore pointer-events: none on elements and hit test them.
+    pDOMGetNodeForLocationIgnorePointerEventsNone :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pDOMGetNodeForLocation
+  {-
+  -- | X coordinate.
+  -}
+  :: Int
+  {-
+  -- | Y coordinate.
+  -}
+  -> Int
+  -> PDOMGetNodeForLocation
+pDOMGetNodeForLocation
+  arg_pDOMGetNodeForLocationX
+  arg_pDOMGetNodeForLocationY
+  = PDOMGetNodeForLocation
+    arg_pDOMGetNodeForLocationX
+    arg_pDOMGetNodeForLocationY
+    Nothing
+    Nothing
+instance ToJSON PDOMGetNodeForLocation where
+  toJSON p = A.object $ catMaybes [
+    ("x" A..=) <$> Just (pDOMGetNodeForLocationX p),
+    ("y" A..=) <$> Just (pDOMGetNodeForLocationY p),
+    ("includeUserAgentShadowDOM" A..=) <$> (pDOMGetNodeForLocationIncludeUserAgentShadowDOM p),
+    ("ignorePointerEventsNone" A..=) <$> (pDOMGetNodeForLocationIgnorePointerEventsNone p)
+    ]
+data DOMGetNodeForLocation = DOMGetNodeForLocation
+  {
+    -- | Resulting node.
+    dOMGetNodeForLocationBackendNodeId :: DOMBackendNodeId,
+    -- | Frame this node belongs to.
+    dOMGetNodeForLocationFrameId :: PageFrameId,
+    -- | Id of the node at given coordinates, only when enabled and requested document.
+    dOMGetNodeForLocationNodeId :: Maybe DOMNodeId
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMGetNodeForLocation where
+  parseJSON = A.withObject "DOMGetNodeForLocation" $ \o -> DOMGetNodeForLocation
+    <$> o A..: "backendNodeId"
+    <*> o A..: "frameId"
+    <*> o A..:? "nodeId"
+instance Command PDOMGetNodeForLocation where
+  type CommandResponse PDOMGetNodeForLocation = DOMGetNodeForLocation
+  commandName _ = "DOM.getNodeForLocation"
+
+-- | Returns node's HTML markup.
+
+-- | Parameters of the 'DOM.getOuterHTML' command.
+data PDOMGetOuterHTML = PDOMGetOuterHTML
+  {
+    -- | Identifier of the node.
+    pDOMGetOuterHTMLNodeId :: Maybe DOMNodeId,
+    -- | Identifier of the backend node.
+    pDOMGetOuterHTMLBackendNodeId :: Maybe DOMBackendNodeId,
+    -- | JavaScript object id of the node wrapper.
+    pDOMGetOuterHTMLObjectId :: Maybe Runtime.RuntimeRemoteObjectId
+  }
+  deriving (Eq, Show)
+pDOMGetOuterHTML
+  :: PDOMGetOuterHTML
+pDOMGetOuterHTML
+  = PDOMGetOuterHTML
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PDOMGetOuterHTML where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> (pDOMGetOuterHTMLNodeId p),
+    ("backendNodeId" A..=) <$> (pDOMGetOuterHTMLBackendNodeId p),
+    ("objectId" A..=) <$> (pDOMGetOuterHTMLObjectId p)
+    ]
+data DOMGetOuterHTML = DOMGetOuterHTML
+  {
+    -- | Outer HTML markup.
+    dOMGetOuterHTMLOuterHTML :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMGetOuterHTML where
+  parseJSON = A.withObject "DOMGetOuterHTML" $ \o -> DOMGetOuterHTML
+    <$> o A..: "outerHTML"
+instance Command PDOMGetOuterHTML where
+  type CommandResponse PDOMGetOuterHTML = DOMGetOuterHTML
+  commandName _ = "DOM.getOuterHTML"
+
+-- | Returns the id of the nearest ancestor that is a relayout boundary.
+
+-- | Parameters of the 'DOM.getRelayoutBoundary' command.
+data PDOMGetRelayoutBoundary = PDOMGetRelayoutBoundary
+  {
+    -- | Id of the node.
+    pDOMGetRelayoutBoundaryNodeId :: DOMNodeId
+  }
+  deriving (Eq, Show)
+pDOMGetRelayoutBoundary
+  {-
+  -- | Id of the node.
+  -}
+  :: DOMNodeId
+  -> PDOMGetRelayoutBoundary
+pDOMGetRelayoutBoundary
+  arg_pDOMGetRelayoutBoundaryNodeId
+  = PDOMGetRelayoutBoundary
+    arg_pDOMGetRelayoutBoundaryNodeId
+instance ToJSON PDOMGetRelayoutBoundary where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> Just (pDOMGetRelayoutBoundaryNodeId p)
+    ]
+data DOMGetRelayoutBoundary = DOMGetRelayoutBoundary
+  {
+    -- | Relayout boundary node id for the given node.
+    dOMGetRelayoutBoundaryNodeId :: DOMNodeId
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMGetRelayoutBoundary where
+  parseJSON = A.withObject "DOMGetRelayoutBoundary" $ \o -> DOMGetRelayoutBoundary
+    <$> o A..: "nodeId"
+instance Command PDOMGetRelayoutBoundary where
+  type CommandResponse PDOMGetRelayoutBoundary = DOMGetRelayoutBoundary
+  commandName _ = "DOM.getRelayoutBoundary"
+
+-- | Returns search results from given `fromIndex` to given `toIndex` from the search with the given
+--   identifier.
+
+-- | Parameters of the 'DOM.getSearchResults' command.
+data PDOMGetSearchResults = PDOMGetSearchResults
+  {
+    -- | Unique search session identifier.
+    pDOMGetSearchResultsSearchId :: T.Text,
+    -- | Start index of the search result to be returned.
+    pDOMGetSearchResultsFromIndex :: Int,
+    -- | End index of the search result to be returned.
+    pDOMGetSearchResultsToIndex :: Int
+  }
+  deriving (Eq, Show)
+pDOMGetSearchResults
+  {-
+  -- | Unique search session identifier.
+  -}
+  :: T.Text
+  {-
+  -- | Start index of the search result to be returned.
+  -}
+  -> Int
+  {-
+  -- | End index of the search result to be returned.
+  -}
+  -> Int
+  -> PDOMGetSearchResults
+pDOMGetSearchResults
+  arg_pDOMGetSearchResultsSearchId
+  arg_pDOMGetSearchResultsFromIndex
+  arg_pDOMGetSearchResultsToIndex
+  = PDOMGetSearchResults
+    arg_pDOMGetSearchResultsSearchId
+    arg_pDOMGetSearchResultsFromIndex
+    arg_pDOMGetSearchResultsToIndex
+instance ToJSON PDOMGetSearchResults where
+  toJSON p = A.object $ catMaybes [
+    ("searchId" A..=) <$> Just (pDOMGetSearchResultsSearchId p),
+    ("fromIndex" A..=) <$> Just (pDOMGetSearchResultsFromIndex p),
+    ("toIndex" A..=) <$> Just (pDOMGetSearchResultsToIndex p)
+    ]
+data DOMGetSearchResults = DOMGetSearchResults
+  {
+    -- | Ids of the search result nodes.
+    dOMGetSearchResultsNodeIds :: [DOMNodeId]
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMGetSearchResults where
+  parseJSON = A.withObject "DOMGetSearchResults" $ \o -> DOMGetSearchResults
+    <$> o A..: "nodeIds"
+instance Command PDOMGetSearchResults where
+  type CommandResponse PDOMGetSearchResults = DOMGetSearchResults
+  commandName _ = "DOM.getSearchResults"
+
+-- | Hides any highlight.
+
+-- | Parameters of the 'DOM.hideHighlight' command.
+data PDOMHideHighlight = PDOMHideHighlight
+  deriving (Eq, Show)
+pDOMHideHighlight
+  :: PDOMHideHighlight
+pDOMHideHighlight
+  = PDOMHideHighlight
+instance ToJSON PDOMHideHighlight where
+  toJSON _ = A.Null
+instance Command PDOMHideHighlight where
+  type CommandResponse PDOMHideHighlight = ()
+  commandName _ = "DOM.hideHighlight"
+  fromJSON = const . A.Success . const ()
+
+-- | Highlights DOM node.
+
+-- | Parameters of the 'DOM.highlightNode' command.
+data PDOMHighlightNode = PDOMHighlightNode
+  deriving (Eq, Show)
+pDOMHighlightNode
+  :: PDOMHighlightNode
+pDOMHighlightNode
+  = PDOMHighlightNode
+instance ToJSON PDOMHighlightNode where
+  toJSON _ = A.Null
+instance Command PDOMHighlightNode where
+  type CommandResponse PDOMHighlightNode = ()
+  commandName _ = "DOM.highlightNode"
+  fromJSON = const . A.Success . const ()
+
+-- | Highlights given rectangle.
+
+-- | Parameters of the 'DOM.highlightRect' command.
+data PDOMHighlightRect = PDOMHighlightRect
+  deriving (Eq, Show)
+pDOMHighlightRect
+  :: PDOMHighlightRect
+pDOMHighlightRect
+  = PDOMHighlightRect
+instance ToJSON PDOMHighlightRect where
+  toJSON _ = A.Null
+instance Command PDOMHighlightRect where
+  type CommandResponse PDOMHighlightRect = ()
+  commandName _ = "DOM.highlightRect"
+  fromJSON = const . A.Success . const ()
+
+-- | Marks last undoable state.
+
+-- | Parameters of the 'DOM.markUndoableState' command.
+data PDOMMarkUndoableState = PDOMMarkUndoableState
+  deriving (Eq, Show)
+pDOMMarkUndoableState
+  :: PDOMMarkUndoableState
+pDOMMarkUndoableState
+  = PDOMMarkUndoableState
+instance ToJSON PDOMMarkUndoableState where
+  toJSON _ = A.Null
+instance Command PDOMMarkUndoableState where
+  type CommandResponse PDOMMarkUndoableState = ()
+  commandName _ = "DOM.markUndoableState"
+  fromJSON = const . A.Success . const ()
+
+-- | Moves node into the new container, places it before the given anchor.
+
+-- | Parameters of the 'DOM.moveTo' command.
+data PDOMMoveTo = PDOMMoveTo
+  {
+    -- | Id of the node to move.
+    pDOMMoveToNodeId :: DOMNodeId,
+    -- | Id of the element to drop the moved node into.
+    pDOMMoveToTargetNodeId :: DOMNodeId,
+    -- | Drop node before this one (if absent, the moved node becomes the last child of
+    --   `targetNodeId`).
+    pDOMMoveToInsertBeforeNodeId :: Maybe DOMNodeId
+  }
+  deriving (Eq, Show)
+pDOMMoveTo
+  {-
+  -- | Id of the node to move.
+  -}
+  :: DOMNodeId
+  {-
+  -- | Id of the element to drop the moved node into.
+  -}
+  -> DOMNodeId
+  -> PDOMMoveTo
+pDOMMoveTo
+  arg_pDOMMoveToNodeId
+  arg_pDOMMoveToTargetNodeId
+  = PDOMMoveTo
+    arg_pDOMMoveToNodeId
+    arg_pDOMMoveToTargetNodeId
+    Nothing
+instance ToJSON PDOMMoveTo where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> Just (pDOMMoveToNodeId p),
+    ("targetNodeId" A..=) <$> Just (pDOMMoveToTargetNodeId p),
+    ("insertBeforeNodeId" A..=) <$> (pDOMMoveToInsertBeforeNodeId p)
+    ]
+data DOMMoveTo = DOMMoveTo
+  {
+    -- | New id of the moved node.
+    dOMMoveToNodeId :: DOMNodeId
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMMoveTo where
+  parseJSON = A.withObject "DOMMoveTo" $ \o -> DOMMoveTo
+    <$> o A..: "nodeId"
+instance Command PDOMMoveTo where
+  type CommandResponse PDOMMoveTo = DOMMoveTo
+  commandName _ = "DOM.moveTo"
+
+-- | Searches for a given string in the DOM tree. Use `getSearchResults` to access search results or
+--   `cancelSearch` to end this search session.
+
+-- | Parameters of the 'DOM.performSearch' command.
+data PDOMPerformSearch = PDOMPerformSearch
+  {
+    -- | Plain text or query selector or XPath search query.
+    pDOMPerformSearchQuery :: T.Text,
+    -- | True to search in user agent shadow DOM.
+    pDOMPerformSearchIncludeUserAgentShadowDOM :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pDOMPerformSearch
+  {-
+  -- | Plain text or query selector or XPath search query.
+  -}
+  :: T.Text
+  -> PDOMPerformSearch
+pDOMPerformSearch
+  arg_pDOMPerformSearchQuery
+  = PDOMPerformSearch
+    arg_pDOMPerformSearchQuery
+    Nothing
+instance ToJSON PDOMPerformSearch where
+  toJSON p = A.object $ catMaybes [
+    ("query" A..=) <$> Just (pDOMPerformSearchQuery p),
+    ("includeUserAgentShadowDOM" A..=) <$> (pDOMPerformSearchIncludeUserAgentShadowDOM p)
+    ]
+data DOMPerformSearch = DOMPerformSearch
+  {
+    -- | Unique search session identifier.
+    dOMPerformSearchSearchId :: T.Text,
+    -- | Number of search results.
+    dOMPerformSearchResultCount :: Int
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMPerformSearch where
+  parseJSON = A.withObject "DOMPerformSearch" $ \o -> DOMPerformSearch
+    <$> o A..: "searchId"
+    <*> o A..: "resultCount"
+instance Command PDOMPerformSearch where
+  type CommandResponse PDOMPerformSearch = DOMPerformSearch
+  commandName _ = "DOM.performSearch"
+
+-- | Requests that the node is sent to the caller given its path. // FIXME, use XPath
+
+-- | Parameters of the 'DOM.pushNodeByPathToFrontend' command.
+data PDOMPushNodeByPathToFrontend = PDOMPushNodeByPathToFrontend
+  {
+    -- | Path to node in the proprietary format.
+    pDOMPushNodeByPathToFrontendPath :: T.Text
+  }
+  deriving (Eq, Show)
+pDOMPushNodeByPathToFrontend
+  {-
+  -- | Path to node in the proprietary format.
+  -}
+  :: T.Text
+  -> PDOMPushNodeByPathToFrontend
+pDOMPushNodeByPathToFrontend
+  arg_pDOMPushNodeByPathToFrontendPath
+  = PDOMPushNodeByPathToFrontend
+    arg_pDOMPushNodeByPathToFrontendPath
+instance ToJSON PDOMPushNodeByPathToFrontend where
+  toJSON p = A.object $ catMaybes [
+    ("path" A..=) <$> Just (pDOMPushNodeByPathToFrontendPath p)
+    ]
+data DOMPushNodeByPathToFrontend = DOMPushNodeByPathToFrontend
+  {
+    -- | Id of the node for given path.
+    dOMPushNodeByPathToFrontendNodeId :: DOMNodeId
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMPushNodeByPathToFrontend where
+  parseJSON = A.withObject "DOMPushNodeByPathToFrontend" $ \o -> DOMPushNodeByPathToFrontend
+    <$> o A..: "nodeId"
+instance Command PDOMPushNodeByPathToFrontend where
+  type CommandResponse PDOMPushNodeByPathToFrontend = DOMPushNodeByPathToFrontend
+  commandName _ = "DOM.pushNodeByPathToFrontend"
+
+-- | Requests that a batch of nodes is sent to the caller given their backend node ids.
+
+-- | Parameters of the 'DOM.pushNodesByBackendIdsToFrontend' command.
+data PDOMPushNodesByBackendIdsToFrontend = PDOMPushNodesByBackendIdsToFrontend
+  {
+    -- | The array of backend node ids.
+    pDOMPushNodesByBackendIdsToFrontendBackendNodeIds :: [DOMBackendNodeId]
+  }
+  deriving (Eq, Show)
+pDOMPushNodesByBackendIdsToFrontend
+  {-
+  -- | The array of backend node ids.
+  -}
+  :: [DOMBackendNodeId]
+  -> PDOMPushNodesByBackendIdsToFrontend
+pDOMPushNodesByBackendIdsToFrontend
+  arg_pDOMPushNodesByBackendIdsToFrontendBackendNodeIds
+  = PDOMPushNodesByBackendIdsToFrontend
+    arg_pDOMPushNodesByBackendIdsToFrontendBackendNodeIds
+instance ToJSON PDOMPushNodesByBackendIdsToFrontend where
+  toJSON p = A.object $ catMaybes [
+    ("backendNodeIds" A..=) <$> Just (pDOMPushNodesByBackendIdsToFrontendBackendNodeIds p)
+    ]
+data DOMPushNodesByBackendIdsToFrontend = DOMPushNodesByBackendIdsToFrontend
+  {
+    -- | The array of ids of pushed nodes that correspond to the backend ids specified in
+    --   backendNodeIds.
+    dOMPushNodesByBackendIdsToFrontendNodeIds :: [DOMNodeId]
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMPushNodesByBackendIdsToFrontend where
+  parseJSON = A.withObject "DOMPushNodesByBackendIdsToFrontend" $ \o -> DOMPushNodesByBackendIdsToFrontend
+    <$> o A..: "nodeIds"
+instance Command PDOMPushNodesByBackendIdsToFrontend where
+  type CommandResponse PDOMPushNodesByBackendIdsToFrontend = DOMPushNodesByBackendIdsToFrontend
+  commandName _ = "DOM.pushNodesByBackendIdsToFrontend"
+
+-- | Executes `querySelector` on a given node.
+
+-- | Parameters of the 'DOM.querySelector' command.
+data PDOMQuerySelector = PDOMQuerySelector
+  {
+    -- | Id of the node to query upon.
+    pDOMQuerySelectorNodeId :: DOMNodeId,
+    -- | Selector string.
+    pDOMQuerySelectorSelector :: T.Text
+  }
+  deriving (Eq, Show)
+pDOMQuerySelector
+  {-
+  -- | Id of the node to query upon.
+  -}
+  :: DOMNodeId
+  {-
+  -- | Selector string.
+  -}
+  -> T.Text
+  -> PDOMQuerySelector
+pDOMQuerySelector
+  arg_pDOMQuerySelectorNodeId
+  arg_pDOMQuerySelectorSelector
+  = PDOMQuerySelector
+    arg_pDOMQuerySelectorNodeId
+    arg_pDOMQuerySelectorSelector
+instance ToJSON PDOMQuerySelector where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> Just (pDOMQuerySelectorNodeId p),
+    ("selector" A..=) <$> Just (pDOMQuerySelectorSelector p)
+    ]
+data DOMQuerySelector = DOMQuerySelector
+  {
+    -- | Query selector result.
+    dOMQuerySelectorNodeId :: DOMNodeId
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMQuerySelector where
+  parseJSON = A.withObject "DOMQuerySelector" $ \o -> DOMQuerySelector
+    <$> o A..: "nodeId"
+instance Command PDOMQuerySelector where
+  type CommandResponse PDOMQuerySelector = DOMQuerySelector
+  commandName _ = "DOM.querySelector"
+
+-- | Executes `querySelectorAll` on a given node.
+
+-- | Parameters of the 'DOM.querySelectorAll' command.
+data PDOMQuerySelectorAll = PDOMQuerySelectorAll
+  {
+    -- | Id of the node to query upon.
+    pDOMQuerySelectorAllNodeId :: DOMNodeId,
+    -- | Selector string.
+    pDOMQuerySelectorAllSelector :: T.Text
+  }
+  deriving (Eq, Show)
+pDOMQuerySelectorAll
+  {-
+  -- | Id of the node to query upon.
+  -}
+  :: DOMNodeId
+  {-
+  -- | Selector string.
+  -}
+  -> T.Text
+  -> PDOMQuerySelectorAll
+pDOMQuerySelectorAll
+  arg_pDOMQuerySelectorAllNodeId
+  arg_pDOMQuerySelectorAllSelector
+  = PDOMQuerySelectorAll
+    arg_pDOMQuerySelectorAllNodeId
+    arg_pDOMQuerySelectorAllSelector
+instance ToJSON PDOMQuerySelectorAll where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> Just (pDOMQuerySelectorAllNodeId p),
+    ("selector" A..=) <$> Just (pDOMQuerySelectorAllSelector p)
+    ]
+data DOMQuerySelectorAll = DOMQuerySelectorAll
+  {
+    -- | Query selector result.
+    dOMQuerySelectorAllNodeIds :: [DOMNodeId]
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMQuerySelectorAll where
+  parseJSON = A.withObject "DOMQuerySelectorAll" $ \o -> DOMQuerySelectorAll
+    <$> o A..: "nodeIds"
+instance Command PDOMQuerySelectorAll where
+  type CommandResponse PDOMQuerySelectorAll = DOMQuerySelectorAll
+  commandName _ = "DOM.querySelectorAll"
+
+-- | Returns NodeIds of current top layer elements.
+--   Top layer is rendered closest to the user within a viewport, therefore its elements always
+--   appear on top of all other content.
+
+-- | Parameters of the 'DOM.getTopLayerElements' command.
+data PDOMGetTopLayerElements = PDOMGetTopLayerElements
+  deriving (Eq, Show)
+pDOMGetTopLayerElements
+  :: PDOMGetTopLayerElements
+pDOMGetTopLayerElements
+  = PDOMGetTopLayerElements
+instance ToJSON PDOMGetTopLayerElements where
+  toJSON _ = A.Null
+data DOMGetTopLayerElements = DOMGetTopLayerElements
+  {
+    -- | NodeIds of top layer elements
+    dOMGetTopLayerElementsNodeIds :: [DOMNodeId]
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMGetTopLayerElements where
+  parseJSON = A.withObject "DOMGetTopLayerElements" $ \o -> DOMGetTopLayerElements
+    <$> o A..: "nodeIds"
+instance Command PDOMGetTopLayerElements where
+  type CommandResponse PDOMGetTopLayerElements = DOMGetTopLayerElements
+  commandName _ = "DOM.getTopLayerElements"
+
+-- | Re-does the last undone action.
+
+-- | Parameters of the 'DOM.redo' command.
+data PDOMRedo = PDOMRedo
+  deriving (Eq, Show)
+pDOMRedo
+  :: PDOMRedo
+pDOMRedo
+  = PDOMRedo
+instance ToJSON PDOMRedo where
+  toJSON _ = A.Null
+instance Command PDOMRedo where
+  type CommandResponse PDOMRedo = ()
+  commandName _ = "DOM.redo"
+  fromJSON = const . A.Success . const ()
+
+-- | Removes attribute with given name from an element with given id.
+
+-- | Parameters of the 'DOM.removeAttribute' command.
+data PDOMRemoveAttribute = PDOMRemoveAttribute
+  {
+    -- | Id of the element to remove attribute from.
+    pDOMRemoveAttributeNodeId :: DOMNodeId,
+    -- | Name of the attribute to remove.
+    pDOMRemoveAttributeName :: T.Text
+  }
+  deriving (Eq, Show)
+pDOMRemoveAttribute
+  {-
+  -- | Id of the element to remove attribute from.
+  -}
+  :: DOMNodeId
+  {-
+  -- | Name of the attribute to remove.
+  -}
+  -> T.Text
+  -> PDOMRemoveAttribute
+pDOMRemoveAttribute
+  arg_pDOMRemoveAttributeNodeId
+  arg_pDOMRemoveAttributeName
+  = PDOMRemoveAttribute
+    arg_pDOMRemoveAttributeNodeId
+    arg_pDOMRemoveAttributeName
+instance ToJSON PDOMRemoveAttribute where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> Just (pDOMRemoveAttributeNodeId p),
+    ("name" A..=) <$> Just (pDOMRemoveAttributeName p)
+    ]
+instance Command PDOMRemoveAttribute where
+  type CommandResponse PDOMRemoveAttribute = ()
+  commandName _ = "DOM.removeAttribute"
+  fromJSON = const . A.Success . const ()
+
+-- | Removes node with given id.
+
+-- | Parameters of the 'DOM.removeNode' command.
+data PDOMRemoveNode = PDOMRemoveNode
+  {
+    -- | Id of the node to remove.
+    pDOMRemoveNodeNodeId :: DOMNodeId
+  }
+  deriving (Eq, Show)
+pDOMRemoveNode
+  {-
+  -- | Id of the node to remove.
+  -}
+  :: DOMNodeId
+  -> PDOMRemoveNode
+pDOMRemoveNode
+  arg_pDOMRemoveNodeNodeId
+  = PDOMRemoveNode
+    arg_pDOMRemoveNodeNodeId
+instance ToJSON PDOMRemoveNode where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> Just (pDOMRemoveNodeNodeId p)
+    ]
+instance Command PDOMRemoveNode where
+  type CommandResponse PDOMRemoveNode = ()
+  commandName _ = "DOM.removeNode"
+  fromJSON = const . A.Success . const ()
+
+-- | Requests that children of the node with given id are returned to the caller in form of
+--   `setChildNodes` events where not only immediate children are retrieved, but all children down to
+--   the specified depth.
+
+-- | Parameters of the 'DOM.requestChildNodes' command.
+data PDOMRequestChildNodes = PDOMRequestChildNodes
+  {
+    -- | Id of the node to get children for.
+    pDOMRequestChildNodesNodeId :: DOMNodeId,
+    -- | The maximum depth at which children should be retrieved, defaults to 1. Use -1 for the
+    --   entire subtree or provide an integer larger than 0.
+    pDOMRequestChildNodesDepth :: Maybe Int,
+    -- | Whether or not iframes and shadow roots should be traversed when returning the sub-tree
+    --   (default is false).
+    pDOMRequestChildNodesPierce :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pDOMRequestChildNodes
+  {-
+  -- | Id of the node to get children for.
+  -}
+  :: DOMNodeId
+  -> PDOMRequestChildNodes
+pDOMRequestChildNodes
+  arg_pDOMRequestChildNodesNodeId
+  = PDOMRequestChildNodes
+    arg_pDOMRequestChildNodesNodeId
+    Nothing
+    Nothing
+instance ToJSON PDOMRequestChildNodes where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> Just (pDOMRequestChildNodesNodeId p),
+    ("depth" A..=) <$> (pDOMRequestChildNodesDepth p),
+    ("pierce" A..=) <$> (pDOMRequestChildNodesPierce p)
+    ]
+instance Command PDOMRequestChildNodes where
+  type CommandResponse PDOMRequestChildNodes = ()
+  commandName _ = "DOM.requestChildNodes"
+  fromJSON = const . A.Success . const ()
+
+-- | Requests that the node is sent to the caller given the JavaScript node object reference. All
+--   nodes that form the path from the node to the root are also sent to the client as a series of
+--   `setChildNodes` notifications.
+
+-- | Parameters of the 'DOM.requestNode' command.
+data PDOMRequestNode = PDOMRequestNode
+  {
+    -- | JavaScript object id to convert into node.
+    pDOMRequestNodeObjectId :: Runtime.RuntimeRemoteObjectId
+  }
+  deriving (Eq, Show)
+pDOMRequestNode
+  {-
+  -- | JavaScript object id to convert into node.
+  -}
+  :: Runtime.RuntimeRemoteObjectId
+  -> PDOMRequestNode
+pDOMRequestNode
+  arg_pDOMRequestNodeObjectId
+  = PDOMRequestNode
+    arg_pDOMRequestNodeObjectId
+instance ToJSON PDOMRequestNode where
+  toJSON p = A.object $ catMaybes [
+    ("objectId" A..=) <$> Just (pDOMRequestNodeObjectId p)
+    ]
+data DOMRequestNode = DOMRequestNode
+  {
+    -- | Node id for given object.
+    dOMRequestNodeNodeId :: DOMNodeId
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMRequestNode where
+  parseJSON = A.withObject "DOMRequestNode" $ \o -> DOMRequestNode
+    <$> o A..: "nodeId"
+instance Command PDOMRequestNode where
+  type CommandResponse PDOMRequestNode = DOMRequestNode
+  commandName _ = "DOM.requestNode"
+
+-- | Resolves the JavaScript node object for a given NodeId or BackendNodeId.
+
+-- | Parameters of the 'DOM.resolveNode' command.
+data PDOMResolveNode = PDOMResolveNode
+  {
+    -- | Id of the node to resolve.
+    pDOMResolveNodeNodeId :: Maybe DOMNodeId,
+    -- | Backend identifier of the node to resolve.
+    pDOMResolveNodeBackendNodeId :: Maybe DOMBackendNodeId,
+    -- | Symbolic group name that can be used to release multiple objects.
+    pDOMResolveNodeObjectGroup :: Maybe T.Text,
+    -- | Execution context in which to resolve the node.
+    pDOMResolveNodeExecutionContextId :: Maybe Runtime.RuntimeExecutionContextId
+  }
+  deriving (Eq, Show)
+pDOMResolveNode
+  :: PDOMResolveNode
+pDOMResolveNode
+  = PDOMResolveNode
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PDOMResolveNode where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> (pDOMResolveNodeNodeId p),
+    ("backendNodeId" A..=) <$> (pDOMResolveNodeBackendNodeId p),
+    ("objectGroup" A..=) <$> (pDOMResolveNodeObjectGroup p),
+    ("executionContextId" A..=) <$> (pDOMResolveNodeExecutionContextId p)
+    ]
+data DOMResolveNode = DOMResolveNode
+  {
+    -- | JavaScript object wrapper for given node.
+    dOMResolveNodeObject :: Runtime.RuntimeRemoteObject
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMResolveNode where
+  parseJSON = A.withObject "DOMResolveNode" $ \o -> DOMResolveNode
+    <$> o A..: "object"
+instance Command PDOMResolveNode where
+  type CommandResponse PDOMResolveNode = DOMResolveNode
+  commandName _ = "DOM.resolveNode"
+
+-- | Sets attribute for an element with given id.
+
+-- | Parameters of the 'DOM.setAttributeValue' command.
+data PDOMSetAttributeValue = PDOMSetAttributeValue
+  {
+    -- | Id of the element to set attribute for.
+    pDOMSetAttributeValueNodeId :: DOMNodeId,
+    -- | Attribute name.
+    pDOMSetAttributeValueName :: T.Text,
+    -- | Attribute value.
+    pDOMSetAttributeValueValue :: T.Text
+  }
+  deriving (Eq, Show)
+pDOMSetAttributeValue
+  {-
+  -- | Id of the element to set attribute for.
+  -}
+  :: DOMNodeId
+  {-
+  -- | Attribute name.
+  -}
+  -> T.Text
+  {-
+  -- | Attribute value.
+  -}
+  -> T.Text
+  -> PDOMSetAttributeValue
+pDOMSetAttributeValue
+  arg_pDOMSetAttributeValueNodeId
+  arg_pDOMSetAttributeValueName
+  arg_pDOMSetAttributeValueValue
+  = PDOMSetAttributeValue
+    arg_pDOMSetAttributeValueNodeId
+    arg_pDOMSetAttributeValueName
+    arg_pDOMSetAttributeValueValue
+instance ToJSON PDOMSetAttributeValue where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> Just (pDOMSetAttributeValueNodeId p),
+    ("name" A..=) <$> Just (pDOMSetAttributeValueName p),
+    ("value" A..=) <$> Just (pDOMSetAttributeValueValue p)
+    ]
+instance Command PDOMSetAttributeValue where
+  type CommandResponse PDOMSetAttributeValue = ()
+  commandName _ = "DOM.setAttributeValue"
+  fromJSON = const . A.Success . const ()
+
+-- | Sets attributes on element with given id. This method is useful when user edits some existing
+--   attribute value and types in several attribute name/value pairs.
+
+-- | Parameters of the 'DOM.setAttributesAsText' command.
+data PDOMSetAttributesAsText = PDOMSetAttributesAsText
+  {
+    -- | Id of the element to set attributes for.
+    pDOMSetAttributesAsTextNodeId :: DOMNodeId,
+    -- | Text with a number of attributes. Will parse this text using HTML parser.
+    pDOMSetAttributesAsTextText :: T.Text,
+    -- | Attribute name to replace with new attributes derived from text in case text parsed
+    --   successfully.
+    pDOMSetAttributesAsTextName :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+pDOMSetAttributesAsText
+  {-
+  -- | Id of the element to set attributes for.
+  -}
+  :: DOMNodeId
+  {-
+  -- | Text with a number of attributes. Will parse this text using HTML parser.
+  -}
+  -> T.Text
+  -> PDOMSetAttributesAsText
+pDOMSetAttributesAsText
+  arg_pDOMSetAttributesAsTextNodeId
+  arg_pDOMSetAttributesAsTextText
+  = PDOMSetAttributesAsText
+    arg_pDOMSetAttributesAsTextNodeId
+    arg_pDOMSetAttributesAsTextText
+    Nothing
+instance ToJSON PDOMSetAttributesAsText where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> Just (pDOMSetAttributesAsTextNodeId p),
+    ("text" A..=) <$> Just (pDOMSetAttributesAsTextText p),
+    ("name" A..=) <$> (pDOMSetAttributesAsTextName p)
+    ]
+instance Command PDOMSetAttributesAsText where
+  type CommandResponse PDOMSetAttributesAsText = ()
+  commandName _ = "DOM.setAttributesAsText"
+  fromJSON = const . A.Success . const ()
+
+-- | Sets files for the given file input element.
+
+-- | Parameters of the 'DOM.setFileInputFiles' command.
+data PDOMSetFileInputFiles = PDOMSetFileInputFiles
+  {
+    -- | Array of file paths to set.
+    pDOMSetFileInputFilesFiles :: [T.Text],
+    -- | Identifier of the node.
+    pDOMSetFileInputFilesNodeId :: Maybe DOMNodeId,
+    -- | Identifier of the backend node.
+    pDOMSetFileInputFilesBackendNodeId :: Maybe DOMBackendNodeId,
+    -- | JavaScript object id of the node wrapper.
+    pDOMSetFileInputFilesObjectId :: Maybe Runtime.RuntimeRemoteObjectId
+  }
+  deriving (Eq, Show)
+pDOMSetFileInputFiles
+  {-
+  -- | Array of file paths to set.
+  -}
+  :: [T.Text]
+  -> PDOMSetFileInputFiles
+pDOMSetFileInputFiles
+  arg_pDOMSetFileInputFilesFiles
+  = PDOMSetFileInputFiles
+    arg_pDOMSetFileInputFilesFiles
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PDOMSetFileInputFiles where
+  toJSON p = A.object $ catMaybes [
+    ("files" A..=) <$> Just (pDOMSetFileInputFilesFiles p),
+    ("nodeId" A..=) <$> (pDOMSetFileInputFilesNodeId p),
+    ("backendNodeId" A..=) <$> (pDOMSetFileInputFilesBackendNodeId p),
+    ("objectId" A..=) <$> (pDOMSetFileInputFilesObjectId p)
+    ]
+instance Command PDOMSetFileInputFiles where
+  type CommandResponse PDOMSetFileInputFiles = ()
+  commandName _ = "DOM.setFileInputFiles"
+  fromJSON = const . A.Success . const ()
+
+-- | Sets if stack traces should be captured for Nodes. See `Node.getNodeStackTraces`. Default is disabled.
+
+-- | Parameters of the 'DOM.setNodeStackTracesEnabled' command.
+data PDOMSetNodeStackTracesEnabled = PDOMSetNodeStackTracesEnabled
+  {
+    -- | Enable or disable.
+    pDOMSetNodeStackTracesEnabledEnable :: Bool
+  }
+  deriving (Eq, Show)
+pDOMSetNodeStackTracesEnabled
+  {-
+  -- | Enable or disable.
+  -}
+  :: Bool
+  -> PDOMSetNodeStackTracesEnabled
+pDOMSetNodeStackTracesEnabled
+  arg_pDOMSetNodeStackTracesEnabledEnable
+  = PDOMSetNodeStackTracesEnabled
+    arg_pDOMSetNodeStackTracesEnabledEnable
+instance ToJSON PDOMSetNodeStackTracesEnabled where
+  toJSON p = A.object $ catMaybes [
+    ("enable" A..=) <$> Just (pDOMSetNodeStackTracesEnabledEnable p)
+    ]
+instance Command PDOMSetNodeStackTracesEnabled where
+  type CommandResponse PDOMSetNodeStackTracesEnabled = ()
+  commandName _ = "DOM.setNodeStackTracesEnabled"
+  fromJSON = const . A.Success . const ()
+
+-- | Gets stack traces associated with a Node. As of now, only provides stack trace for Node creation.
+
+-- | Parameters of the 'DOM.getNodeStackTraces' command.
+data PDOMGetNodeStackTraces = PDOMGetNodeStackTraces
+  {
+    -- | Id of the node to get stack traces for.
+    pDOMGetNodeStackTracesNodeId :: DOMNodeId
+  }
+  deriving (Eq, Show)
+pDOMGetNodeStackTraces
+  {-
+  -- | Id of the node to get stack traces for.
+  -}
+  :: DOMNodeId
+  -> PDOMGetNodeStackTraces
+pDOMGetNodeStackTraces
+  arg_pDOMGetNodeStackTracesNodeId
+  = PDOMGetNodeStackTraces
+    arg_pDOMGetNodeStackTracesNodeId
+instance ToJSON PDOMGetNodeStackTraces where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> Just (pDOMGetNodeStackTracesNodeId p)
+    ]
+data DOMGetNodeStackTraces = DOMGetNodeStackTraces
+  {
+    -- | Creation stack trace, if available.
+    dOMGetNodeStackTracesCreation :: Maybe Runtime.RuntimeStackTrace
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMGetNodeStackTraces where
+  parseJSON = A.withObject "DOMGetNodeStackTraces" $ \o -> DOMGetNodeStackTraces
+    <$> o A..:? "creation"
+instance Command PDOMGetNodeStackTraces where
+  type CommandResponse PDOMGetNodeStackTraces = DOMGetNodeStackTraces
+  commandName _ = "DOM.getNodeStackTraces"
+
+-- | Returns file information for the given
+--   File wrapper.
+
+-- | Parameters of the 'DOM.getFileInfo' command.
+data PDOMGetFileInfo = PDOMGetFileInfo
+  {
+    -- | JavaScript object id of the node wrapper.
+    pDOMGetFileInfoObjectId :: Runtime.RuntimeRemoteObjectId
+  }
+  deriving (Eq, Show)
+pDOMGetFileInfo
+  {-
+  -- | JavaScript object id of the node wrapper.
+  -}
+  :: Runtime.RuntimeRemoteObjectId
+  -> PDOMGetFileInfo
+pDOMGetFileInfo
+  arg_pDOMGetFileInfoObjectId
+  = PDOMGetFileInfo
+    arg_pDOMGetFileInfoObjectId
+instance ToJSON PDOMGetFileInfo where
+  toJSON p = A.object $ catMaybes [
+    ("objectId" A..=) <$> Just (pDOMGetFileInfoObjectId p)
+    ]
+data DOMGetFileInfo = DOMGetFileInfo
+  {
+    dOMGetFileInfoPath :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMGetFileInfo where
+  parseJSON = A.withObject "DOMGetFileInfo" $ \o -> DOMGetFileInfo
+    <$> o A..: "path"
+instance Command PDOMGetFileInfo where
+  type CommandResponse PDOMGetFileInfo = DOMGetFileInfo
+  commandName _ = "DOM.getFileInfo"
+
+-- | Enables console to refer to the node with given id via $x (see Command Line API for more details
+--   $x functions).
+
+-- | Parameters of the 'DOM.setInspectedNode' command.
+data PDOMSetInspectedNode = PDOMSetInspectedNode
+  {
+    -- | DOM node id to be accessible by means of $x command line API.
+    pDOMSetInspectedNodeNodeId :: DOMNodeId
+  }
+  deriving (Eq, Show)
+pDOMSetInspectedNode
+  {-
+  -- | DOM node id to be accessible by means of $x command line API.
+  -}
+  :: DOMNodeId
+  -> PDOMSetInspectedNode
+pDOMSetInspectedNode
+  arg_pDOMSetInspectedNodeNodeId
+  = PDOMSetInspectedNode
+    arg_pDOMSetInspectedNodeNodeId
+instance ToJSON PDOMSetInspectedNode where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> Just (pDOMSetInspectedNodeNodeId p)
+    ]
+instance Command PDOMSetInspectedNode where
+  type CommandResponse PDOMSetInspectedNode = ()
+  commandName _ = "DOM.setInspectedNode"
+  fromJSON = const . A.Success . const ()
+
+-- | Sets node name for a node with given id.
+
+-- | Parameters of the 'DOM.setNodeName' command.
+data PDOMSetNodeName = PDOMSetNodeName
+  {
+    -- | Id of the node to set name for.
+    pDOMSetNodeNameNodeId :: DOMNodeId,
+    -- | New node's name.
+    pDOMSetNodeNameName :: T.Text
+  }
+  deriving (Eq, Show)
+pDOMSetNodeName
+  {-
+  -- | Id of the node to set name for.
+  -}
+  :: DOMNodeId
+  {-
+  -- | New node's name.
+  -}
+  -> T.Text
+  -> PDOMSetNodeName
+pDOMSetNodeName
+  arg_pDOMSetNodeNameNodeId
+  arg_pDOMSetNodeNameName
+  = PDOMSetNodeName
+    arg_pDOMSetNodeNameNodeId
+    arg_pDOMSetNodeNameName
+instance ToJSON PDOMSetNodeName where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> Just (pDOMSetNodeNameNodeId p),
+    ("name" A..=) <$> Just (pDOMSetNodeNameName p)
+    ]
+data DOMSetNodeName = DOMSetNodeName
+  {
+    -- | New node's id.
+    dOMSetNodeNameNodeId :: DOMNodeId
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMSetNodeName where
+  parseJSON = A.withObject "DOMSetNodeName" $ \o -> DOMSetNodeName
+    <$> o A..: "nodeId"
+instance Command PDOMSetNodeName where
+  type CommandResponse PDOMSetNodeName = DOMSetNodeName
+  commandName _ = "DOM.setNodeName"
+
+-- | Sets node value for a node with given id.
+
+-- | Parameters of the 'DOM.setNodeValue' command.
+data PDOMSetNodeValue = PDOMSetNodeValue
+  {
+    -- | Id of the node to set value for.
+    pDOMSetNodeValueNodeId :: DOMNodeId,
+    -- | New node's value.
+    pDOMSetNodeValueValue :: T.Text
+  }
+  deriving (Eq, Show)
+pDOMSetNodeValue
+  {-
+  -- | Id of the node to set value for.
+  -}
+  :: DOMNodeId
+  {-
+  -- | New node's value.
+  -}
+  -> T.Text
+  -> PDOMSetNodeValue
+pDOMSetNodeValue
+  arg_pDOMSetNodeValueNodeId
+  arg_pDOMSetNodeValueValue
+  = PDOMSetNodeValue
+    arg_pDOMSetNodeValueNodeId
+    arg_pDOMSetNodeValueValue
+instance ToJSON PDOMSetNodeValue where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> Just (pDOMSetNodeValueNodeId p),
+    ("value" A..=) <$> Just (pDOMSetNodeValueValue p)
+    ]
+instance Command PDOMSetNodeValue where
+  type CommandResponse PDOMSetNodeValue = ()
+  commandName _ = "DOM.setNodeValue"
+  fromJSON = const . A.Success . const ()
+
+-- | Sets node HTML markup, returns new node id.
+
+-- | Parameters of the 'DOM.setOuterHTML' command.
+data PDOMSetOuterHTML = PDOMSetOuterHTML
+  {
+    -- | Id of the node to set markup for.
+    pDOMSetOuterHTMLNodeId :: DOMNodeId,
+    -- | Outer HTML markup to set.
+    pDOMSetOuterHTMLOuterHTML :: T.Text
+  }
+  deriving (Eq, Show)
+pDOMSetOuterHTML
+  {-
+  -- | Id of the node to set markup for.
+  -}
+  :: DOMNodeId
+  {-
+  -- | Outer HTML markup to set.
+  -}
+  -> T.Text
+  -> PDOMSetOuterHTML
+pDOMSetOuterHTML
+  arg_pDOMSetOuterHTMLNodeId
+  arg_pDOMSetOuterHTMLOuterHTML
+  = PDOMSetOuterHTML
+    arg_pDOMSetOuterHTMLNodeId
+    arg_pDOMSetOuterHTMLOuterHTML
+instance ToJSON PDOMSetOuterHTML where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> Just (pDOMSetOuterHTMLNodeId p),
+    ("outerHTML" A..=) <$> Just (pDOMSetOuterHTMLOuterHTML p)
+    ]
+instance Command PDOMSetOuterHTML where
+  type CommandResponse PDOMSetOuterHTML = ()
+  commandName _ = "DOM.setOuterHTML"
+  fromJSON = const . A.Success . const ()
+
+-- | Undoes the last performed action.
+
+-- | Parameters of the 'DOM.undo' command.
+data PDOMUndo = PDOMUndo
+  deriving (Eq, Show)
+pDOMUndo
+  :: PDOMUndo
+pDOMUndo
+  = PDOMUndo
+instance ToJSON PDOMUndo where
+  toJSON _ = A.Null
+instance Command PDOMUndo where
+  type CommandResponse PDOMUndo = ()
+  commandName _ = "DOM.undo"
+  fromJSON = const . A.Success . const ()
+
+-- | Returns iframe node that owns iframe with the given domain.
+
+-- | Parameters of the 'DOM.getFrameOwner' command.
+data PDOMGetFrameOwner = PDOMGetFrameOwner
+  {
+    pDOMGetFrameOwnerFrameId :: PageFrameId
+  }
+  deriving (Eq, Show)
+pDOMGetFrameOwner
+  :: PageFrameId
+  -> PDOMGetFrameOwner
+pDOMGetFrameOwner
+  arg_pDOMGetFrameOwnerFrameId
+  = PDOMGetFrameOwner
+    arg_pDOMGetFrameOwnerFrameId
+instance ToJSON PDOMGetFrameOwner where
+  toJSON p = A.object $ catMaybes [
+    ("frameId" A..=) <$> Just (pDOMGetFrameOwnerFrameId p)
+    ]
+data DOMGetFrameOwner = DOMGetFrameOwner
+  {
+    -- | Resulting node.
+    dOMGetFrameOwnerBackendNodeId :: DOMBackendNodeId,
+    -- | Id of the node at given coordinates, only when enabled and requested document.
+    dOMGetFrameOwnerNodeId :: Maybe DOMNodeId
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMGetFrameOwner where
+  parseJSON = A.withObject "DOMGetFrameOwner" $ \o -> DOMGetFrameOwner
+    <$> o A..: "backendNodeId"
+    <*> o A..:? "nodeId"
+instance Command PDOMGetFrameOwner where
+  type CommandResponse PDOMGetFrameOwner = DOMGetFrameOwner
+  commandName _ = "DOM.getFrameOwner"
+
+-- | Returns the container of the given node based on container query conditions.
+--   If containerName is given, it will find the nearest container with a matching name;
+--   otherwise it will find the nearest container regardless of its container name.
+
+-- | Parameters of the 'DOM.getContainerForNode' command.
+data PDOMGetContainerForNode = PDOMGetContainerForNode
+  {
+    pDOMGetContainerForNodeNodeId :: DOMNodeId,
+    pDOMGetContainerForNodeContainerName :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+pDOMGetContainerForNode
+  :: DOMNodeId
+  -> PDOMGetContainerForNode
+pDOMGetContainerForNode
+  arg_pDOMGetContainerForNodeNodeId
+  = PDOMGetContainerForNode
+    arg_pDOMGetContainerForNodeNodeId
+    Nothing
+instance ToJSON PDOMGetContainerForNode where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> Just (pDOMGetContainerForNodeNodeId p),
+    ("containerName" A..=) <$> (pDOMGetContainerForNodeContainerName p)
+    ]
+data DOMGetContainerForNode = DOMGetContainerForNode
+  {
+    -- | The container node for the given node, or null if not found.
+    dOMGetContainerForNodeNodeId :: Maybe DOMNodeId
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMGetContainerForNode where
+  parseJSON = A.withObject "DOMGetContainerForNode" $ \o -> DOMGetContainerForNode
+    <$> o A..:? "nodeId"
+instance Command PDOMGetContainerForNode where
+  type CommandResponse PDOMGetContainerForNode = DOMGetContainerForNode
+  commandName _ = "DOM.getContainerForNode"
+
+-- | Returns the descendants of a container query container that have
+--   container queries against this container.
+
+-- | Parameters of the 'DOM.getQueryingDescendantsForContainer' command.
+data PDOMGetQueryingDescendantsForContainer = PDOMGetQueryingDescendantsForContainer
+  {
+    -- | Id of the container node to find querying descendants from.
+    pDOMGetQueryingDescendantsForContainerNodeId :: DOMNodeId
+  }
+  deriving (Eq, Show)
+pDOMGetQueryingDescendantsForContainer
+  {-
+  -- | Id of the container node to find querying descendants from.
+  -}
+  :: DOMNodeId
+  -> PDOMGetQueryingDescendantsForContainer
+pDOMGetQueryingDescendantsForContainer
+  arg_pDOMGetQueryingDescendantsForContainerNodeId
+  = PDOMGetQueryingDescendantsForContainer
+    arg_pDOMGetQueryingDescendantsForContainerNodeId
+instance ToJSON PDOMGetQueryingDescendantsForContainer where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> Just (pDOMGetQueryingDescendantsForContainerNodeId p)
+    ]
+data DOMGetQueryingDescendantsForContainer = DOMGetQueryingDescendantsForContainer
+  {
+    -- | Descendant nodes with container queries against the given container.
+    dOMGetQueryingDescendantsForContainerNodeIds :: [DOMNodeId]
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMGetQueryingDescendantsForContainer where
+  parseJSON = A.withObject "DOMGetQueryingDescendantsForContainer" $ \o -> DOMGetQueryingDescendantsForContainer
+    <$> o A..: "nodeIds"
+instance Command PDOMGetQueryingDescendantsForContainer where
+  type CommandResponse PDOMGetQueryingDescendantsForContainer = DOMGetQueryingDescendantsForContainer
+  commandName _ = "DOM.getQueryingDescendantsForContainer"
+
+-- | Type 'Emulation.ScreenOrientation'.
+--   Screen orientation.
+data EmulationScreenOrientationType = EmulationScreenOrientationTypePortraitPrimary | EmulationScreenOrientationTypePortraitSecondary | EmulationScreenOrientationTypeLandscapePrimary | EmulationScreenOrientationTypeLandscapeSecondary
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON EmulationScreenOrientationType where
+  parseJSON = A.withText "EmulationScreenOrientationType" $ \v -> case v of
+    "portraitPrimary" -> pure EmulationScreenOrientationTypePortraitPrimary
+    "portraitSecondary" -> pure EmulationScreenOrientationTypePortraitSecondary
+    "landscapePrimary" -> pure EmulationScreenOrientationTypeLandscapePrimary
+    "landscapeSecondary" -> pure EmulationScreenOrientationTypeLandscapeSecondary
+    "_" -> fail "failed to parse EmulationScreenOrientationType"
+instance ToJSON EmulationScreenOrientationType where
+  toJSON v = A.String $ case v of
+    EmulationScreenOrientationTypePortraitPrimary -> "portraitPrimary"
+    EmulationScreenOrientationTypePortraitSecondary -> "portraitSecondary"
+    EmulationScreenOrientationTypeLandscapePrimary -> "landscapePrimary"
+    EmulationScreenOrientationTypeLandscapeSecondary -> "landscapeSecondary"
+data EmulationScreenOrientation = EmulationScreenOrientation
+  {
+    -- | Orientation type.
+    emulationScreenOrientationType :: EmulationScreenOrientationType,
+    -- | Orientation angle.
+    emulationScreenOrientationAngle :: Int
+  }
+  deriving (Eq, Show)
+instance FromJSON EmulationScreenOrientation where
+  parseJSON = A.withObject "EmulationScreenOrientation" $ \o -> EmulationScreenOrientation
+    <$> o A..: "type"
+    <*> o A..: "angle"
+instance ToJSON EmulationScreenOrientation where
+  toJSON p = A.object $ catMaybes [
+    ("type" A..=) <$> Just (emulationScreenOrientationType p),
+    ("angle" A..=) <$> Just (emulationScreenOrientationAngle p)
+    ]
+
+-- | Type 'Emulation.DisplayFeature'.
+data EmulationDisplayFeatureOrientation = EmulationDisplayFeatureOrientationVertical | EmulationDisplayFeatureOrientationHorizontal
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON EmulationDisplayFeatureOrientation where
+  parseJSON = A.withText "EmulationDisplayFeatureOrientation" $ \v -> case v of
+    "vertical" -> pure EmulationDisplayFeatureOrientationVertical
+    "horizontal" -> pure EmulationDisplayFeatureOrientationHorizontal
+    "_" -> fail "failed to parse EmulationDisplayFeatureOrientation"
+instance ToJSON EmulationDisplayFeatureOrientation where
+  toJSON v = A.String $ case v of
+    EmulationDisplayFeatureOrientationVertical -> "vertical"
+    EmulationDisplayFeatureOrientationHorizontal -> "horizontal"
+data EmulationDisplayFeature = EmulationDisplayFeature
+  {
+    -- | Orientation of a display feature in relation to screen
+    emulationDisplayFeatureOrientation :: EmulationDisplayFeatureOrientation,
+    -- | The offset from the screen origin in either the x (for vertical
+    --   orientation) or y (for horizontal orientation) direction.
+    emulationDisplayFeatureOffset :: Int,
+    -- | A display feature may mask content such that it is not physically
+    --   displayed - this length along with the offset describes this area.
+    --   A display feature that only splits content will have a 0 mask_length.
+    emulationDisplayFeatureMaskLength :: Int
+  }
+  deriving (Eq, Show)
+instance FromJSON EmulationDisplayFeature where
+  parseJSON = A.withObject "EmulationDisplayFeature" $ \o -> EmulationDisplayFeature
+    <$> o A..: "orientation"
+    <*> o A..: "offset"
+    <*> o A..: "maskLength"
+instance ToJSON EmulationDisplayFeature where
+  toJSON p = A.object $ catMaybes [
+    ("orientation" A..=) <$> Just (emulationDisplayFeatureOrientation p),
+    ("offset" A..=) <$> Just (emulationDisplayFeatureOffset p),
+    ("maskLength" A..=) <$> Just (emulationDisplayFeatureMaskLength p)
+    ]
+
+-- | Type 'Emulation.MediaFeature'.
+data EmulationMediaFeature = EmulationMediaFeature
+  {
+    emulationMediaFeatureName :: T.Text,
+    emulationMediaFeatureValue :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON EmulationMediaFeature where
+  parseJSON = A.withObject "EmulationMediaFeature" $ \o -> EmulationMediaFeature
+    <$> o A..: "name"
+    <*> o A..: "value"
+instance ToJSON EmulationMediaFeature where
+  toJSON p = A.object $ catMaybes [
+    ("name" A..=) <$> Just (emulationMediaFeatureName p),
+    ("value" A..=) <$> Just (emulationMediaFeatureValue p)
+    ]
+
+-- | Type 'Emulation.VirtualTimePolicy'.
+--   advance: If the scheduler runs out of immediate work, the virtual time base may fast forward to
+--   allow the next delayed task (if any) to run; pause: The virtual time base may not advance;
+--   pauseIfNetworkFetchesPending: The virtual time base may not advance if there are any pending
+--   resource fetches.
+data EmulationVirtualTimePolicy = EmulationVirtualTimePolicyAdvance | EmulationVirtualTimePolicyPause | EmulationVirtualTimePolicyPauseIfNetworkFetchesPending
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON EmulationVirtualTimePolicy where
+  parseJSON = A.withText "EmulationVirtualTimePolicy" $ \v -> case v of
+    "advance" -> pure EmulationVirtualTimePolicyAdvance
+    "pause" -> pure EmulationVirtualTimePolicyPause
+    "pauseIfNetworkFetchesPending" -> pure EmulationVirtualTimePolicyPauseIfNetworkFetchesPending
+    "_" -> fail "failed to parse EmulationVirtualTimePolicy"
+instance ToJSON EmulationVirtualTimePolicy where
+  toJSON v = A.String $ case v of
+    EmulationVirtualTimePolicyAdvance -> "advance"
+    EmulationVirtualTimePolicyPause -> "pause"
+    EmulationVirtualTimePolicyPauseIfNetworkFetchesPending -> "pauseIfNetworkFetchesPending"
+
+-- | Type 'Emulation.UserAgentBrandVersion'.
+--   Used to specify User Agent Cient Hints to emulate. See https://wicg.github.io/ua-client-hints
+data EmulationUserAgentBrandVersion = EmulationUserAgentBrandVersion
+  {
+    emulationUserAgentBrandVersionBrand :: T.Text,
+    emulationUserAgentBrandVersionVersion :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON EmulationUserAgentBrandVersion where
+  parseJSON = A.withObject "EmulationUserAgentBrandVersion" $ \o -> EmulationUserAgentBrandVersion
+    <$> o A..: "brand"
+    <*> o A..: "version"
+instance ToJSON EmulationUserAgentBrandVersion where
+  toJSON p = A.object $ catMaybes [
+    ("brand" A..=) <$> Just (emulationUserAgentBrandVersionBrand p),
+    ("version" A..=) <$> Just (emulationUserAgentBrandVersionVersion p)
+    ]
+
+-- | Type 'Emulation.UserAgentMetadata'.
+--   Used to specify User Agent Cient Hints to emulate. See https://wicg.github.io/ua-client-hints
+--   Missing optional values will be filled in by the target with what it would normally use.
+data EmulationUserAgentMetadata = EmulationUserAgentMetadata
+  {
+    emulationUserAgentMetadataBrands :: Maybe [EmulationUserAgentBrandVersion],
+    emulationUserAgentMetadataFullVersionList :: Maybe [EmulationUserAgentBrandVersion],
+    emulationUserAgentMetadataPlatform :: T.Text,
+    emulationUserAgentMetadataPlatformVersion :: T.Text,
+    emulationUserAgentMetadataArchitecture :: T.Text,
+    emulationUserAgentMetadataModel :: T.Text,
+    emulationUserAgentMetadataMobile :: Bool,
+    emulationUserAgentMetadataBitness :: Maybe T.Text,
+    emulationUserAgentMetadataWow64 :: Maybe Bool
+  }
+  deriving (Eq, Show)
+instance FromJSON EmulationUserAgentMetadata where
+  parseJSON = A.withObject "EmulationUserAgentMetadata" $ \o -> EmulationUserAgentMetadata
+    <$> o A..:? "brands"
+    <*> o A..:? "fullVersionList"
+    <*> o A..: "platform"
+    <*> o A..: "platformVersion"
+    <*> o A..: "architecture"
+    <*> o A..: "model"
+    <*> o A..: "mobile"
+    <*> o A..:? "bitness"
+    <*> o A..:? "wow64"
+instance ToJSON EmulationUserAgentMetadata where
+  toJSON p = A.object $ catMaybes [
+    ("brands" A..=) <$> (emulationUserAgentMetadataBrands p),
+    ("fullVersionList" A..=) <$> (emulationUserAgentMetadataFullVersionList p),
+    ("platform" A..=) <$> Just (emulationUserAgentMetadataPlatform p),
+    ("platformVersion" A..=) <$> Just (emulationUserAgentMetadataPlatformVersion p),
+    ("architecture" A..=) <$> Just (emulationUserAgentMetadataArchitecture p),
+    ("model" A..=) <$> Just (emulationUserAgentMetadataModel p),
+    ("mobile" A..=) <$> Just (emulationUserAgentMetadataMobile p),
+    ("bitness" A..=) <$> (emulationUserAgentMetadataBitness p),
+    ("wow64" A..=) <$> (emulationUserAgentMetadataWow64 p)
+    ]
+
+-- | Type 'Emulation.DisabledImageType'.
+--   Enum of image types that can be disabled.
+data EmulationDisabledImageType = EmulationDisabledImageTypeAvif | EmulationDisabledImageTypeJxl | EmulationDisabledImageTypeWebp
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON EmulationDisabledImageType where
+  parseJSON = A.withText "EmulationDisabledImageType" $ \v -> case v of
+    "avif" -> pure EmulationDisabledImageTypeAvif
+    "jxl" -> pure EmulationDisabledImageTypeJxl
+    "webp" -> pure EmulationDisabledImageTypeWebp
+    "_" -> fail "failed to parse EmulationDisabledImageType"
+instance ToJSON EmulationDisabledImageType where
+  toJSON v = A.String $ case v of
+    EmulationDisabledImageTypeAvif -> "avif"
+    EmulationDisabledImageTypeJxl -> "jxl"
+    EmulationDisabledImageTypeWebp -> "webp"
+
+-- | Type of the 'Emulation.virtualTimeBudgetExpired' event.
+data EmulationVirtualTimeBudgetExpired = EmulationVirtualTimeBudgetExpired
+  deriving (Eq, Show, Read)
+instance FromJSON EmulationVirtualTimeBudgetExpired where
+  parseJSON _ = pure EmulationVirtualTimeBudgetExpired
+instance Event EmulationVirtualTimeBudgetExpired where
+  eventName _ = "Emulation.virtualTimeBudgetExpired"
+
+-- | Tells whether emulation is supported.
+
+-- | Parameters of the 'Emulation.canEmulate' command.
+data PEmulationCanEmulate = PEmulationCanEmulate
+  deriving (Eq, Show)
+pEmulationCanEmulate
+  :: PEmulationCanEmulate
+pEmulationCanEmulate
+  = PEmulationCanEmulate
+instance ToJSON PEmulationCanEmulate where
+  toJSON _ = A.Null
+data EmulationCanEmulate = EmulationCanEmulate
+  {
+    -- | True if emulation is supported.
+    emulationCanEmulateResult :: Bool
+  }
+  deriving (Eq, Show)
+instance FromJSON EmulationCanEmulate where
+  parseJSON = A.withObject "EmulationCanEmulate" $ \o -> EmulationCanEmulate
+    <$> o A..: "result"
+instance Command PEmulationCanEmulate where
+  type CommandResponse PEmulationCanEmulate = EmulationCanEmulate
+  commandName _ = "Emulation.canEmulate"
+
+-- | Clears the overridden device metrics.
+
+-- | Parameters of the 'Emulation.clearDeviceMetricsOverride' command.
+data PEmulationClearDeviceMetricsOverride = PEmulationClearDeviceMetricsOverride
+  deriving (Eq, Show)
+pEmulationClearDeviceMetricsOverride
+  :: PEmulationClearDeviceMetricsOverride
+pEmulationClearDeviceMetricsOverride
+  = PEmulationClearDeviceMetricsOverride
+instance ToJSON PEmulationClearDeviceMetricsOverride where
+  toJSON _ = A.Null
+instance Command PEmulationClearDeviceMetricsOverride where
+  type CommandResponse PEmulationClearDeviceMetricsOverride = ()
+  commandName _ = "Emulation.clearDeviceMetricsOverride"
+  fromJSON = const . A.Success . const ()
+
+-- | Clears the overridden Geolocation Position and Error.
+
+-- | Parameters of the 'Emulation.clearGeolocationOverride' command.
+data PEmulationClearGeolocationOverride = PEmulationClearGeolocationOverride
+  deriving (Eq, Show)
+pEmulationClearGeolocationOverride
+  :: PEmulationClearGeolocationOverride
+pEmulationClearGeolocationOverride
+  = PEmulationClearGeolocationOverride
+instance ToJSON PEmulationClearGeolocationOverride where
+  toJSON _ = A.Null
+instance Command PEmulationClearGeolocationOverride where
+  type CommandResponse PEmulationClearGeolocationOverride = ()
+  commandName _ = "Emulation.clearGeolocationOverride"
+  fromJSON = const . A.Success . const ()
+
+-- | Requests that page scale factor is reset to initial values.
+
+-- | Parameters of the 'Emulation.resetPageScaleFactor' command.
+data PEmulationResetPageScaleFactor = PEmulationResetPageScaleFactor
+  deriving (Eq, Show)
+pEmulationResetPageScaleFactor
+  :: PEmulationResetPageScaleFactor
+pEmulationResetPageScaleFactor
+  = PEmulationResetPageScaleFactor
+instance ToJSON PEmulationResetPageScaleFactor where
+  toJSON _ = A.Null
+instance Command PEmulationResetPageScaleFactor where
+  type CommandResponse PEmulationResetPageScaleFactor = ()
+  commandName _ = "Emulation.resetPageScaleFactor"
+  fromJSON = const . A.Success . const ()
+
+-- | Enables or disables simulating a focused and active page.
+
+-- | Parameters of the 'Emulation.setFocusEmulationEnabled' command.
+data PEmulationSetFocusEmulationEnabled = PEmulationSetFocusEmulationEnabled
+  {
+    -- | Whether to enable to disable focus emulation.
+    pEmulationSetFocusEmulationEnabledEnabled :: Bool
+  }
+  deriving (Eq, Show)
+pEmulationSetFocusEmulationEnabled
+  {-
+  -- | Whether to enable to disable focus emulation.
+  -}
+  :: Bool
+  -> PEmulationSetFocusEmulationEnabled
+pEmulationSetFocusEmulationEnabled
+  arg_pEmulationSetFocusEmulationEnabledEnabled
+  = PEmulationSetFocusEmulationEnabled
+    arg_pEmulationSetFocusEmulationEnabledEnabled
+instance ToJSON PEmulationSetFocusEmulationEnabled where
+  toJSON p = A.object $ catMaybes [
+    ("enabled" A..=) <$> Just (pEmulationSetFocusEmulationEnabledEnabled p)
+    ]
+instance Command PEmulationSetFocusEmulationEnabled where
+  type CommandResponse PEmulationSetFocusEmulationEnabled = ()
+  commandName _ = "Emulation.setFocusEmulationEnabled"
+  fromJSON = const . A.Success . const ()
+
+-- | Automatically render all web contents using a dark theme.
+
+-- | Parameters of the 'Emulation.setAutoDarkModeOverride' command.
+data PEmulationSetAutoDarkModeOverride = PEmulationSetAutoDarkModeOverride
+  {
+    -- | Whether to enable or disable automatic dark mode.
+    --   If not specified, any existing override will be cleared.
+    pEmulationSetAutoDarkModeOverrideEnabled :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pEmulationSetAutoDarkModeOverride
+  :: PEmulationSetAutoDarkModeOverride
+pEmulationSetAutoDarkModeOverride
+  = PEmulationSetAutoDarkModeOverride
+    Nothing
+instance ToJSON PEmulationSetAutoDarkModeOverride where
+  toJSON p = A.object $ catMaybes [
+    ("enabled" A..=) <$> (pEmulationSetAutoDarkModeOverrideEnabled p)
+    ]
+instance Command PEmulationSetAutoDarkModeOverride where
+  type CommandResponse PEmulationSetAutoDarkModeOverride = ()
+  commandName _ = "Emulation.setAutoDarkModeOverride"
+  fromJSON = const . A.Success . const ()
+
+-- | Enables CPU throttling to emulate slow CPUs.
+
+-- | Parameters of the 'Emulation.setCPUThrottlingRate' command.
+data PEmulationSetCPUThrottlingRate = PEmulationSetCPUThrottlingRate
+  {
+    -- | Throttling rate as a slowdown factor (1 is no throttle, 2 is 2x slowdown, etc).
+    pEmulationSetCPUThrottlingRateRate :: Double
+  }
+  deriving (Eq, Show)
+pEmulationSetCPUThrottlingRate
+  {-
+  -- | Throttling rate as a slowdown factor (1 is no throttle, 2 is 2x slowdown, etc).
+  -}
+  :: Double
+  -> PEmulationSetCPUThrottlingRate
+pEmulationSetCPUThrottlingRate
+  arg_pEmulationSetCPUThrottlingRateRate
+  = PEmulationSetCPUThrottlingRate
+    arg_pEmulationSetCPUThrottlingRateRate
+instance ToJSON PEmulationSetCPUThrottlingRate where
+  toJSON p = A.object $ catMaybes [
+    ("rate" A..=) <$> Just (pEmulationSetCPUThrottlingRateRate p)
+    ]
+instance Command PEmulationSetCPUThrottlingRate where
+  type CommandResponse PEmulationSetCPUThrottlingRate = ()
+  commandName _ = "Emulation.setCPUThrottlingRate"
+  fromJSON = const . A.Success . const ()
+
+-- | Sets or clears an override of the default background color of the frame. This override is used
+--   if the content does not specify one.
+
+-- | Parameters of the 'Emulation.setDefaultBackgroundColorOverride' command.
+data PEmulationSetDefaultBackgroundColorOverride = PEmulationSetDefaultBackgroundColorOverride
+  {
+    -- | RGBA of the default background color. If not specified, any existing override will be
+    --   cleared.
+    pEmulationSetDefaultBackgroundColorOverrideColor :: Maybe DOMRGBA
+  }
+  deriving (Eq, Show)
+pEmulationSetDefaultBackgroundColorOverride
+  :: PEmulationSetDefaultBackgroundColorOverride
+pEmulationSetDefaultBackgroundColorOverride
+  = PEmulationSetDefaultBackgroundColorOverride
+    Nothing
+instance ToJSON PEmulationSetDefaultBackgroundColorOverride where
+  toJSON p = A.object $ catMaybes [
+    ("color" A..=) <$> (pEmulationSetDefaultBackgroundColorOverrideColor p)
+    ]
+instance Command PEmulationSetDefaultBackgroundColorOverride where
+  type CommandResponse PEmulationSetDefaultBackgroundColorOverride = ()
+  commandName _ = "Emulation.setDefaultBackgroundColorOverride"
+  fromJSON = const . A.Success . const ()
+
+-- | Overrides the values of device screen dimensions (window.screen.width, window.screen.height,
+--   window.innerWidth, window.innerHeight, and "device-width"/"device-height"-related CSS media
+--   query results).
+
+-- | Parameters of the 'Emulation.setDeviceMetricsOverride' command.
+data PEmulationSetDeviceMetricsOverride = PEmulationSetDeviceMetricsOverride
+  {
+    -- | Overriding width value in pixels (minimum 0, maximum 10000000). 0 disables the override.
+    pEmulationSetDeviceMetricsOverrideWidth :: Int,
+    -- | Overriding height value in pixels (minimum 0, maximum 10000000). 0 disables the override.
+    pEmulationSetDeviceMetricsOverrideHeight :: Int,
+    -- | Overriding device scale factor value. 0 disables the override.
+    pEmulationSetDeviceMetricsOverrideDeviceScaleFactor :: Double,
+    -- | Whether to emulate mobile device. This includes viewport meta tag, overlay scrollbars, text
+    --   autosizing and more.
+    pEmulationSetDeviceMetricsOverrideMobile :: Bool,
+    -- | Scale to apply to resulting view image.
+    pEmulationSetDeviceMetricsOverrideScale :: Maybe Double,
+    -- | Overriding screen width value in pixels (minimum 0, maximum 10000000).
+    pEmulationSetDeviceMetricsOverrideScreenWidth :: Maybe Int,
+    -- | Overriding screen height value in pixels (minimum 0, maximum 10000000).
+    pEmulationSetDeviceMetricsOverrideScreenHeight :: Maybe Int,
+    -- | Overriding view X position on screen in pixels (minimum 0, maximum 10000000).
+    pEmulationSetDeviceMetricsOverridePositionX :: Maybe Int,
+    -- | Overriding view Y position on screen in pixels (minimum 0, maximum 10000000).
+    pEmulationSetDeviceMetricsOverridePositionY :: Maybe Int,
+    -- | Do not set visible view size, rely upon explicit setVisibleSize call.
+    pEmulationSetDeviceMetricsOverrideDontSetVisibleSize :: Maybe Bool,
+    -- | Screen orientation override.
+    pEmulationSetDeviceMetricsOverrideScreenOrientation :: Maybe EmulationScreenOrientation,
+    -- | If set, the visible area of the page will be overridden to this viewport. This viewport
+    --   change is not observed by the page, e.g. viewport-relative elements do not change positions.
+    pEmulationSetDeviceMetricsOverrideViewport :: Maybe PageViewport,
+    -- | If set, the display feature of a multi-segment screen. If not set, multi-segment support
+    --   is turned-off.
+    pEmulationSetDeviceMetricsOverrideDisplayFeature :: Maybe EmulationDisplayFeature
+  }
+  deriving (Eq, Show)
+pEmulationSetDeviceMetricsOverride
+  {-
+  -- | Overriding width value in pixels (minimum 0, maximum 10000000). 0 disables the override.
+  -}
+  :: Int
+  {-
+  -- | Overriding height value in pixels (minimum 0, maximum 10000000). 0 disables the override.
+  -}
+  -> Int
+  {-
+  -- | Overriding device scale factor value. 0 disables the override.
+  -}
+  -> Double
+  {-
+  -- | Whether to emulate mobile device. This includes viewport meta tag, overlay scrollbars, text
+  --   autosizing and more.
+  -}
+  -> Bool
+  -> PEmulationSetDeviceMetricsOverride
+pEmulationSetDeviceMetricsOverride
+  arg_pEmulationSetDeviceMetricsOverrideWidth
+  arg_pEmulationSetDeviceMetricsOverrideHeight
+  arg_pEmulationSetDeviceMetricsOverrideDeviceScaleFactor
+  arg_pEmulationSetDeviceMetricsOverrideMobile
+  = PEmulationSetDeviceMetricsOverride
+    arg_pEmulationSetDeviceMetricsOverrideWidth
+    arg_pEmulationSetDeviceMetricsOverrideHeight
+    arg_pEmulationSetDeviceMetricsOverrideDeviceScaleFactor
+    arg_pEmulationSetDeviceMetricsOverrideMobile
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PEmulationSetDeviceMetricsOverride where
+  toJSON p = A.object $ catMaybes [
+    ("width" A..=) <$> Just (pEmulationSetDeviceMetricsOverrideWidth p),
+    ("height" A..=) <$> Just (pEmulationSetDeviceMetricsOverrideHeight p),
+    ("deviceScaleFactor" A..=) <$> Just (pEmulationSetDeviceMetricsOverrideDeviceScaleFactor p),
+    ("mobile" A..=) <$> Just (pEmulationSetDeviceMetricsOverrideMobile p),
+    ("scale" A..=) <$> (pEmulationSetDeviceMetricsOverrideScale p),
+    ("screenWidth" A..=) <$> (pEmulationSetDeviceMetricsOverrideScreenWidth p),
+    ("screenHeight" A..=) <$> (pEmulationSetDeviceMetricsOverrideScreenHeight p),
+    ("positionX" A..=) <$> (pEmulationSetDeviceMetricsOverridePositionX p),
+    ("positionY" A..=) <$> (pEmulationSetDeviceMetricsOverridePositionY p),
+    ("dontSetVisibleSize" A..=) <$> (pEmulationSetDeviceMetricsOverrideDontSetVisibleSize p),
+    ("screenOrientation" A..=) <$> (pEmulationSetDeviceMetricsOverrideScreenOrientation p),
+    ("viewport" A..=) <$> (pEmulationSetDeviceMetricsOverrideViewport p),
+    ("displayFeature" A..=) <$> (pEmulationSetDeviceMetricsOverrideDisplayFeature p)
+    ]
+instance Command PEmulationSetDeviceMetricsOverride where
+  type CommandResponse PEmulationSetDeviceMetricsOverride = ()
+  commandName _ = "Emulation.setDeviceMetricsOverride"
+  fromJSON = const . A.Success . const ()
+
+
+-- | Parameters of the 'Emulation.setScrollbarsHidden' command.
+data PEmulationSetScrollbarsHidden = PEmulationSetScrollbarsHidden
+  {
+    -- | Whether scrollbars should be always hidden.
+    pEmulationSetScrollbarsHiddenHidden :: Bool
+  }
+  deriving (Eq, Show)
+pEmulationSetScrollbarsHidden
+  {-
+  -- | Whether scrollbars should be always hidden.
+  -}
+  :: Bool
+  -> PEmulationSetScrollbarsHidden
+pEmulationSetScrollbarsHidden
+  arg_pEmulationSetScrollbarsHiddenHidden
+  = PEmulationSetScrollbarsHidden
+    arg_pEmulationSetScrollbarsHiddenHidden
+instance ToJSON PEmulationSetScrollbarsHidden where
+  toJSON p = A.object $ catMaybes [
+    ("hidden" A..=) <$> Just (pEmulationSetScrollbarsHiddenHidden p)
+    ]
+instance Command PEmulationSetScrollbarsHidden where
+  type CommandResponse PEmulationSetScrollbarsHidden = ()
+  commandName _ = "Emulation.setScrollbarsHidden"
+  fromJSON = const . A.Success . const ()
+
+
+-- | Parameters of the 'Emulation.setDocumentCookieDisabled' command.
+data PEmulationSetDocumentCookieDisabled = PEmulationSetDocumentCookieDisabled
+  {
+    -- | Whether document.coookie API should be disabled.
+    pEmulationSetDocumentCookieDisabledDisabled :: Bool
+  }
+  deriving (Eq, Show)
+pEmulationSetDocumentCookieDisabled
+  {-
+  -- | Whether document.coookie API should be disabled.
+  -}
+  :: Bool
+  -> PEmulationSetDocumentCookieDisabled
+pEmulationSetDocumentCookieDisabled
+  arg_pEmulationSetDocumentCookieDisabledDisabled
+  = PEmulationSetDocumentCookieDisabled
+    arg_pEmulationSetDocumentCookieDisabledDisabled
+instance ToJSON PEmulationSetDocumentCookieDisabled where
+  toJSON p = A.object $ catMaybes [
+    ("disabled" A..=) <$> Just (pEmulationSetDocumentCookieDisabledDisabled p)
+    ]
+instance Command PEmulationSetDocumentCookieDisabled where
+  type CommandResponse PEmulationSetDocumentCookieDisabled = ()
+  commandName _ = "Emulation.setDocumentCookieDisabled"
+  fromJSON = const . A.Success . const ()
+
+
+-- | Parameters of the 'Emulation.setEmitTouchEventsForMouse' command.
+data PEmulationSetEmitTouchEventsForMouseConfiguration = PEmulationSetEmitTouchEventsForMouseConfigurationMobile | PEmulationSetEmitTouchEventsForMouseConfigurationDesktop
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PEmulationSetEmitTouchEventsForMouseConfiguration where
+  parseJSON = A.withText "PEmulationSetEmitTouchEventsForMouseConfiguration" $ \v -> case v of
+    "mobile" -> pure PEmulationSetEmitTouchEventsForMouseConfigurationMobile
+    "desktop" -> pure PEmulationSetEmitTouchEventsForMouseConfigurationDesktop
+    "_" -> fail "failed to parse PEmulationSetEmitTouchEventsForMouseConfiguration"
+instance ToJSON PEmulationSetEmitTouchEventsForMouseConfiguration where
+  toJSON v = A.String $ case v of
+    PEmulationSetEmitTouchEventsForMouseConfigurationMobile -> "mobile"
+    PEmulationSetEmitTouchEventsForMouseConfigurationDesktop -> "desktop"
+data PEmulationSetEmitTouchEventsForMouse = PEmulationSetEmitTouchEventsForMouse
+  {
+    -- | Whether touch emulation based on mouse input should be enabled.
+    pEmulationSetEmitTouchEventsForMouseEnabled :: Bool,
+    -- | Touch/gesture events configuration. Default: current platform.
+    pEmulationSetEmitTouchEventsForMouseConfiguration :: Maybe PEmulationSetEmitTouchEventsForMouseConfiguration
+  }
+  deriving (Eq, Show)
+pEmulationSetEmitTouchEventsForMouse
+  {-
+  -- | Whether touch emulation based on mouse input should be enabled.
+  -}
+  :: Bool
+  -> PEmulationSetEmitTouchEventsForMouse
+pEmulationSetEmitTouchEventsForMouse
+  arg_pEmulationSetEmitTouchEventsForMouseEnabled
+  = PEmulationSetEmitTouchEventsForMouse
+    arg_pEmulationSetEmitTouchEventsForMouseEnabled
+    Nothing
+instance ToJSON PEmulationSetEmitTouchEventsForMouse where
+  toJSON p = A.object $ catMaybes [
+    ("enabled" A..=) <$> Just (pEmulationSetEmitTouchEventsForMouseEnabled p),
+    ("configuration" A..=) <$> (pEmulationSetEmitTouchEventsForMouseConfiguration p)
+    ]
+instance Command PEmulationSetEmitTouchEventsForMouse where
+  type CommandResponse PEmulationSetEmitTouchEventsForMouse = ()
+  commandName _ = "Emulation.setEmitTouchEventsForMouse"
+  fromJSON = const . A.Success . const ()
+
+-- | Emulates the given media type or media feature for CSS media queries.
+
+-- | Parameters of the 'Emulation.setEmulatedMedia' command.
+data PEmulationSetEmulatedMedia = PEmulationSetEmulatedMedia
+  {
+    -- | Media type to emulate. Empty string disables the override.
+    pEmulationSetEmulatedMediaMedia :: Maybe T.Text,
+    -- | Media features to emulate.
+    pEmulationSetEmulatedMediaFeatures :: Maybe [EmulationMediaFeature]
+  }
+  deriving (Eq, Show)
+pEmulationSetEmulatedMedia
+  :: PEmulationSetEmulatedMedia
+pEmulationSetEmulatedMedia
+  = PEmulationSetEmulatedMedia
+    Nothing
+    Nothing
+instance ToJSON PEmulationSetEmulatedMedia where
+  toJSON p = A.object $ catMaybes [
+    ("media" A..=) <$> (pEmulationSetEmulatedMediaMedia p),
+    ("features" A..=) <$> (pEmulationSetEmulatedMediaFeatures p)
+    ]
+instance Command PEmulationSetEmulatedMedia where
+  type CommandResponse PEmulationSetEmulatedMedia = ()
+  commandName _ = "Emulation.setEmulatedMedia"
+  fromJSON = const . A.Success . const ()
+
+-- | Emulates the given vision deficiency.
+
+-- | Parameters of the 'Emulation.setEmulatedVisionDeficiency' command.
+data PEmulationSetEmulatedVisionDeficiencyType = PEmulationSetEmulatedVisionDeficiencyTypeNone | PEmulationSetEmulatedVisionDeficiencyTypeAchromatopsia | PEmulationSetEmulatedVisionDeficiencyTypeBlurredVision | PEmulationSetEmulatedVisionDeficiencyTypeDeuteranopia | PEmulationSetEmulatedVisionDeficiencyTypeProtanopia | PEmulationSetEmulatedVisionDeficiencyTypeTritanopia
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PEmulationSetEmulatedVisionDeficiencyType where
+  parseJSON = A.withText "PEmulationSetEmulatedVisionDeficiencyType" $ \v -> case v of
+    "none" -> pure PEmulationSetEmulatedVisionDeficiencyTypeNone
+    "achromatopsia" -> pure PEmulationSetEmulatedVisionDeficiencyTypeAchromatopsia
+    "blurredVision" -> pure PEmulationSetEmulatedVisionDeficiencyTypeBlurredVision
+    "deuteranopia" -> pure PEmulationSetEmulatedVisionDeficiencyTypeDeuteranopia
+    "protanopia" -> pure PEmulationSetEmulatedVisionDeficiencyTypeProtanopia
+    "tritanopia" -> pure PEmulationSetEmulatedVisionDeficiencyTypeTritanopia
+    "_" -> fail "failed to parse PEmulationSetEmulatedVisionDeficiencyType"
+instance ToJSON PEmulationSetEmulatedVisionDeficiencyType where
+  toJSON v = A.String $ case v of
+    PEmulationSetEmulatedVisionDeficiencyTypeNone -> "none"
+    PEmulationSetEmulatedVisionDeficiencyTypeAchromatopsia -> "achromatopsia"
+    PEmulationSetEmulatedVisionDeficiencyTypeBlurredVision -> "blurredVision"
+    PEmulationSetEmulatedVisionDeficiencyTypeDeuteranopia -> "deuteranopia"
+    PEmulationSetEmulatedVisionDeficiencyTypeProtanopia -> "protanopia"
+    PEmulationSetEmulatedVisionDeficiencyTypeTritanopia -> "tritanopia"
+data PEmulationSetEmulatedVisionDeficiency = PEmulationSetEmulatedVisionDeficiency
+  {
+    -- | Vision deficiency to emulate.
+    pEmulationSetEmulatedVisionDeficiencyType :: PEmulationSetEmulatedVisionDeficiencyType
+  }
+  deriving (Eq, Show)
+pEmulationSetEmulatedVisionDeficiency
+  {-
+  -- | Vision deficiency to emulate.
+  -}
+  :: PEmulationSetEmulatedVisionDeficiencyType
+  -> PEmulationSetEmulatedVisionDeficiency
+pEmulationSetEmulatedVisionDeficiency
+  arg_pEmulationSetEmulatedVisionDeficiencyType
+  = PEmulationSetEmulatedVisionDeficiency
+    arg_pEmulationSetEmulatedVisionDeficiencyType
+instance ToJSON PEmulationSetEmulatedVisionDeficiency where
+  toJSON p = A.object $ catMaybes [
+    ("type" A..=) <$> Just (pEmulationSetEmulatedVisionDeficiencyType p)
+    ]
+instance Command PEmulationSetEmulatedVisionDeficiency where
+  type CommandResponse PEmulationSetEmulatedVisionDeficiency = ()
+  commandName _ = "Emulation.setEmulatedVisionDeficiency"
+  fromJSON = const . A.Success . const ()
+
+-- | Overrides the Geolocation Position or Error. Omitting any of the parameters emulates position
+--   unavailable.
+
+-- | Parameters of the 'Emulation.setGeolocationOverride' command.
+data PEmulationSetGeolocationOverride = PEmulationSetGeolocationOverride
+  {
+    -- | Mock latitude
+    pEmulationSetGeolocationOverrideLatitude :: Maybe Double,
+    -- | Mock longitude
+    pEmulationSetGeolocationOverrideLongitude :: Maybe Double,
+    -- | Mock accuracy
+    pEmulationSetGeolocationOverrideAccuracy :: Maybe Double
+  }
+  deriving (Eq, Show)
+pEmulationSetGeolocationOverride
+  :: PEmulationSetGeolocationOverride
+pEmulationSetGeolocationOverride
+  = PEmulationSetGeolocationOverride
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PEmulationSetGeolocationOverride where
+  toJSON p = A.object $ catMaybes [
+    ("latitude" A..=) <$> (pEmulationSetGeolocationOverrideLatitude p),
+    ("longitude" A..=) <$> (pEmulationSetGeolocationOverrideLongitude p),
+    ("accuracy" A..=) <$> (pEmulationSetGeolocationOverrideAccuracy p)
+    ]
+instance Command PEmulationSetGeolocationOverride where
+  type CommandResponse PEmulationSetGeolocationOverride = ()
+  commandName _ = "Emulation.setGeolocationOverride"
+  fromJSON = const . A.Success . const ()
+
+-- | Overrides the Idle state.
+
+-- | Parameters of the 'Emulation.setIdleOverride' command.
+data PEmulationSetIdleOverride = PEmulationSetIdleOverride
+  {
+    -- | Mock isUserActive
+    pEmulationSetIdleOverrideIsUserActive :: Bool,
+    -- | Mock isScreenUnlocked
+    pEmulationSetIdleOverrideIsScreenUnlocked :: Bool
+  }
+  deriving (Eq, Show)
+pEmulationSetIdleOverride
+  {-
+  -- | Mock isUserActive
+  -}
+  :: Bool
+  {-
+  -- | Mock isScreenUnlocked
+  -}
+  -> Bool
+  -> PEmulationSetIdleOverride
+pEmulationSetIdleOverride
+  arg_pEmulationSetIdleOverrideIsUserActive
+  arg_pEmulationSetIdleOverrideIsScreenUnlocked
+  = PEmulationSetIdleOverride
+    arg_pEmulationSetIdleOverrideIsUserActive
+    arg_pEmulationSetIdleOverrideIsScreenUnlocked
+instance ToJSON PEmulationSetIdleOverride where
+  toJSON p = A.object $ catMaybes [
+    ("isUserActive" A..=) <$> Just (pEmulationSetIdleOverrideIsUserActive p),
+    ("isScreenUnlocked" A..=) <$> Just (pEmulationSetIdleOverrideIsScreenUnlocked p)
+    ]
+instance Command PEmulationSetIdleOverride where
+  type CommandResponse PEmulationSetIdleOverride = ()
+  commandName _ = "Emulation.setIdleOverride"
+  fromJSON = const . A.Success . const ()
+
+-- | Clears Idle state overrides.
+
+-- | Parameters of the 'Emulation.clearIdleOverride' command.
+data PEmulationClearIdleOverride = PEmulationClearIdleOverride
+  deriving (Eq, Show)
+pEmulationClearIdleOverride
+  :: PEmulationClearIdleOverride
+pEmulationClearIdleOverride
+  = PEmulationClearIdleOverride
+instance ToJSON PEmulationClearIdleOverride where
+  toJSON _ = A.Null
+instance Command PEmulationClearIdleOverride where
+  type CommandResponse PEmulationClearIdleOverride = ()
+  commandName _ = "Emulation.clearIdleOverride"
+  fromJSON = const . A.Success . const ()
+
+-- | Sets a specified page scale factor.
+
+-- | Parameters of the 'Emulation.setPageScaleFactor' command.
+data PEmulationSetPageScaleFactor = PEmulationSetPageScaleFactor
+  {
+    -- | Page scale factor.
+    pEmulationSetPageScaleFactorPageScaleFactor :: Double
+  }
+  deriving (Eq, Show)
+pEmulationSetPageScaleFactor
+  {-
+  -- | Page scale factor.
+  -}
+  :: Double
+  -> PEmulationSetPageScaleFactor
+pEmulationSetPageScaleFactor
+  arg_pEmulationSetPageScaleFactorPageScaleFactor
+  = PEmulationSetPageScaleFactor
+    arg_pEmulationSetPageScaleFactorPageScaleFactor
+instance ToJSON PEmulationSetPageScaleFactor where
+  toJSON p = A.object $ catMaybes [
+    ("pageScaleFactor" A..=) <$> Just (pEmulationSetPageScaleFactorPageScaleFactor p)
+    ]
+instance Command PEmulationSetPageScaleFactor where
+  type CommandResponse PEmulationSetPageScaleFactor = ()
+  commandName _ = "Emulation.setPageScaleFactor"
+  fromJSON = const . A.Success . const ()
+
+-- | Switches script execution in the page.
+
+-- | Parameters of the 'Emulation.setScriptExecutionDisabled' command.
+data PEmulationSetScriptExecutionDisabled = PEmulationSetScriptExecutionDisabled
+  {
+    -- | Whether script execution should be disabled in the page.
+    pEmulationSetScriptExecutionDisabledValue :: Bool
+  }
+  deriving (Eq, Show)
+pEmulationSetScriptExecutionDisabled
+  {-
+  -- | Whether script execution should be disabled in the page.
+  -}
+  :: Bool
+  -> PEmulationSetScriptExecutionDisabled
+pEmulationSetScriptExecutionDisabled
+  arg_pEmulationSetScriptExecutionDisabledValue
+  = PEmulationSetScriptExecutionDisabled
+    arg_pEmulationSetScriptExecutionDisabledValue
+instance ToJSON PEmulationSetScriptExecutionDisabled where
+  toJSON p = A.object $ catMaybes [
+    ("value" A..=) <$> Just (pEmulationSetScriptExecutionDisabledValue p)
+    ]
+instance Command PEmulationSetScriptExecutionDisabled where
+  type CommandResponse PEmulationSetScriptExecutionDisabled = ()
+  commandName _ = "Emulation.setScriptExecutionDisabled"
+  fromJSON = const . A.Success . const ()
+
+-- | Enables touch on platforms which do not support them.
+
+-- | Parameters of the 'Emulation.setTouchEmulationEnabled' command.
+data PEmulationSetTouchEmulationEnabled = PEmulationSetTouchEmulationEnabled
+  {
+    -- | Whether the touch event emulation should be enabled.
+    pEmulationSetTouchEmulationEnabledEnabled :: Bool,
+    -- | Maximum touch points supported. Defaults to one.
+    pEmulationSetTouchEmulationEnabledMaxTouchPoints :: Maybe Int
+  }
+  deriving (Eq, Show)
+pEmulationSetTouchEmulationEnabled
+  {-
+  -- | Whether the touch event emulation should be enabled.
+  -}
+  :: Bool
+  -> PEmulationSetTouchEmulationEnabled
+pEmulationSetTouchEmulationEnabled
+  arg_pEmulationSetTouchEmulationEnabledEnabled
+  = PEmulationSetTouchEmulationEnabled
+    arg_pEmulationSetTouchEmulationEnabledEnabled
+    Nothing
+instance ToJSON PEmulationSetTouchEmulationEnabled where
+  toJSON p = A.object $ catMaybes [
+    ("enabled" A..=) <$> Just (pEmulationSetTouchEmulationEnabledEnabled p),
+    ("maxTouchPoints" A..=) <$> (pEmulationSetTouchEmulationEnabledMaxTouchPoints p)
+    ]
+instance Command PEmulationSetTouchEmulationEnabled where
+  type CommandResponse PEmulationSetTouchEmulationEnabled = ()
+  commandName _ = "Emulation.setTouchEmulationEnabled"
+  fromJSON = const . A.Success . const ()
+
+-- | Turns on virtual time for all frames (replacing real-time with a synthetic time source) and sets
+--   the current virtual time policy.  Note this supersedes any previous time budget.
+
+-- | Parameters of the 'Emulation.setVirtualTimePolicy' command.
+data PEmulationSetVirtualTimePolicy = PEmulationSetVirtualTimePolicy
+  {
+    pEmulationSetVirtualTimePolicyPolicy :: EmulationVirtualTimePolicy,
+    -- | If set, after this many virtual milliseconds have elapsed virtual time will be paused and a
+    --   virtualTimeBudgetExpired event is sent.
+    pEmulationSetVirtualTimePolicyBudget :: Maybe Double,
+    -- | If set this specifies the maximum number of tasks that can be run before virtual is forced
+    --   forwards to prevent deadlock.
+    pEmulationSetVirtualTimePolicyMaxVirtualTimeTaskStarvationCount :: Maybe Int,
+    -- | If set, base::Time::Now will be overridden to initially return this value.
+    pEmulationSetVirtualTimePolicyInitialVirtualTime :: Maybe NetworkTimeSinceEpoch
+  }
+  deriving (Eq, Show)
+pEmulationSetVirtualTimePolicy
+  :: EmulationVirtualTimePolicy
+  -> PEmulationSetVirtualTimePolicy
+pEmulationSetVirtualTimePolicy
+  arg_pEmulationSetVirtualTimePolicyPolicy
+  = PEmulationSetVirtualTimePolicy
+    arg_pEmulationSetVirtualTimePolicyPolicy
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PEmulationSetVirtualTimePolicy where
+  toJSON p = A.object $ catMaybes [
+    ("policy" A..=) <$> Just (pEmulationSetVirtualTimePolicyPolicy p),
+    ("budget" A..=) <$> (pEmulationSetVirtualTimePolicyBudget p),
+    ("maxVirtualTimeTaskStarvationCount" A..=) <$> (pEmulationSetVirtualTimePolicyMaxVirtualTimeTaskStarvationCount p),
+    ("initialVirtualTime" A..=) <$> (pEmulationSetVirtualTimePolicyInitialVirtualTime p)
+    ]
+data EmulationSetVirtualTimePolicy = EmulationSetVirtualTimePolicy
+  {
+    -- | Absolute timestamp at which virtual time was first enabled (up time in milliseconds).
+    emulationSetVirtualTimePolicyVirtualTimeTicksBase :: Double
+  }
+  deriving (Eq, Show)
+instance FromJSON EmulationSetVirtualTimePolicy where
+  parseJSON = A.withObject "EmulationSetVirtualTimePolicy" $ \o -> EmulationSetVirtualTimePolicy
+    <$> o A..: "virtualTimeTicksBase"
+instance Command PEmulationSetVirtualTimePolicy where
+  type CommandResponse PEmulationSetVirtualTimePolicy = EmulationSetVirtualTimePolicy
+  commandName _ = "Emulation.setVirtualTimePolicy"
+
+-- | Overrides default host system locale with the specified one.
+
+-- | Parameters of the 'Emulation.setLocaleOverride' command.
+data PEmulationSetLocaleOverride = PEmulationSetLocaleOverride
+  {
+    -- | ICU style C locale (e.g. "en_US"). If not specified or empty, disables the override and
+    --   restores default host system locale.
+    pEmulationSetLocaleOverrideLocale :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+pEmulationSetLocaleOverride
+  :: PEmulationSetLocaleOverride
+pEmulationSetLocaleOverride
+  = PEmulationSetLocaleOverride
+    Nothing
+instance ToJSON PEmulationSetLocaleOverride where
+  toJSON p = A.object $ catMaybes [
+    ("locale" A..=) <$> (pEmulationSetLocaleOverrideLocale p)
+    ]
+instance Command PEmulationSetLocaleOverride where
+  type CommandResponse PEmulationSetLocaleOverride = ()
+  commandName _ = "Emulation.setLocaleOverride"
+  fromJSON = const . A.Success . const ()
+
+-- | Overrides default host system timezone with the specified one.
+
+-- | Parameters of the 'Emulation.setTimezoneOverride' command.
+data PEmulationSetTimezoneOverride = PEmulationSetTimezoneOverride
+  {
+    -- | The timezone identifier. If empty, disables the override and
+    --   restores default host system timezone.
+    pEmulationSetTimezoneOverrideTimezoneId :: T.Text
+  }
+  deriving (Eq, Show)
+pEmulationSetTimezoneOverride
+  {-
+  -- | The timezone identifier. If empty, disables the override and
+  --   restores default host system timezone.
+  -}
+  :: T.Text
+  -> PEmulationSetTimezoneOverride
+pEmulationSetTimezoneOverride
+  arg_pEmulationSetTimezoneOverrideTimezoneId
+  = PEmulationSetTimezoneOverride
+    arg_pEmulationSetTimezoneOverrideTimezoneId
+instance ToJSON PEmulationSetTimezoneOverride where
+  toJSON p = A.object $ catMaybes [
+    ("timezoneId" A..=) <$> Just (pEmulationSetTimezoneOverrideTimezoneId p)
+    ]
+instance Command PEmulationSetTimezoneOverride where
+  type CommandResponse PEmulationSetTimezoneOverride = ()
+  commandName _ = "Emulation.setTimezoneOverride"
+  fromJSON = const . A.Success . const ()
+
+
+-- | Parameters of the 'Emulation.setDisabledImageTypes' command.
+data PEmulationSetDisabledImageTypes = PEmulationSetDisabledImageTypes
+  {
+    -- | Image types to disable.
+    pEmulationSetDisabledImageTypesImageTypes :: [EmulationDisabledImageType]
+  }
+  deriving (Eq, Show)
+pEmulationSetDisabledImageTypes
+  {-
+  -- | Image types to disable.
+  -}
+  :: [EmulationDisabledImageType]
+  -> PEmulationSetDisabledImageTypes
+pEmulationSetDisabledImageTypes
+  arg_pEmulationSetDisabledImageTypesImageTypes
+  = PEmulationSetDisabledImageTypes
+    arg_pEmulationSetDisabledImageTypesImageTypes
+instance ToJSON PEmulationSetDisabledImageTypes where
+  toJSON p = A.object $ catMaybes [
+    ("imageTypes" A..=) <$> Just (pEmulationSetDisabledImageTypesImageTypes p)
+    ]
+instance Command PEmulationSetDisabledImageTypes where
+  type CommandResponse PEmulationSetDisabledImageTypes = ()
+  commandName _ = "Emulation.setDisabledImageTypes"
+  fromJSON = const . A.Success . const ()
+
+
+-- | Parameters of the 'Emulation.setHardwareConcurrencyOverride' command.
+data PEmulationSetHardwareConcurrencyOverride = PEmulationSetHardwareConcurrencyOverride
+  {
+    -- | Hardware concurrency to report
+    pEmulationSetHardwareConcurrencyOverrideHardwareConcurrency :: Int
+  }
+  deriving (Eq, Show)
+pEmulationSetHardwareConcurrencyOverride
+  {-
+  -- | Hardware concurrency to report
+  -}
+  :: Int
+  -> PEmulationSetHardwareConcurrencyOverride
+pEmulationSetHardwareConcurrencyOverride
+  arg_pEmulationSetHardwareConcurrencyOverrideHardwareConcurrency
+  = PEmulationSetHardwareConcurrencyOverride
+    arg_pEmulationSetHardwareConcurrencyOverrideHardwareConcurrency
+instance ToJSON PEmulationSetHardwareConcurrencyOverride where
+  toJSON p = A.object $ catMaybes [
+    ("hardwareConcurrency" A..=) <$> Just (pEmulationSetHardwareConcurrencyOverrideHardwareConcurrency p)
+    ]
+instance Command PEmulationSetHardwareConcurrencyOverride where
+  type CommandResponse PEmulationSetHardwareConcurrencyOverride = ()
+  commandName _ = "Emulation.setHardwareConcurrencyOverride"
+  fromJSON = const . A.Success . const ()
+
+-- | Allows overriding user agent with the given string.
+
+-- | Parameters of the 'Emulation.setUserAgentOverride' command.
+data PEmulationSetUserAgentOverride = PEmulationSetUserAgentOverride
+  {
+    -- | User agent to use.
+    pEmulationSetUserAgentOverrideUserAgent :: T.Text,
+    -- | Browser langugage to emulate.
+    pEmulationSetUserAgentOverrideAcceptLanguage :: Maybe T.Text,
+    -- | The platform navigator.platform should return.
+    pEmulationSetUserAgentOverridePlatform :: Maybe T.Text,
+    -- | To be sent in Sec-CH-UA-* headers and returned in navigator.userAgentData
+    pEmulationSetUserAgentOverrideUserAgentMetadata :: Maybe EmulationUserAgentMetadata
+  }
+  deriving (Eq, Show)
+pEmulationSetUserAgentOverride
+  {-
+  -- | User agent to use.
+  -}
+  :: T.Text
+  -> PEmulationSetUserAgentOverride
+pEmulationSetUserAgentOverride
+  arg_pEmulationSetUserAgentOverrideUserAgent
+  = PEmulationSetUserAgentOverride
+    arg_pEmulationSetUserAgentOverrideUserAgent
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PEmulationSetUserAgentOverride where
+  toJSON p = A.object $ catMaybes [
+    ("userAgent" A..=) <$> Just (pEmulationSetUserAgentOverrideUserAgent p),
+    ("acceptLanguage" A..=) <$> (pEmulationSetUserAgentOverrideAcceptLanguage p),
+    ("platform" A..=) <$> (pEmulationSetUserAgentOverridePlatform p),
+    ("userAgentMetadata" A..=) <$> (pEmulationSetUserAgentOverrideUserAgentMetadata p)
+    ]
+instance Command PEmulationSetUserAgentOverride where
+  type CommandResponse PEmulationSetUserAgentOverride = ()
+  commandName _ = "Emulation.setUserAgentOverride"
+  fromJSON = const . A.Success . const ()
+
+-- | Allows overriding the automation flag.
+
+-- | Parameters of the 'Emulation.setAutomationOverride' command.
+data PEmulationSetAutomationOverride = PEmulationSetAutomationOverride
+  {
+    -- | Whether the override should be enabled.
+    pEmulationSetAutomationOverrideEnabled :: Bool
+  }
+  deriving (Eq, Show)
+pEmulationSetAutomationOverride
+  {-
+  -- | Whether the override should be enabled.
+  -}
+  :: Bool
+  -> PEmulationSetAutomationOverride
+pEmulationSetAutomationOverride
+  arg_pEmulationSetAutomationOverrideEnabled
+  = PEmulationSetAutomationOverride
+    arg_pEmulationSetAutomationOverrideEnabled
+instance ToJSON PEmulationSetAutomationOverride where
+  toJSON p = A.object $ catMaybes [
+    ("enabled" A..=) <$> Just (pEmulationSetAutomationOverrideEnabled p)
+    ]
+instance Command PEmulationSetAutomationOverride where
+  type CommandResponse PEmulationSetAutomationOverride = ()
+  commandName _ = "Emulation.setAutomationOverride"
+  fromJSON = const . A.Success . const ()
+
+-- | Type 'Network.ResourceType'.
+--   Resource type as it was perceived by the rendering engine.
+data NetworkResourceType = NetworkResourceTypeDocument | NetworkResourceTypeStylesheet | NetworkResourceTypeImage | NetworkResourceTypeMedia | NetworkResourceTypeFont | NetworkResourceTypeScript | NetworkResourceTypeTextTrack | NetworkResourceTypeXHR | NetworkResourceTypeFetch | NetworkResourceTypePrefetch | NetworkResourceTypeEventSource | NetworkResourceTypeWebSocket | NetworkResourceTypeManifest | NetworkResourceTypeSignedExchange | NetworkResourceTypePing | NetworkResourceTypeCSPViolationReport | NetworkResourceTypePreflight | NetworkResourceTypeOther
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON NetworkResourceType where
+  parseJSON = A.withText "NetworkResourceType" $ \v -> case v of
+    "Document" -> pure NetworkResourceTypeDocument
+    "Stylesheet" -> pure NetworkResourceTypeStylesheet
+    "Image" -> pure NetworkResourceTypeImage
+    "Media" -> pure NetworkResourceTypeMedia
+    "Font" -> pure NetworkResourceTypeFont
+    "Script" -> pure NetworkResourceTypeScript
+    "TextTrack" -> pure NetworkResourceTypeTextTrack
+    "XHR" -> pure NetworkResourceTypeXHR
+    "Fetch" -> pure NetworkResourceTypeFetch
+    "Prefetch" -> pure NetworkResourceTypePrefetch
+    "EventSource" -> pure NetworkResourceTypeEventSource
+    "WebSocket" -> pure NetworkResourceTypeWebSocket
+    "Manifest" -> pure NetworkResourceTypeManifest
+    "SignedExchange" -> pure NetworkResourceTypeSignedExchange
+    "Ping" -> pure NetworkResourceTypePing
+    "CSPViolationReport" -> pure NetworkResourceTypeCSPViolationReport
+    "Preflight" -> pure NetworkResourceTypePreflight
+    "Other" -> pure NetworkResourceTypeOther
+    "_" -> fail "failed to parse NetworkResourceType"
+instance ToJSON NetworkResourceType where
+  toJSON v = A.String $ case v of
+    NetworkResourceTypeDocument -> "Document"
+    NetworkResourceTypeStylesheet -> "Stylesheet"
+    NetworkResourceTypeImage -> "Image"
+    NetworkResourceTypeMedia -> "Media"
+    NetworkResourceTypeFont -> "Font"
+    NetworkResourceTypeScript -> "Script"
+    NetworkResourceTypeTextTrack -> "TextTrack"
+    NetworkResourceTypeXHR -> "XHR"
+    NetworkResourceTypeFetch -> "Fetch"
+    NetworkResourceTypePrefetch -> "Prefetch"
+    NetworkResourceTypeEventSource -> "EventSource"
+    NetworkResourceTypeWebSocket -> "WebSocket"
+    NetworkResourceTypeManifest -> "Manifest"
+    NetworkResourceTypeSignedExchange -> "SignedExchange"
+    NetworkResourceTypePing -> "Ping"
+    NetworkResourceTypeCSPViolationReport -> "CSPViolationReport"
+    NetworkResourceTypePreflight -> "Preflight"
+    NetworkResourceTypeOther -> "Other"
+
+-- | Type 'Network.LoaderId'.
+--   Unique loader identifier.
+type NetworkLoaderId = T.Text
+
+-- | Type 'Network.RequestId'.
+--   Unique request identifier.
+type NetworkRequestId = T.Text
+
+-- | Type 'Network.InterceptionId'.
+--   Unique intercepted request identifier.
+type NetworkInterceptionId = T.Text
+
+-- | Type 'Network.ErrorReason'.
+--   Network level fetch failure reason.
+data NetworkErrorReason = NetworkErrorReasonFailed | NetworkErrorReasonAborted | NetworkErrorReasonTimedOut | NetworkErrorReasonAccessDenied | NetworkErrorReasonConnectionClosed | NetworkErrorReasonConnectionReset | NetworkErrorReasonConnectionRefused | NetworkErrorReasonConnectionAborted | NetworkErrorReasonConnectionFailed | NetworkErrorReasonNameNotResolved | NetworkErrorReasonInternetDisconnected | NetworkErrorReasonAddressUnreachable | NetworkErrorReasonBlockedByClient | NetworkErrorReasonBlockedByResponse
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON NetworkErrorReason where
+  parseJSON = A.withText "NetworkErrorReason" $ \v -> case v of
+    "Failed" -> pure NetworkErrorReasonFailed
+    "Aborted" -> pure NetworkErrorReasonAborted
+    "TimedOut" -> pure NetworkErrorReasonTimedOut
+    "AccessDenied" -> pure NetworkErrorReasonAccessDenied
+    "ConnectionClosed" -> pure NetworkErrorReasonConnectionClosed
+    "ConnectionReset" -> pure NetworkErrorReasonConnectionReset
+    "ConnectionRefused" -> pure NetworkErrorReasonConnectionRefused
+    "ConnectionAborted" -> pure NetworkErrorReasonConnectionAborted
+    "ConnectionFailed" -> pure NetworkErrorReasonConnectionFailed
+    "NameNotResolved" -> pure NetworkErrorReasonNameNotResolved
+    "InternetDisconnected" -> pure NetworkErrorReasonInternetDisconnected
+    "AddressUnreachable" -> pure NetworkErrorReasonAddressUnreachable
+    "BlockedByClient" -> pure NetworkErrorReasonBlockedByClient
+    "BlockedByResponse" -> pure NetworkErrorReasonBlockedByResponse
+    "_" -> fail "failed to parse NetworkErrorReason"
+instance ToJSON NetworkErrorReason where
+  toJSON v = A.String $ case v of
+    NetworkErrorReasonFailed -> "Failed"
+    NetworkErrorReasonAborted -> "Aborted"
+    NetworkErrorReasonTimedOut -> "TimedOut"
+    NetworkErrorReasonAccessDenied -> "AccessDenied"
+    NetworkErrorReasonConnectionClosed -> "ConnectionClosed"
+    NetworkErrorReasonConnectionReset -> "ConnectionReset"
+    NetworkErrorReasonConnectionRefused -> "ConnectionRefused"
+    NetworkErrorReasonConnectionAborted -> "ConnectionAborted"
+    NetworkErrorReasonConnectionFailed -> "ConnectionFailed"
+    NetworkErrorReasonNameNotResolved -> "NameNotResolved"
+    NetworkErrorReasonInternetDisconnected -> "InternetDisconnected"
+    NetworkErrorReasonAddressUnreachable -> "AddressUnreachable"
+    NetworkErrorReasonBlockedByClient -> "BlockedByClient"
+    NetworkErrorReasonBlockedByResponse -> "BlockedByResponse"
+
+-- | Type 'Network.TimeSinceEpoch'.
+--   UTC time in seconds, counted from January 1, 1970.
+type NetworkTimeSinceEpoch = Double
+
+-- | Type 'Network.MonotonicTime'.
+--   Monotonically increasing time in seconds since an arbitrary point in the past.
+type NetworkMonotonicTime = Double
+
+-- | Type 'Network.Headers'.
+--   Request / response headers as keys / values of JSON object.
+type NetworkHeaders = [(T.Text, T.Text)]
+
+-- | Type 'Network.ConnectionType'.
+--   The underlying connection technology that the browser is supposedly using.
+data NetworkConnectionType = NetworkConnectionTypeNone | NetworkConnectionTypeCellular2g | NetworkConnectionTypeCellular3g | NetworkConnectionTypeCellular4g | NetworkConnectionTypeBluetooth | NetworkConnectionTypeEthernet | NetworkConnectionTypeWifi | NetworkConnectionTypeWimax | NetworkConnectionTypeOther
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON NetworkConnectionType where
+  parseJSON = A.withText "NetworkConnectionType" $ \v -> case v of
+    "none" -> pure NetworkConnectionTypeNone
+    "cellular2g" -> pure NetworkConnectionTypeCellular2g
+    "cellular3g" -> pure NetworkConnectionTypeCellular3g
+    "cellular4g" -> pure NetworkConnectionTypeCellular4g
+    "bluetooth" -> pure NetworkConnectionTypeBluetooth
+    "ethernet" -> pure NetworkConnectionTypeEthernet
+    "wifi" -> pure NetworkConnectionTypeWifi
+    "wimax" -> pure NetworkConnectionTypeWimax
+    "other" -> pure NetworkConnectionTypeOther
+    "_" -> fail "failed to parse NetworkConnectionType"
+instance ToJSON NetworkConnectionType where
+  toJSON v = A.String $ case v of
+    NetworkConnectionTypeNone -> "none"
+    NetworkConnectionTypeCellular2g -> "cellular2g"
+    NetworkConnectionTypeCellular3g -> "cellular3g"
+    NetworkConnectionTypeCellular4g -> "cellular4g"
+    NetworkConnectionTypeBluetooth -> "bluetooth"
+    NetworkConnectionTypeEthernet -> "ethernet"
+    NetworkConnectionTypeWifi -> "wifi"
+    NetworkConnectionTypeWimax -> "wimax"
+    NetworkConnectionTypeOther -> "other"
+
+-- | Type 'Network.CookieSameSite'.
+--   Represents the cookie's 'SameSite' status:
+--   https://tools.ietf.org/html/draft-west-first-party-cookies
+data NetworkCookieSameSite = NetworkCookieSameSiteStrict | NetworkCookieSameSiteLax | NetworkCookieSameSiteNone
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON NetworkCookieSameSite where
+  parseJSON = A.withText "NetworkCookieSameSite" $ \v -> case v of
+    "Strict" -> pure NetworkCookieSameSiteStrict
+    "Lax" -> pure NetworkCookieSameSiteLax
+    "None" -> pure NetworkCookieSameSiteNone
+    "_" -> fail "failed to parse NetworkCookieSameSite"
+instance ToJSON NetworkCookieSameSite where
+  toJSON v = A.String $ case v of
+    NetworkCookieSameSiteStrict -> "Strict"
+    NetworkCookieSameSiteLax -> "Lax"
+    NetworkCookieSameSiteNone -> "None"
+
+-- | Type 'Network.CookiePriority'.
+--   Represents the cookie's 'Priority' status:
+--   https://tools.ietf.org/html/draft-west-cookie-priority-00
+data NetworkCookiePriority = NetworkCookiePriorityLow | NetworkCookiePriorityMedium | NetworkCookiePriorityHigh
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON NetworkCookiePriority where
+  parseJSON = A.withText "NetworkCookiePriority" $ \v -> case v of
+    "Low" -> pure NetworkCookiePriorityLow
+    "Medium" -> pure NetworkCookiePriorityMedium
+    "High" -> pure NetworkCookiePriorityHigh
+    "_" -> fail "failed to parse NetworkCookiePriority"
+instance ToJSON NetworkCookiePriority where
+  toJSON v = A.String $ case v of
+    NetworkCookiePriorityLow -> "Low"
+    NetworkCookiePriorityMedium -> "Medium"
+    NetworkCookiePriorityHigh -> "High"
+
+-- | Type 'Network.CookieSourceScheme'.
+--   Represents the source scheme of the origin that originally set the cookie.
+--   A value of "Unset" allows protocol clients to emulate legacy cookie scope for the scheme.
+--   This is a temporary ability and it will be removed in the future.
+data NetworkCookieSourceScheme = NetworkCookieSourceSchemeUnset | NetworkCookieSourceSchemeNonSecure | NetworkCookieSourceSchemeSecure
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON NetworkCookieSourceScheme where
+  parseJSON = A.withText "NetworkCookieSourceScheme" $ \v -> case v of
+    "Unset" -> pure NetworkCookieSourceSchemeUnset
+    "NonSecure" -> pure NetworkCookieSourceSchemeNonSecure
+    "Secure" -> pure NetworkCookieSourceSchemeSecure
+    "_" -> fail "failed to parse NetworkCookieSourceScheme"
+instance ToJSON NetworkCookieSourceScheme where
+  toJSON v = A.String $ case v of
+    NetworkCookieSourceSchemeUnset -> "Unset"
+    NetworkCookieSourceSchemeNonSecure -> "NonSecure"
+    NetworkCookieSourceSchemeSecure -> "Secure"
+
+-- | Type 'Network.ResourceTiming'.
+--   Timing information for the request.
+data NetworkResourceTiming = NetworkResourceTiming
+  {
+    -- | Timing's requestTime is a baseline in seconds, while the other numbers are ticks in
+    --   milliseconds relatively to this requestTime.
+    networkResourceTimingRequestTime :: Double,
+    -- | Started resolving proxy.
+    networkResourceTimingProxyStart :: Double,
+    -- | Finished resolving proxy.
+    networkResourceTimingProxyEnd :: Double,
+    -- | Started DNS address resolve.
+    networkResourceTimingDnsStart :: Double,
+    -- | Finished DNS address resolve.
+    networkResourceTimingDnsEnd :: Double,
+    -- | Started connecting to the remote host.
+    networkResourceTimingConnectStart :: Double,
+    -- | Connected to the remote host.
+    networkResourceTimingConnectEnd :: Double,
+    -- | Started SSL handshake.
+    networkResourceTimingSslStart :: Double,
+    -- | Finished SSL handshake.
+    networkResourceTimingSslEnd :: Double,
+    -- | Started running ServiceWorker.
+    networkResourceTimingWorkerStart :: Double,
+    -- | Finished Starting ServiceWorker.
+    networkResourceTimingWorkerReady :: Double,
+    -- | Started fetch event.
+    networkResourceTimingWorkerFetchStart :: Double,
+    -- | Settled fetch event respondWith promise.
+    networkResourceTimingWorkerRespondWithSettled :: Double,
+    -- | Started sending request.
+    networkResourceTimingSendStart :: Double,
+    -- | Finished sending request.
+    networkResourceTimingSendEnd :: Double,
+    -- | Time the server started pushing request.
+    networkResourceTimingPushStart :: Double,
+    -- | Time the server finished pushing request.
+    networkResourceTimingPushEnd :: Double,
+    -- | Finished receiving response headers.
+    networkResourceTimingReceiveHeadersEnd :: Double
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkResourceTiming where
+  parseJSON = A.withObject "NetworkResourceTiming" $ \o -> NetworkResourceTiming
+    <$> o A..: "requestTime"
+    <*> o A..: "proxyStart"
+    <*> o A..: "proxyEnd"
+    <*> o A..: "dnsStart"
+    <*> o A..: "dnsEnd"
+    <*> o A..: "connectStart"
+    <*> o A..: "connectEnd"
+    <*> o A..: "sslStart"
+    <*> o A..: "sslEnd"
+    <*> o A..: "workerStart"
+    <*> o A..: "workerReady"
+    <*> o A..: "workerFetchStart"
+    <*> o A..: "workerRespondWithSettled"
+    <*> o A..: "sendStart"
+    <*> o A..: "sendEnd"
+    <*> o A..: "pushStart"
+    <*> o A..: "pushEnd"
+    <*> o A..: "receiveHeadersEnd"
+instance ToJSON NetworkResourceTiming where
+  toJSON p = A.object $ catMaybes [
+    ("requestTime" A..=) <$> Just (networkResourceTimingRequestTime p),
+    ("proxyStart" A..=) <$> Just (networkResourceTimingProxyStart p),
+    ("proxyEnd" A..=) <$> Just (networkResourceTimingProxyEnd p),
+    ("dnsStart" A..=) <$> Just (networkResourceTimingDnsStart p),
+    ("dnsEnd" A..=) <$> Just (networkResourceTimingDnsEnd p),
+    ("connectStart" A..=) <$> Just (networkResourceTimingConnectStart p),
+    ("connectEnd" A..=) <$> Just (networkResourceTimingConnectEnd p),
+    ("sslStart" A..=) <$> Just (networkResourceTimingSslStart p),
+    ("sslEnd" A..=) <$> Just (networkResourceTimingSslEnd p),
+    ("workerStart" A..=) <$> Just (networkResourceTimingWorkerStart p),
+    ("workerReady" A..=) <$> Just (networkResourceTimingWorkerReady p),
+    ("workerFetchStart" A..=) <$> Just (networkResourceTimingWorkerFetchStart p),
+    ("workerRespondWithSettled" A..=) <$> Just (networkResourceTimingWorkerRespondWithSettled p),
+    ("sendStart" A..=) <$> Just (networkResourceTimingSendStart p),
+    ("sendEnd" A..=) <$> Just (networkResourceTimingSendEnd p),
+    ("pushStart" A..=) <$> Just (networkResourceTimingPushStart p),
+    ("pushEnd" A..=) <$> Just (networkResourceTimingPushEnd p),
+    ("receiveHeadersEnd" A..=) <$> Just (networkResourceTimingReceiveHeadersEnd p)
+    ]
+
+-- | Type 'Network.ResourcePriority'.
+--   Loading priority of a resource request.
+data NetworkResourcePriority = NetworkResourcePriorityVeryLow | NetworkResourcePriorityLow | NetworkResourcePriorityMedium | NetworkResourcePriorityHigh | NetworkResourcePriorityVeryHigh
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON NetworkResourcePriority where
+  parseJSON = A.withText "NetworkResourcePriority" $ \v -> case v of
+    "VeryLow" -> pure NetworkResourcePriorityVeryLow
+    "Low" -> pure NetworkResourcePriorityLow
+    "Medium" -> pure NetworkResourcePriorityMedium
+    "High" -> pure NetworkResourcePriorityHigh
+    "VeryHigh" -> pure NetworkResourcePriorityVeryHigh
+    "_" -> fail "failed to parse NetworkResourcePriority"
+instance ToJSON NetworkResourcePriority where
+  toJSON v = A.String $ case v of
+    NetworkResourcePriorityVeryLow -> "VeryLow"
+    NetworkResourcePriorityLow -> "Low"
+    NetworkResourcePriorityMedium -> "Medium"
+    NetworkResourcePriorityHigh -> "High"
+    NetworkResourcePriorityVeryHigh -> "VeryHigh"
+
+-- | Type 'Network.PostDataEntry'.
+--   Post data entry for HTTP request
+data NetworkPostDataEntry = NetworkPostDataEntry
+  {
+    networkPostDataEntryBytes :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkPostDataEntry where
+  parseJSON = A.withObject "NetworkPostDataEntry" $ \o -> NetworkPostDataEntry
+    <$> o A..:? "bytes"
+instance ToJSON NetworkPostDataEntry where
+  toJSON p = A.object $ catMaybes [
+    ("bytes" A..=) <$> (networkPostDataEntryBytes p)
+    ]
+
+-- | Type 'Network.Request'.
+--   HTTP request data.
+data NetworkRequestReferrerPolicy = NetworkRequestReferrerPolicyUnsafeUrl | NetworkRequestReferrerPolicyNoReferrerWhenDowngrade | NetworkRequestReferrerPolicyNoReferrer | NetworkRequestReferrerPolicyOrigin | NetworkRequestReferrerPolicyOriginWhenCrossOrigin | NetworkRequestReferrerPolicySameOrigin | NetworkRequestReferrerPolicyStrictOrigin | NetworkRequestReferrerPolicyStrictOriginWhenCrossOrigin
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON NetworkRequestReferrerPolicy where
+  parseJSON = A.withText "NetworkRequestReferrerPolicy" $ \v -> case v of
+    "unsafe-url" -> pure NetworkRequestReferrerPolicyUnsafeUrl
+    "no-referrer-when-downgrade" -> pure NetworkRequestReferrerPolicyNoReferrerWhenDowngrade
+    "no-referrer" -> pure NetworkRequestReferrerPolicyNoReferrer
+    "origin" -> pure NetworkRequestReferrerPolicyOrigin
+    "origin-when-cross-origin" -> pure NetworkRequestReferrerPolicyOriginWhenCrossOrigin
+    "same-origin" -> pure NetworkRequestReferrerPolicySameOrigin
+    "strict-origin" -> pure NetworkRequestReferrerPolicyStrictOrigin
+    "strict-origin-when-cross-origin" -> pure NetworkRequestReferrerPolicyStrictOriginWhenCrossOrigin
+    "_" -> fail "failed to parse NetworkRequestReferrerPolicy"
+instance ToJSON NetworkRequestReferrerPolicy where
+  toJSON v = A.String $ case v of
+    NetworkRequestReferrerPolicyUnsafeUrl -> "unsafe-url"
+    NetworkRequestReferrerPolicyNoReferrerWhenDowngrade -> "no-referrer-when-downgrade"
+    NetworkRequestReferrerPolicyNoReferrer -> "no-referrer"
+    NetworkRequestReferrerPolicyOrigin -> "origin"
+    NetworkRequestReferrerPolicyOriginWhenCrossOrigin -> "origin-when-cross-origin"
+    NetworkRequestReferrerPolicySameOrigin -> "same-origin"
+    NetworkRequestReferrerPolicyStrictOrigin -> "strict-origin"
+    NetworkRequestReferrerPolicyStrictOriginWhenCrossOrigin -> "strict-origin-when-cross-origin"
+data NetworkRequest = NetworkRequest
+  {
+    -- | Request URL (without fragment).
+    networkRequestUrl :: T.Text,
+    -- | Fragment of the requested URL starting with hash, if present.
+    networkRequestUrlFragment :: Maybe T.Text,
+    -- | HTTP request method.
+    networkRequestMethod :: T.Text,
+    -- | HTTP request headers.
+    networkRequestHeaders :: NetworkHeaders,
+    -- | HTTP POST request data.
+    networkRequestPostData :: Maybe T.Text,
+    -- | True when the request has POST data. Note that postData might still be omitted when this flag is true when the data is too long.
+    networkRequestHasPostData :: Maybe Bool,
+    -- | Request body elements. This will be converted from base64 to binary
+    networkRequestPostDataEntries :: Maybe [NetworkPostDataEntry],
+    -- | The mixed content type of the request.
+    networkRequestMixedContentType :: Maybe SecurityMixedContentType,
+    -- | Priority of the resource request at the time request is sent.
+    networkRequestInitialPriority :: NetworkResourcePriority,
+    -- | The referrer policy of the request, as defined in https://www.w3.org/TR/referrer-policy/
+    networkRequestReferrerPolicy :: NetworkRequestReferrerPolicy,
+    -- | Whether is loaded via link preload.
+    networkRequestIsLinkPreload :: Maybe Bool,
+    -- | Set for requests when the TrustToken API is used. Contains the parameters
+    --   passed by the developer (e.g. via "fetch") as understood by the backend.
+    networkRequestTrustTokenParams :: Maybe NetworkTrustTokenParams,
+    -- | True if this resource request is considered to be the 'same site' as the
+    --   request correspondinfg to the main frame.
+    networkRequestIsSameSite :: Maybe Bool
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkRequest where
+  parseJSON = A.withObject "NetworkRequest" $ \o -> NetworkRequest
+    <$> o A..: "url"
+    <*> o A..:? "urlFragment"
+    <*> o A..: "method"
+    <*> o A..: "headers"
+    <*> o A..:? "postData"
+    <*> o A..:? "hasPostData"
+    <*> o A..:? "postDataEntries"
+    <*> o A..:? "mixedContentType"
+    <*> o A..: "initialPriority"
+    <*> o A..: "referrerPolicy"
+    <*> o A..:? "isLinkPreload"
+    <*> o A..:? "trustTokenParams"
+    <*> o A..:? "isSameSite"
+instance ToJSON NetworkRequest where
+  toJSON p = A.object $ catMaybes [
+    ("url" A..=) <$> Just (networkRequestUrl p),
+    ("urlFragment" A..=) <$> (networkRequestUrlFragment p),
+    ("method" A..=) <$> Just (networkRequestMethod p),
+    ("headers" A..=) <$> Just (networkRequestHeaders p),
+    ("postData" A..=) <$> (networkRequestPostData p),
+    ("hasPostData" A..=) <$> (networkRequestHasPostData p),
+    ("postDataEntries" A..=) <$> (networkRequestPostDataEntries p),
+    ("mixedContentType" A..=) <$> (networkRequestMixedContentType p),
+    ("initialPriority" A..=) <$> Just (networkRequestInitialPriority p),
+    ("referrerPolicy" A..=) <$> Just (networkRequestReferrerPolicy p),
+    ("isLinkPreload" A..=) <$> (networkRequestIsLinkPreload p),
+    ("trustTokenParams" A..=) <$> (networkRequestTrustTokenParams p),
+    ("isSameSite" A..=) <$> (networkRequestIsSameSite p)
+    ]
+
+-- | Type 'Network.SignedCertificateTimestamp'.
+--   Details of a signed certificate timestamp (SCT).
+data NetworkSignedCertificateTimestamp = NetworkSignedCertificateTimestamp
+  {
+    -- | Validation status.
+    networkSignedCertificateTimestampStatus :: T.Text,
+    -- | Origin.
+    networkSignedCertificateTimestampOrigin :: T.Text,
+    -- | Log name / description.
+    networkSignedCertificateTimestampLogDescription :: T.Text,
+    -- | Log ID.
+    networkSignedCertificateTimestampLogId :: T.Text,
+    -- | Issuance date. Unlike TimeSinceEpoch, this contains the number of
+    --   milliseconds since January 1, 1970, UTC, not the number of seconds.
+    networkSignedCertificateTimestampTimestamp :: Double,
+    -- | Hash algorithm.
+    networkSignedCertificateTimestampHashAlgorithm :: T.Text,
+    -- | Signature algorithm.
+    networkSignedCertificateTimestampSignatureAlgorithm :: T.Text,
+    -- | Signature data.
+    networkSignedCertificateTimestampSignatureData :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkSignedCertificateTimestamp where
+  parseJSON = A.withObject "NetworkSignedCertificateTimestamp" $ \o -> NetworkSignedCertificateTimestamp
+    <$> o A..: "status"
+    <*> o A..: "origin"
+    <*> o A..: "logDescription"
+    <*> o A..: "logId"
+    <*> o A..: "timestamp"
+    <*> o A..: "hashAlgorithm"
+    <*> o A..: "signatureAlgorithm"
+    <*> o A..: "signatureData"
+instance ToJSON NetworkSignedCertificateTimestamp where
+  toJSON p = A.object $ catMaybes [
+    ("status" A..=) <$> Just (networkSignedCertificateTimestampStatus p),
+    ("origin" A..=) <$> Just (networkSignedCertificateTimestampOrigin p),
+    ("logDescription" A..=) <$> Just (networkSignedCertificateTimestampLogDescription p),
+    ("logId" A..=) <$> Just (networkSignedCertificateTimestampLogId p),
+    ("timestamp" A..=) <$> Just (networkSignedCertificateTimestampTimestamp p),
+    ("hashAlgorithm" A..=) <$> Just (networkSignedCertificateTimestampHashAlgorithm p),
+    ("signatureAlgorithm" A..=) <$> Just (networkSignedCertificateTimestampSignatureAlgorithm p),
+    ("signatureData" A..=) <$> Just (networkSignedCertificateTimestampSignatureData p)
+    ]
+
+-- | Type 'Network.SecurityDetails'.
+--   Security details about a request.
+data NetworkSecurityDetails = NetworkSecurityDetails
+  {
+    -- | Protocol name (e.g. "TLS 1.2" or "QUIC").
+    networkSecurityDetailsProtocol :: T.Text,
+    -- | Key Exchange used by the connection, or the empty string if not applicable.
+    networkSecurityDetailsKeyExchange :: T.Text,
+    -- | (EC)DH group used by the connection, if applicable.
+    networkSecurityDetailsKeyExchangeGroup :: Maybe T.Text,
+    -- | Cipher name.
+    networkSecurityDetailsCipher :: T.Text,
+    -- | TLS MAC. Note that AEAD ciphers do not have separate MACs.
+    networkSecurityDetailsMac :: Maybe T.Text,
+    -- | Certificate ID value.
+    networkSecurityDetailsCertificateId :: SecurityCertificateId,
+    -- | Certificate subject name.
+    networkSecurityDetailsSubjectName :: T.Text,
+    -- | Subject Alternative Name (SAN) DNS names and IP addresses.
+    networkSecurityDetailsSanList :: [T.Text],
+    -- | Name of the issuing CA.
+    networkSecurityDetailsIssuer :: T.Text,
+    -- | Certificate valid from date.
+    networkSecurityDetailsValidFrom :: NetworkTimeSinceEpoch,
+    -- | Certificate valid to (expiration) date
+    networkSecurityDetailsValidTo :: NetworkTimeSinceEpoch,
+    -- | List of signed certificate timestamps (SCTs).
+    networkSecurityDetailsSignedCertificateTimestampList :: [NetworkSignedCertificateTimestamp],
+    -- | Whether the request complied with Certificate Transparency policy
+    networkSecurityDetailsCertificateTransparencyCompliance :: NetworkCertificateTransparencyCompliance,
+    -- | The signature algorithm used by the server in the TLS server signature,
+    --   represented as a TLS SignatureScheme code point. Omitted if not
+    --   applicable or not known.
+    networkSecurityDetailsServerSignatureAlgorithm :: Maybe Int,
+    -- | Whether the connection used Encrypted ClientHello
+    networkSecurityDetailsEncryptedClientHello :: Bool
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkSecurityDetails where
+  parseJSON = A.withObject "NetworkSecurityDetails" $ \o -> NetworkSecurityDetails
+    <$> o A..: "protocol"
+    <*> o A..: "keyExchange"
+    <*> o A..:? "keyExchangeGroup"
+    <*> o A..: "cipher"
+    <*> o A..:? "mac"
+    <*> o A..: "certificateId"
+    <*> o A..: "subjectName"
+    <*> o A..: "sanList"
+    <*> o A..: "issuer"
+    <*> o A..: "validFrom"
+    <*> o A..: "validTo"
+    <*> o A..: "signedCertificateTimestampList"
+    <*> o A..: "certificateTransparencyCompliance"
+    <*> o A..:? "serverSignatureAlgorithm"
+    <*> o A..: "encryptedClientHello"
+instance ToJSON NetworkSecurityDetails where
+  toJSON p = A.object $ catMaybes [
+    ("protocol" A..=) <$> Just (networkSecurityDetailsProtocol p),
+    ("keyExchange" A..=) <$> Just (networkSecurityDetailsKeyExchange p),
+    ("keyExchangeGroup" A..=) <$> (networkSecurityDetailsKeyExchangeGroup p),
+    ("cipher" A..=) <$> Just (networkSecurityDetailsCipher p),
+    ("mac" A..=) <$> (networkSecurityDetailsMac p),
+    ("certificateId" A..=) <$> Just (networkSecurityDetailsCertificateId p),
+    ("subjectName" A..=) <$> Just (networkSecurityDetailsSubjectName p),
+    ("sanList" A..=) <$> Just (networkSecurityDetailsSanList p),
+    ("issuer" A..=) <$> Just (networkSecurityDetailsIssuer p),
+    ("validFrom" A..=) <$> Just (networkSecurityDetailsValidFrom p),
+    ("validTo" A..=) <$> Just (networkSecurityDetailsValidTo p),
+    ("signedCertificateTimestampList" A..=) <$> Just (networkSecurityDetailsSignedCertificateTimestampList p),
+    ("certificateTransparencyCompliance" A..=) <$> Just (networkSecurityDetailsCertificateTransparencyCompliance p),
+    ("serverSignatureAlgorithm" A..=) <$> (networkSecurityDetailsServerSignatureAlgorithm p),
+    ("encryptedClientHello" A..=) <$> Just (networkSecurityDetailsEncryptedClientHello p)
+    ]
+
+-- | Type 'Network.CertificateTransparencyCompliance'.
+--   Whether the request complied with Certificate Transparency policy.
+data NetworkCertificateTransparencyCompliance = NetworkCertificateTransparencyComplianceUnknown | NetworkCertificateTransparencyComplianceNotCompliant | NetworkCertificateTransparencyComplianceCompliant
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON NetworkCertificateTransparencyCompliance where
+  parseJSON = A.withText "NetworkCertificateTransparencyCompliance" $ \v -> case v of
+    "unknown" -> pure NetworkCertificateTransparencyComplianceUnknown
+    "not-compliant" -> pure NetworkCertificateTransparencyComplianceNotCompliant
+    "compliant" -> pure NetworkCertificateTransparencyComplianceCompliant
+    "_" -> fail "failed to parse NetworkCertificateTransparencyCompliance"
+instance ToJSON NetworkCertificateTransparencyCompliance where
+  toJSON v = A.String $ case v of
+    NetworkCertificateTransparencyComplianceUnknown -> "unknown"
+    NetworkCertificateTransparencyComplianceNotCompliant -> "not-compliant"
+    NetworkCertificateTransparencyComplianceCompliant -> "compliant"
+
+-- | Type 'Network.BlockedReason'.
+--   The reason why request was blocked.
+data NetworkBlockedReason = NetworkBlockedReasonOther | NetworkBlockedReasonCsp | NetworkBlockedReasonMixedContent | NetworkBlockedReasonOrigin | NetworkBlockedReasonInspector | NetworkBlockedReasonSubresourceFilter | NetworkBlockedReasonContentType | NetworkBlockedReasonCoepFrameResourceNeedsCoepHeader | NetworkBlockedReasonCoopSandboxedIframeCannotNavigateToCoopPage | NetworkBlockedReasonCorpNotSameOrigin | NetworkBlockedReasonCorpNotSameOriginAfterDefaultedToSameOriginByCoep | NetworkBlockedReasonCorpNotSameSite
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON NetworkBlockedReason where
+  parseJSON = A.withText "NetworkBlockedReason" $ \v -> case v of
+    "other" -> pure NetworkBlockedReasonOther
+    "csp" -> pure NetworkBlockedReasonCsp
+    "mixed-content" -> pure NetworkBlockedReasonMixedContent
+    "origin" -> pure NetworkBlockedReasonOrigin
+    "inspector" -> pure NetworkBlockedReasonInspector
+    "subresource-filter" -> pure NetworkBlockedReasonSubresourceFilter
+    "content-type" -> pure NetworkBlockedReasonContentType
+    "coep-frame-resource-needs-coep-header" -> pure NetworkBlockedReasonCoepFrameResourceNeedsCoepHeader
+    "coop-sandboxed-iframe-cannot-navigate-to-coop-page" -> pure NetworkBlockedReasonCoopSandboxedIframeCannotNavigateToCoopPage
+    "corp-not-same-origin" -> pure NetworkBlockedReasonCorpNotSameOrigin
+    "corp-not-same-origin-after-defaulted-to-same-origin-by-coep" -> pure NetworkBlockedReasonCorpNotSameOriginAfterDefaultedToSameOriginByCoep
+    "corp-not-same-site" -> pure NetworkBlockedReasonCorpNotSameSite
+    "_" -> fail "failed to parse NetworkBlockedReason"
+instance ToJSON NetworkBlockedReason where
+  toJSON v = A.String $ case v of
+    NetworkBlockedReasonOther -> "other"
+    NetworkBlockedReasonCsp -> "csp"
+    NetworkBlockedReasonMixedContent -> "mixed-content"
+    NetworkBlockedReasonOrigin -> "origin"
+    NetworkBlockedReasonInspector -> "inspector"
+    NetworkBlockedReasonSubresourceFilter -> "subresource-filter"
+    NetworkBlockedReasonContentType -> "content-type"
+    NetworkBlockedReasonCoepFrameResourceNeedsCoepHeader -> "coep-frame-resource-needs-coep-header"
+    NetworkBlockedReasonCoopSandboxedIframeCannotNavigateToCoopPage -> "coop-sandboxed-iframe-cannot-navigate-to-coop-page"
+    NetworkBlockedReasonCorpNotSameOrigin -> "corp-not-same-origin"
+    NetworkBlockedReasonCorpNotSameOriginAfterDefaultedToSameOriginByCoep -> "corp-not-same-origin-after-defaulted-to-same-origin-by-coep"
+    NetworkBlockedReasonCorpNotSameSite -> "corp-not-same-site"
+
+-- | Type 'Network.CorsError'.
+--   The reason why request was blocked.
+data NetworkCorsError = NetworkCorsErrorDisallowedByMode | NetworkCorsErrorInvalidResponse | NetworkCorsErrorWildcardOriginNotAllowed | NetworkCorsErrorMissingAllowOriginHeader | NetworkCorsErrorMultipleAllowOriginValues | NetworkCorsErrorInvalidAllowOriginValue | NetworkCorsErrorAllowOriginMismatch | NetworkCorsErrorInvalidAllowCredentials | NetworkCorsErrorCorsDisabledScheme | NetworkCorsErrorPreflightInvalidStatus | NetworkCorsErrorPreflightDisallowedRedirect | NetworkCorsErrorPreflightWildcardOriginNotAllowed | NetworkCorsErrorPreflightMissingAllowOriginHeader | NetworkCorsErrorPreflightMultipleAllowOriginValues | NetworkCorsErrorPreflightInvalidAllowOriginValue | NetworkCorsErrorPreflightAllowOriginMismatch | NetworkCorsErrorPreflightInvalidAllowCredentials | NetworkCorsErrorPreflightMissingAllowExternal | NetworkCorsErrorPreflightInvalidAllowExternal | NetworkCorsErrorPreflightMissingAllowPrivateNetwork | NetworkCorsErrorPreflightInvalidAllowPrivateNetwork | NetworkCorsErrorInvalidAllowMethodsPreflightResponse | NetworkCorsErrorInvalidAllowHeadersPreflightResponse | NetworkCorsErrorMethodDisallowedByPreflightResponse | NetworkCorsErrorHeaderDisallowedByPreflightResponse | NetworkCorsErrorRedirectContainsCredentials | NetworkCorsErrorInsecurePrivateNetwork | NetworkCorsErrorInvalidPrivateNetworkAccess | NetworkCorsErrorUnexpectedPrivateNetworkAccess | NetworkCorsErrorNoCorsRedirectModeNotFollow
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON NetworkCorsError where
+  parseJSON = A.withText "NetworkCorsError" $ \v -> case v of
+    "DisallowedByMode" -> pure NetworkCorsErrorDisallowedByMode
+    "InvalidResponse" -> pure NetworkCorsErrorInvalidResponse
+    "WildcardOriginNotAllowed" -> pure NetworkCorsErrorWildcardOriginNotAllowed
+    "MissingAllowOriginHeader" -> pure NetworkCorsErrorMissingAllowOriginHeader
+    "MultipleAllowOriginValues" -> pure NetworkCorsErrorMultipleAllowOriginValues
+    "InvalidAllowOriginValue" -> pure NetworkCorsErrorInvalidAllowOriginValue
+    "AllowOriginMismatch" -> pure NetworkCorsErrorAllowOriginMismatch
+    "InvalidAllowCredentials" -> pure NetworkCorsErrorInvalidAllowCredentials
+    "CorsDisabledScheme" -> pure NetworkCorsErrorCorsDisabledScheme
+    "PreflightInvalidStatus" -> pure NetworkCorsErrorPreflightInvalidStatus
+    "PreflightDisallowedRedirect" -> pure NetworkCorsErrorPreflightDisallowedRedirect
+    "PreflightWildcardOriginNotAllowed" -> pure NetworkCorsErrorPreflightWildcardOriginNotAllowed
+    "PreflightMissingAllowOriginHeader" -> pure NetworkCorsErrorPreflightMissingAllowOriginHeader
+    "PreflightMultipleAllowOriginValues" -> pure NetworkCorsErrorPreflightMultipleAllowOriginValues
+    "PreflightInvalidAllowOriginValue" -> pure NetworkCorsErrorPreflightInvalidAllowOriginValue
+    "PreflightAllowOriginMismatch" -> pure NetworkCorsErrorPreflightAllowOriginMismatch
+    "PreflightInvalidAllowCredentials" -> pure NetworkCorsErrorPreflightInvalidAllowCredentials
+    "PreflightMissingAllowExternal" -> pure NetworkCorsErrorPreflightMissingAllowExternal
+    "PreflightInvalidAllowExternal" -> pure NetworkCorsErrorPreflightInvalidAllowExternal
+    "PreflightMissingAllowPrivateNetwork" -> pure NetworkCorsErrorPreflightMissingAllowPrivateNetwork
+    "PreflightInvalidAllowPrivateNetwork" -> pure NetworkCorsErrorPreflightInvalidAllowPrivateNetwork
+    "InvalidAllowMethodsPreflightResponse" -> pure NetworkCorsErrorInvalidAllowMethodsPreflightResponse
+    "InvalidAllowHeadersPreflightResponse" -> pure NetworkCorsErrorInvalidAllowHeadersPreflightResponse
+    "MethodDisallowedByPreflightResponse" -> pure NetworkCorsErrorMethodDisallowedByPreflightResponse
+    "HeaderDisallowedByPreflightResponse" -> pure NetworkCorsErrorHeaderDisallowedByPreflightResponse
+    "RedirectContainsCredentials" -> pure NetworkCorsErrorRedirectContainsCredentials
+    "InsecurePrivateNetwork" -> pure NetworkCorsErrorInsecurePrivateNetwork
+    "InvalidPrivateNetworkAccess" -> pure NetworkCorsErrorInvalidPrivateNetworkAccess
+    "UnexpectedPrivateNetworkAccess" -> pure NetworkCorsErrorUnexpectedPrivateNetworkAccess
+    "NoCorsRedirectModeNotFollow" -> pure NetworkCorsErrorNoCorsRedirectModeNotFollow
+    "_" -> fail "failed to parse NetworkCorsError"
+instance ToJSON NetworkCorsError where
+  toJSON v = A.String $ case v of
+    NetworkCorsErrorDisallowedByMode -> "DisallowedByMode"
+    NetworkCorsErrorInvalidResponse -> "InvalidResponse"
+    NetworkCorsErrorWildcardOriginNotAllowed -> "WildcardOriginNotAllowed"
+    NetworkCorsErrorMissingAllowOriginHeader -> "MissingAllowOriginHeader"
+    NetworkCorsErrorMultipleAllowOriginValues -> "MultipleAllowOriginValues"
+    NetworkCorsErrorInvalidAllowOriginValue -> "InvalidAllowOriginValue"
+    NetworkCorsErrorAllowOriginMismatch -> "AllowOriginMismatch"
+    NetworkCorsErrorInvalidAllowCredentials -> "InvalidAllowCredentials"
+    NetworkCorsErrorCorsDisabledScheme -> "CorsDisabledScheme"
+    NetworkCorsErrorPreflightInvalidStatus -> "PreflightInvalidStatus"
+    NetworkCorsErrorPreflightDisallowedRedirect -> "PreflightDisallowedRedirect"
+    NetworkCorsErrorPreflightWildcardOriginNotAllowed -> "PreflightWildcardOriginNotAllowed"
+    NetworkCorsErrorPreflightMissingAllowOriginHeader -> "PreflightMissingAllowOriginHeader"
+    NetworkCorsErrorPreflightMultipleAllowOriginValues -> "PreflightMultipleAllowOriginValues"
+    NetworkCorsErrorPreflightInvalidAllowOriginValue -> "PreflightInvalidAllowOriginValue"
+    NetworkCorsErrorPreflightAllowOriginMismatch -> "PreflightAllowOriginMismatch"
+    NetworkCorsErrorPreflightInvalidAllowCredentials -> "PreflightInvalidAllowCredentials"
+    NetworkCorsErrorPreflightMissingAllowExternal -> "PreflightMissingAllowExternal"
+    NetworkCorsErrorPreflightInvalidAllowExternal -> "PreflightInvalidAllowExternal"
+    NetworkCorsErrorPreflightMissingAllowPrivateNetwork -> "PreflightMissingAllowPrivateNetwork"
+    NetworkCorsErrorPreflightInvalidAllowPrivateNetwork -> "PreflightInvalidAllowPrivateNetwork"
+    NetworkCorsErrorInvalidAllowMethodsPreflightResponse -> "InvalidAllowMethodsPreflightResponse"
+    NetworkCorsErrorInvalidAllowHeadersPreflightResponse -> "InvalidAllowHeadersPreflightResponse"
+    NetworkCorsErrorMethodDisallowedByPreflightResponse -> "MethodDisallowedByPreflightResponse"
+    NetworkCorsErrorHeaderDisallowedByPreflightResponse -> "HeaderDisallowedByPreflightResponse"
+    NetworkCorsErrorRedirectContainsCredentials -> "RedirectContainsCredentials"
+    NetworkCorsErrorInsecurePrivateNetwork -> "InsecurePrivateNetwork"
+    NetworkCorsErrorInvalidPrivateNetworkAccess -> "InvalidPrivateNetworkAccess"
+    NetworkCorsErrorUnexpectedPrivateNetworkAccess -> "UnexpectedPrivateNetworkAccess"
+    NetworkCorsErrorNoCorsRedirectModeNotFollow -> "NoCorsRedirectModeNotFollow"
+
+-- | Type 'Network.CorsErrorStatus'.
+data NetworkCorsErrorStatus = NetworkCorsErrorStatus
+  {
+    networkCorsErrorStatusCorsError :: NetworkCorsError,
+    networkCorsErrorStatusFailedParameter :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkCorsErrorStatus where
+  parseJSON = A.withObject "NetworkCorsErrorStatus" $ \o -> NetworkCorsErrorStatus
+    <$> o A..: "corsError"
+    <*> o A..: "failedParameter"
+instance ToJSON NetworkCorsErrorStatus where
+  toJSON p = A.object $ catMaybes [
+    ("corsError" A..=) <$> Just (networkCorsErrorStatusCorsError p),
+    ("failedParameter" A..=) <$> Just (networkCorsErrorStatusFailedParameter p)
+    ]
+
+-- | Type 'Network.ServiceWorkerResponseSource'.
+--   Source of serviceworker response.
+data NetworkServiceWorkerResponseSource = NetworkServiceWorkerResponseSourceCacheStorage | NetworkServiceWorkerResponseSourceHttpCache | NetworkServiceWorkerResponseSourceFallbackCode | NetworkServiceWorkerResponseSourceNetwork
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON NetworkServiceWorkerResponseSource where
+  parseJSON = A.withText "NetworkServiceWorkerResponseSource" $ \v -> case v of
+    "cache-storage" -> pure NetworkServiceWorkerResponseSourceCacheStorage
+    "http-cache" -> pure NetworkServiceWorkerResponseSourceHttpCache
+    "fallback-code" -> pure NetworkServiceWorkerResponseSourceFallbackCode
+    "network" -> pure NetworkServiceWorkerResponseSourceNetwork
+    "_" -> fail "failed to parse NetworkServiceWorkerResponseSource"
+instance ToJSON NetworkServiceWorkerResponseSource where
+  toJSON v = A.String $ case v of
+    NetworkServiceWorkerResponseSourceCacheStorage -> "cache-storage"
+    NetworkServiceWorkerResponseSourceHttpCache -> "http-cache"
+    NetworkServiceWorkerResponseSourceFallbackCode -> "fallback-code"
+    NetworkServiceWorkerResponseSourceNetwork -> "network"
+
+-- | Type 'Network.TrustTokenParams'.
+--   Determines what type of Trust Token operation is executed and
+--   depending on the type, some additional parameters. The values
+--   are specified in third_party/blink/renderer/core/fetch/trust_token.idl.
+data NetworkTrustTokenParamsRefreshPolicy = NetworkTrustTokenParamsRefreshPolicyUseCached | NetworkTrustTokenParamsRefreshPolicyRefresh
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON NetworkTrustTokenParamsRefreshPolicy where
+  parseJSON = A.withText "NetworkTrustTokenParamsRefreshPolicy" $ \v -> case v of
+    "UseCached" -> pure NetworkTrustTokenParamsRefreshPolicyUseCached
+    "Refresh" -> pure NetworkTrustTokenParamsRefreshPolicyRefresh
+    "_" -> fail "failed to parse NetworkTrustTokenParamsRefreshPolicy"
+instance ToJSON NetworkTrustTokenParamsRefreshPolicy where
+  toJSON v = A.String $ case v of
+    NetworkTrustTokenParamsRefreshPolicyUseCached -> "UseCached"
+    NetworkTrustTokenParamsRefreshPolicyRefresh -> "Refresh"
+data NetworkTrustTokenParams = NetworkTrustTokenParams
+  {
+    networkTrustTokenParamsType :: NetworkTrustTokenOperationType,
+    -- | Only set for "token-redemption" type and determine whether
+    --   to request a fresh SRR or use a still valid cached SRR.
+    networkTrustTokenParamsRefreshPolicy :: NetworkTrustTokenParamsRefreshPolicy,
+    -- | Origins of issuers from whom to request tokens or redemption
+    --   records.
+    networkTrustTokenParamsIssuers :: Maybe [T.Text]
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkTrustTokenParams where
+  parseJSON = A.withObject "NetworkTrustTokenParams" $ \o -> NetworkTrustTokenParams
+    <$> o A..: "type"
+    <*> o A..: "refreshPolicy"
+    <*> o A..:? "issuers"
+instance ToJSON NetworkTrustTokenParams where
+  toJSON p = A.object $ catMaybes [
+    ("type" A..=) <$> Just (networkTrustTokenParamsType p),
+    ("refreshPolicy" A..=) <$> Just (networkTrustTokenParamsRefreshPolicy p),
+    ("issuers" A..=) <$> (networkTrustTokenParamsIssuers p)
+    ]
+
+-- | Type 'Network.TrustTokenOperationType'.
+data NetworkTrustTokenOperationType = NetworkTrustTokenOperationTypeIssuance | NetworkTrustTokenOperationTypeRedemption | NetworkTrustTokenOperationTypeSigning
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON NetworkTrustTokenOperationType where
+  parseJSON = A.withText "NetworkTrustTokenOperationType" $ \v -> case v of
+    "Issuance" -> pure NetworkTrustTokenOperationTypeIssuance
+    "Redemption" -> pure NetworkTrustTokenOperationTypeRedemption
+    "Signing" -> pure NetworkTrustTokenOperationTypeSigning
+    "_" -> fail "failed to parse NetworkTrustTokenOperationType"
+instance ToJSON NetworkTrustTokenOperationType where
+  toJSON v = A.String $ case v of
+    NetworkTrustTokenOperationTypeIssuance -> "Issuance"
+    NetworkTrustTokenOperationTypeRedemption -> "Redemption"
+    NetworkTrustTokenOperationTypeSigning -> "Signing"
+
+-- | Type 'Network.AlternateProtocolUsage'.
+--   The reason why Chrome uses a specific transport protocol for HTTP semantics.
+data NetworkAlternateProtocolUsage = NetworkAlternateProtocolUsageAlternativeJobWonWithoutRace | NetworkAlternateProtocolUsageAlternativeJobWonRace | NetworkAlternateProtocolUsageMainJobWonRace | NetworkAlternateProtocolUsageMappingMissing | NetworkAlternateProtocolUsageBroken | NetworkAlternateProtocolUsageDnsAlpnH3JobWonWithoutRace | NetworkAlternateProtocolUsageDnsAlpnH3JobWonRace | NetworkAlternateProtocolUsageUnspecifiedReason
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON NetworkAlternateProtocolUsage where
+  parseJSON = A.withText "NetworkAlternateProtocolUsage" $ \v -> case v of
+    "alternativeJobWonWithoutRace" -> pure NetworkAlternateProtocolUsageAlternativeJobWonWithoutRace
+    "alternativeJobWonRace" -> pure NetworkAlternateProtocolUsageAlternativeJobWonRace
+    "mainJobWonRace" -> pure NetworkAlternateProtocolUsageMainJobWonRace
+    "mappingMissing" -> pure NetworkAlternateProtocolUsageMappingMissing
+    "broken" -> pure NetworkAlternateProtocolUsageBroken
+    "dnsAlpnH3JobWonWithoutRace" -> pure NetworkAlternateProtocolUsageDnsAlpnH3JobWonWithoutRace
+    "dnsAlpnH3JobWonRace" -> pure NetworkAlternateProtocolUsageDnsAlpnH3JobWonRace
+    "unspecifiedReason" -> pure NetworkAlternateProtocolUsageUnspecifiedReason
+    "_" -> fail "failed to parse NetworkAlternateProtocolUsage"
+instance ToJSON NetworkAlternateProtocolUsage where
+  toJSON v = A.String $ case v of
+    NetworkAlternateProtocolUsageAlternativeJobWonWithoutRace -> "alternativeJobWonWithoutRace"
+    NetworkAlternateProtocolUsageAlternativeJobWonRace -> "alternativeJobWonRace"
+    NetworkAlternateProtocolUsageMainJobWonRace -> "mainJobWonRace"
+    NetworkAlternateProtocolUsageMappingMissing -> "mappingMissing"
+    NetworkAlternateProtocolUsageBroken -> "broken"
+    NetworkAlternateProtocolUsageDnsAlpnH3JobWonWithoutRace -> "dnsAlpnH3JobWonWithoutRace"
+    NetworkAlternateProtocolUsageDnsAlpnH3JobWonRace -> "dnsAlpnH3JobWonRace"
+    NetworkAlternateProtocolUsageUnspecifiedReason -> "unspecifiedReason"
+
+-- | Type 'Network.Response'.
+--   HTTP response data.
+data NetworkResponse = NetworkResponse
+  {
+    -- | Response URL. This URL can be different from CachedResource.url in case of redirect.
+    networkResponseUrl :: T.Text,
+    -- | HTTP response status code.
+    networkResponseStatus :: Int,
+    -- | HTTP response status text.
+    networkResponseStatusText :: T.Text,
+    -- | HTTP response headers.
+    networkResponseHeaders :: NetworkHeaders,
+    -- | Resource mimeType as determined by the browser.
+    networkResponseMimeType :: T.Text,
+    -- | Refined HTTP request headers that were actually transmitted over the network.
+    networkResponseRequestHeaders :: Maybe NetworkHeaders,
+    -- | Specifies whether physical connection was actually reused for this request.
+    networkResponseConnectionReused :: Bool,
+    -- | Physical connection id that was actually used for this request.
+    networkResponseConnectionId :: Double,
+    -- | Remote IP address.
+    networkResponseRemoteIPAddress :: Maybe T.Text,
+    -- | Remote port.
+    networkResponseRemotePort :: Maybe Int,
+    -- | Specifies that the request was served from the disk cache.
+    networkResponseFromDiskCache :: Maybe Bool,
+    -- | Specifies that the request was served from the ServiceWorker.
+    networkResponseFromServiceWorker :: Maybe Bool,
+    -- | Specifies that the request was served from the prefetch cache.
+    networkResponseFromPrefetchCache :: Maybe Bool,
+    -- | Total number of bytes received for this request so far.
+    networkResponseEncodedDataLength :: Double,
+    -- | Timing information for the given request.
+    networkResponseTiming :: Maybe NetworkResourceTiming,
+    -- | Response source of response from ServiceWorker.
+    networkResponseServiceWorkerResponseSource :: Maybe NetworkServiceWorkerResponseSource,
+    -- | The time at which the returned response was generated.
+    networkResponseResponseTime :: Maybe NetworkTimeSinceEpoch,
+    -- | Cache Storage Cache Name.
+    networkResponseCacheStorageCacheName :: Maybe T.Text,
+    -- | Protocol used to fetch this request.
+    networkResponseProtocol :: Maybe T.Text,
+    -- | The reason why Chrome uses a specific transport protocol for HTTP semantics.
+    networkResponseAlternateProtocolUsage :: Maybe NetworkAlternateProtocolUsage,
+    -- | Security state of the request resource.
+    networkResponseSecurityState :: SecuritySecurityState,
+    -- | Security details for the request.
+    networkResponseSecurityDetails :: Maybe NetworkSecurityDetails
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkResponse where
+  parseJSON = A.withObject "NetworkResponse" $ \o -> NetworkResponse
+    <$> o A..: "url"
+    <*> o A..: "status"
+    <*> o A..: "statusText"
+    <*> o A..: "headers"
+    <*> o A..: "mimeType"
+    <*> o A..:? "requestHeaders"
+    <*> o A..: "connectionReused"
+    <*> o A..: "connectionId"
+    <*> o A..:? "remoteIPAddress"
+    <*> o A..:? "remotePort"
+    <*> o A..:? "fromDiskCache"
+    <*> o A..:? "fromServiceWorker"
+    <*> o A..:? "fromPrefetchCache"
+    <*> o A..: "encodedDataLength"
+    <*> o A..:? "timing"
+    <*> o A..:? "serviceWorkerResponseSource"
+    <*> o A..:? "responseTime"
+    <*> o A..:? "cacheStorageCacheName"
+    <*> o A..:? "protocol"
+    <*> o A..:? "alternateProtocolUsage"
+    <*> o A..: "securityState"
+    <*> o A..:? "securityDetails"
+instance ToJSON NetworkResponse where
+  toJSON p = A.object $ catMaybes [
+    ("url" A..=) <$> Just (networkResponseUrl p),
+    ("status" A..=) <$> Just (networkResponseStatus p),
+    ("statusText" A..=) <$> Just (networkResponseStatusText p),
+    ("headers" A..=) <$> Just (networkResponseHeaders p),
+    ("mimeType" A..=) <$> Just (networkResponseMimeType p),
+    ("requestHeaders" A..=) <$> (networkResponseRequestHeaders p),
+    ("connectionReused" A..=) <$> Just (networkResponseConnectionReused p),
+    ("connectionId" A..=) <$> Just (networkResponseConnectionId p),
+    ("remoteIPAddress" A..=) <$> (networkResponseRemoteIPAddress p),
+    ("remotePort" A..=) <$> (networkResponseRemotePort p),
+    ("fromDiskCache" A..=) <$> (networkResponseFromDiskCache p),
+    ("fromServiceWorker" A..=) <$> (networkResponseFromServiceWorker p),
+    ("fromPrefetchCache" A..=) <$> (networkResponseFromPrefetchCache p),
+    ("encodedDataLength" A..=) <$> Just (networkResponseEncodedDataLength p),
+    ("timing" A..=) <$> (networkResponseTiming p),
+    ("serviceWorkerResponseSource" A..=) <$> (networkResponseServiceWorkerResponseSource p),
+    ("responseTime" A..=) <$> (networkResponseResponseTime p),
+    ("cacheStorageCacheName" A..=) <$> (networkResponseCacheStorageCacheName p),
+    ("protocol" A..=) <$> (networkResponseProtocol p),
+    ("alternateProtocolUsage" A..=) <$> (networkResponseAlternateProtocolUsage p),
+    ("securityState" A..=) <$> Just (networkResponseSecurityState p),
+    ("securityDetails" A..=) <$> (networkResponseSecurityDetails p)
+    ]
+
+-- | Type 'Network.WebSocketRequest'.
+--   WebSocket request data.
+data NetworkWebSocketRequest = NetworkWebSocketRequest
+  {
+    -- | HTTP request headers.
+    networkWebSocketRequestHeaders :: NetworkHeaders
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkWebSocketRequest where
+  parseJSON = A.withObject "NetworkWebSocketRequest" $ \o -> NetworkWebSocketRequest
+    <$> o A..: "headers"
+instance ToJSON NetworkWebSocketRequest where
+  toJSON p = A.object $ catMaybes [
+    ("headers" A..=) <$> Just (networkWebSocketRequestHeaders p)
+    ]
+
+-- | Type 'Network.WebSocketResponse'.
+--   WebSocket response data.
+data NetworkWebSocketResponse = NetworkWebSocketResponse
+  {
+    -- | HTTP response status code.
+    networkWebSocketResponseStatus :: Int,
+    -- | HTTP response status text.
+    networkWebSocketResponseStatusText :: T.Text,
+    -- | HTTP response headers.
+    networkWebSocketResponseHeaders :: NetworkHeaders,
+    -- | HTTP response headers text.
+    networkWebSocketResponseHeadersText :: Maybe T.Text,
+    -- | HTTP request headers.
+    networkWebSocketResponseRequestHeaders :: Maybe NetworkHeaders,
+    -- | HTTP request headers text.
+    networkWebSocketResponseRequestHeadersText :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkWebSocketResponse where
+  parseJSON = A.withObject "NetworkWebSocketResponse" $ \o -> NetworkWebSocketResponse
+    <$> o A..: "status"
+    <*> o A..: "statusText"
+    <*> o A..: "headers"
+    <*> o A..:? "headersText"
+    <*> o A..:? "requestHeaders"
+    <*> o A..:? "requestHeadersText"
+instance ToJSON NetworkWebSocketResponse where
+  toJSON p = A.object $ catMaybes [
+    ("status" A..=) <$> Just (networkWebSocketResponseStatus p),
+    ("statusText" A..=) <$> Just (networkWebSocketResponseStatusText p),
+    ("headers" A..=) <$> Just (networkWebSocketResponseHeaders p),
+    ("headersText" A..=) <$> (networkWebSocketResponseHeadersText p),
+    ("requestHeaders" A..=) <$> (networkWebSocketResponseRequestHeaders p),
+    ("requestHeadersText" A..=) <$> (networkWebSocketResponseRequestHeadersText p)
+    ]
+
+-- | Type 'Network.WebSocketFrame'.
+--   WebSocket message data. This represents an entire WebSocket message, not just a fragmented frame as the name suggests.
+data NetworkWebSocketFrame = NetworkWebSocketFrame
+  {
+    -- | WebSocket message opcode.
+    networkWebSocketFrameOpcode :: Double,
+    -- | WebSocket message mask.
+    networkWebSocketFrameMask :: Bool,
+    -- | WebSocket message payload data.
+    --   If the opcode is 1, this is a text message and payloadData is a UTF-8 string.
+    --   If the opcode isn't 1, then payloadData is a base64 encoded string representing binary data.
+    networkWebSocketFramePayloadData :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkWebSocketFrame where
+  parseJSON = A.withObject "NetworkWebSocketFrame" $ \o -> NetworkWebSocketFrame
+    <$> o A..: "opcode"
+    <*> o A..: "mask"
+    <*> o A..: "payloadData"
+instance ToJSON NetworkWebSocketFrame where
+  toJSON p = A.object $ catMaybes [
+    ("opcode" A..=) <$> Just (networkWebSocketFrameOpcode p),
+    ("mask" A..=) <$> Just (networkWebSocketFrameMask p),
+    ("payloadData" A..=) <$> Just (networkWebSocketFramePayloadData p)
+    ]
+
+-- | Type 'Network.CachedResource'.
+--   Information about the cached resource.
+data NetworkCachedResource = NetworkCachedResource
+  {
+    -- | Resource URL. This is the url of the original network request.
+    networkCachedResourceUrl :: T.Text,
+    -- | Type of this resource.
+    networkCachedResourceType :: NetworkResourceType,
+    -- | Cached response data.
+    networkCachedResourceResponse :: Maybe NetworkResponse,
+    -- | Cached response body size.
+    networkCachedResourceBodySize :: Double
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkCachedResource where
+  parseJSON = A.withObject "NetworkCachedResource" $ \o -> NetworkCachedResource
+    <$> o A..: "url"
+    <*> o A..: "type"
+    <*> o A..:? "response"
+    <*> o A..: "bodySize"
+instance ToJSON NetworkCachedResource where
+  toJSON p = A.object $ catMaybes [
+    ("url" A..=) <$> Just (networkCachedResourceUrl p),
+    ("type" A..=) <$> Just (networkCachedResourceType p),
+    ("response" A..=) <$> (networkCachedResourceResponse p),
+    ("bodySize" A..=) <$> Just (networkCachedResourceBodySize p)
+    ]
+
+-- | Type 'Network.Initiator'.
+--   Information about the request initiator.
+data NetworkInitiatorType = NetworkInitiatorTypeParser | NetworkInitiatorTypeScript | NetworkInitiatorTypePreload | NetworkInitiatorTypeSignedExchange | NetworkInitiatorTypePreflight | NetworkInitiatorTypeOther
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON NetworkInitiatorType where
+  parseJSON = A.withText "NetworkInitiatorType" $ \v -> case v of
+    "parser" -> pure NetworkInitiatorTypeParser
+    "script" -> pure NetworkInitiatorTypeScript
+    "preload" -> pure NetworkInitiatorTypePreload
+    "SignedExchange" -> pure NetworkInitiatorTypeSignedExchange
+    "preflight" -> pure NetworkInitiatorTypePreflight
+    "other" -> pure NetworkInitiatorTypeOther
+    "_" -> fail "failed to parse NetworkInitiatorType"
+instance ToJSON NetworkInitiatorType where
+  toJSON v = A.String $ case v of
+    NetworkInitiatorTypeParser -> "parser"
+    NetworkInitiatorTypeScript -> "script"
+    NetworkInitiatorTypePreload -> "preload"
+    NetworkInitiatorTypeSignedExchange -> "SignedExchange"
+    NetworkInitiatorTypePreflight -> "preflight"
+    NetworkInitiatorTypeOther -> "other"
+data NetworkInitiator = NetworkInitiator
+  {
+    -- | Type of this initiator.
+    networkInitiatorType :: NetworkInitiatorType,
+    -- | Initiator JavaScript stack trace, set for Script only.
+    networkInitiatorStack :: Maybe Runtime.RuntimeStackTrace,
+    -- | Initiator URL, set for Parser type or for Script type (when script is importing module) or for SignedExchange type.
+    networkInitiatorUrl :: Maybe T.Text,
+    -- | Initiator line number, set for Parser type or for Script type (when script is importing
+    --   module) (0-based).
+    networkInitiatorLineNumber :: Maybe Double,
+    -- | Initiator column number, set for Parser type or for Script type (when script is importing
+    --   module) (0-based).
+    networkInitiatorColumnNumber :: Maybe Double,
+    -- | Set if another request triggered this request (e.g. preflight).
+    networkInitiatorRequestId :: Maybe NetworkRequestId
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkInitiator where
+  parseJSON = A.withObject "NetworkInitiator" $ \o -> NetworkInitiator
+    <$> o A..: "type"
+    <*> o A..:? "stack"
+    <*> o A..:? "url"
+    <*> o A..:? "lineNumber"
+    <*> o A..:? "columnNumber"
+    <*> o A..:? "requestId"
+instance ToJSON NetworkInitiator where
+  toJSON p = A.object $ catMaybes [
+    ("type" A..=) <$> Just (networkInitiatorType p),
+    ("stack" A..=) <$> (networkInitiatorStack p),
+    ("url" A..=) <$> (networkInitiatorUrl p),
+    ("lineNumber" A..=) <$> (networkInitiatorLineNumber p),
+    ("columnNumber" A..=) <$> (networkInitiatorColumnNumber p),
+    ("requestId" A..=) <$> (networkInitiatorRequestId p)
+    ]
+
+-- | Type 'Network.Cookie'.
+--   Cookie object
+data NetworkCookie = NetworkCookie
+  {
+    -- | Cookie name.
+    networkCookieName :: T.Text,
+    -- | Cookie value.
+    networkCookieValue :: T.Text,
+    -- | Cookie domain.
+    networkCookieDomain :: T.Text,
+    -- | Cookie path.
+    networkCookiePath :: T.Text,
+    -- | Cookie expiration date as the number of seconds since the UNIX epoch.
+    networkCookieExpires :: Double,
+    -- | Cookie size.
+    networkCookieSize :: Int,
+    -- | True if cookie is http-only.
+    networkCookieHttpOnly :: Bool,
+    -- | True if cookie is secure.
+    networkCookieSecure :: Bool,
+    -- | True in case of session cookie.
+    networkCookieSession :: Bool,
+    -- | Cookie SameSite type.
+    networkCookieSameSite :: Maybe NetworkCookieSameSite,
+    -- | Cookie Priority
+    networkCookiePriority :: NetworkCookiePriority,
+    -- | True if cookie is SameParty.
+    networkCookieSameParty :: Bool,
+    -- | Cookie source scheme type.
+    networkCookieSourceScheme :: NetworkCookieSourceScheme,
+    -- | Cookie source port. Valid values are {-1, [1, 65535]}, -1 indicates an unspecified port.
+    --   An unspecified port value allows protocol clients to emulate legacy cookie scope for the port.
+    --   This is a temporary ability and it will be removed in the future.
+    networkCookieSourcePort :: Int,
+    -- | Cookie partition key. The site of the top-level URL the browser was visiting at the start
+    --   of the request to the endpoint that set the cookie.
+    networkCookiePartitionKey :: Maybe T.Text,
+    -- | True if cookie partition key is opaque.
+    networkCookiePartitionKeyOpaque :: Maybe Bool
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkCookie where
+  parseJSON = A.withObject "NetworkCookie" $ \o -> NetworkCookie
+    <$> o A..: "name"
+    <*> o A..: "value"
+    <*> o A..: "domain"
+    <*> o A..: "path"
+    <*> o A..: "expires"
+    <*> o A..: "size"
+    <*> o A..: "httpOnly"
+    <*> o A..: "secure"
+    <*> o A..: "session"
+    <*> o A..:? "sameSite"
+    <*> o A..: "priority"
+    <*> o A..: "sameParty"
+    <*> o A..: "sourceScheme"
+    <*> o A..: "sourcePort"
+    <*> o A..:? "partitionKey"
+    <*> o A..:? "partitionKeyOpaque"
+instance ToJSON NetworkCookie where
+  toJSON p = A.object $ catMaybes [
+    ("name" A..=) <$> Just (networkCookieName p),
+    ("value" A..=) <$> Just (networkCookieValue p),
+    ("domain" A..=) <$> Just (networkCookieDomain p),
+    ("path" A..=) <$> Just (networkCookiePath p),
+    ("expires" A..=) <$> Just (networkCookieExpires p),
+    ("size" A..=) <$> Just (networkCookieSize p),
+    ("httpOnly" A..=) <$> Just (networkCookieHttpOnly p),
+    ("secure" A..=) <$> Just (networkCookieSecure p),
+    ("session" A..=) <$> Just (networkCookieSession p),
+    ("sameSite" A..=) <$> (networkCookieSameSite p),
+    ("priority" A..=) <$> Just (networkCookiePriority p),
+    ("sameParty" A..=) <$> Just (networkCookieSameParty p),
+    ("sourceScheme" A..=) <$> Just (networkCookieSourceScheme p),
+    ("sourcePort" A..=) <$> Just (networkCookieSourcePort p),
+    ("partitionKey" A..=) <$> (networkCookiePartitionKey p),
+    ("partitionKeyOpaque" A..=) <$> (networkCookiePartitionKeyOpaque p)
+    ]
+
+-- | Type 'Network.SetCookieBlockedReason'.
+--   Types of reasons why a cookie may not be stored from a response.
+data NetworkSetCookieBlockedReason = NetworkSetCookieBlockedReasonSecureOnly | NetworkSetCookieBlockedReasonSameSiteStrict | NetworkSetCookieBlockedReasonSameSiteLax | NetworkSetCookieBlockedReasonSameSiteUnspecifiedTreatedAsLax | NetworkSetCookieBlockedReasonSameSiteNoneInsecure | NetworkSetCookieBlockedReasonUserPreferences | NetworkSetCookieBlockedReasonSyntaxError | NetworkSetCookieBlockedReasonSchemeNotSupported | NetworkSetCookieBlockedReasonOverwriteSecure | NetworkSetCookieBlockedReasonInvalidDomain | NetworkSetCookieBlockedReasonInvalidPrefix | NetworkSetCookieBlockedReasonUnknownError | NetworkSetCookieBlockedReasonSchemefulSameSiteStrict | NetworkSetCookieBlockedReasonSchemefulSameSiteLax | NetworkSetCookieBlockedReasonSchemefulSameSiteUnspecifiedTreatedAsLax | NetworkSetCookieBlockedReasonSamePartyFromCrossPartyContext | NetworkSetCookieBlockedReasonSamePartyConflictsWithOtherAttributes | NetworkSetCookieBlockedReasonNameValuePairExceedsMaxSize
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON NetworkSetCookieBlockedReason where
+  parseJSON = A.withText "NetworkSetCookieBlockedReason" $ \v -> case v of
+    "SecureOnly" -> pure NetworkSetCookieBlockedReasonSecureOnly
+    "SameSiteStrict" -> pure NetworkSetCookieBlockedReasonSameSiteStrict
+    "SameSiteLax" -> pure NetworkSetCookieBlockedReasonSameSiteLax
+    "SameSiteUnspecifiedTreatedAsLax" -> pure NetworkSetCookieBlockedReasonSameSiteUnspecifiedTreatedAsLax
+    "SameSiteNoneInsecure" -> pure NetworkSetCookieBlockedReasonSameSiteNoneInsecure
+    "UserPreferences" -> pure NetworkSetCookieBlockedReasonUserPreferences
+    "SyntaxError" -> pure NetworkSetCookieBlockedReasonSyntaxError
+    "SchemeNotSupported" -> pure NetworkSetCookieBlockedReasonSchemeNotSupported
+    "OverwriteSecure" -> pure NetworkSetCookieBlockedReasonOverwriteSecure
+    "InvalidDomain" -> pure NetworkSetCookieBlockedReasonInvalidDomain
+    "InvalidPrefix" -> pure NetworkSetCookieBlockedReasonInvalidPrefix
+    "UnknownError" -> pure NetworkSetCookieBlockedReasonUnknownError
+    "SchemefulSameSiteStrict" -> pure NetworkSetCookieBlockedReasonSchemefulSameSiteStrict
+    "SchemefulSameSiteLax" -> pure NetworkSetCookieBlockedReasonSchemefulSameSiteLax
+    "SchemefulSameSiteUnspecifiedTreatedAsLax" -> pure NetworkSetCookieBlockedReasonSchemefulSameSiteUnspecifiedTreatedAsLax
+    "SamePartyFromCrossPartyContext" -> pure NetworkSetCookieBlockedReasonSamePartyFromCrossPartyContext
+    "SamePartyConflictsWithOtherAttributes" -> pure NetworkSetCookieBlockedReasonSamePartyConflictsWithOtherAttributes
+    "NameValuePairExceedsMaxSize" -> pure NetworkSetCookieBlockedReasonNameValuePairExceedsMaxSize
+    "_" -> fail "failed to parse NetworkSetCookieBlockedReason"
+instance ToJSON NetworkSetCookieBlockedReason where
+  toJSON v = A.String $ case v of
+    NetworkSetCookieBlockedReasonSecureOnly -> "SecureOnly"
+    NetworkSetCookieBlockedReasonSameSiteStrict -> "SameSiteStrict"
+    NetworkSetCookieBlockedReasonSameSiteLax -> "SameSiteLax"
+    NetworkSetCookieBlockedReasonSameSiteUnspecifiedTreatedAsLax -> "SameSiteUnspecifiedTreatedAsLax"
+    NetworkSetCookieBlockedReasonSameSiteNoneInsecure -> "SameSiteNoneInsecure"
+    NetworkSetCookieBlockedReasonUserPreferences -> "UserPreferences"
+    NetworkSetCookieBlockedReasonSyntaxError -> "SyntaxError"
+    NetworkSetCookieBlockedReasonSchemeNotSupported -> "SchemeNotSupported"
+    NetworkSetCookieBlockedReasonOverwriteSecure -> "OverwriteSecure"
+    NetworkSetCookieBlockedReasonInvalidDomain -> "InvalidDomain"
+    NetworkSetCookieBlockedReasonInvalidPrefix -> "InvalidPrefix"
+    NetworkSetCookieBlockedReasonUnknownError -> "UnknownError"
+    NetworkSetCookieBlockedReasonSchemefulSameSiteStrict -> "SchemefulSameSiteStrict"
+    NetworkSetCookieBlockedReasonSchemefulSameSiteLax -> "SchemefulSameSiteLax"
+    NetworkSetCookieBlockedReasonSchemefulSameSiteUnspecifiedTreatedAsLax -> "SchemefulSameSiteUnspecifiedTreatedAsLax"
+    NetworkSetCookieBlockedReasonSamePartyFromCrossPartyContext -> "SamePartyFromCrossPartyContext"
+    NetworkSetCookieBlockedReasonSamePartyConflictsWithOtherAttributes -> "SamePartyConflictsWithOtherAttributes"
+    NetworkSetCookieBlockedReasonNameValuePairExceedsMaxSize -> "NameValuePairExceedsMaxSize"
+
+-- | Type 'Network.CookieBlockedReason'.
+--   Types of reasons why a cookie may not be sent with a request.
+data NetworkCookieBlockedReason = NetworkCookieBlockedReasonSecureOnly | NetworkCookieBlockedReasonNotOnPath | NetworkCookieBlockedReasonDomainMismatch | NetworkCookieBlockedReasonSameSiteStrict | NetworkCookieBlockedReasonSameSiteLax | NetworkCookieBlockedReasonSameSiteUnspecifiedTreatedAsLax | NetworkCookieBlockedReasonSameSiteNoneInsecure | NetworkCookieBlockedReasonUserPreferences | NetworkCookieBlockedReasonUnknownError | NetworkCookieBlockedReasonSchemefulSameSiteStrict | NetworkCookieBlockedReasonSchemefulSameSiteLax | NetworkCookieBlockedReasonSchemefulSameSiteUnspecifiedTreatedAsLax | NetworkCookieBlockedReasonSamePartyFromCrossPartyContext | NetworkCookieBlockedReasonNameValuePairExceedsMaxSize
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON NetworkCookieBlockedReason where
+  parseJSON = A.withText "NetworkCookieBlockedReason" $ \v -> case v of
+    "SecureOnly" -> pure NetworkCookieBlockedReasonSecureOnly
+    "NotOnPath" -> pure NetworkCookieBlockedReasonNotOnPath
+    "DomainMismatch" -> pure NetworkCookieBlockedReasonDomainMismatch
+    "SameSiteStrict" -> pure NetworkCookieBlockedReasonSameSiteStrict
+    "SameSiteLax" -> pure NetworkCookieBlockedReasonSameSiteLax
+    "SameSiteUnspecifiedTreatedAsLax" -> pure NetworkCookieBlockedReasonSameSiteUnspecifiedTreatedAsLax
+    "SameSiteNoneInsecure" -> pure NetworkCookieBlockedReasonSameSiteNoneInsecure
+    "UserPreferences" -> pure NetworkCookieBlockedReasonUserPreferences
+    "UnknownError" -> pure NetworkCookieBlockedReasonUnknownError
+    "SchemefulSameSiteStrict" -> pure NetworkCookieBlockedReasonSchemefulSameSiteStrict
+    "SchemefulSameSiteLax" -> pure NetworkCookieBlockedReasonSchemefulSameSiteLax
+    "SchemefulSameSiteUnspecifiedTreatedAsLax" -> pure NetworkCookieBlockedReasonSchemefulSameSiteUnspecifiedTreatedAsLax
+    "SamePartyFromCrossPartyContext" -> pure NetworkCookieBlockedReasonSamePartyFromCrossPartyContext
+    "NameValuePairExceedsMaxSize" -> pure NetworkCookieBlockedReasonNameValuePairExceedsMaxSize
+    "_" -> fail "failed to parse NetworkCookieBlockedReason"
+instance ToJSON NetworkCookieBlockedReason where
+  toJSON v = A.String $ case v of
+    NetworkCookieBlockedReasonSecureOnly -> "SecureOnly"
+    NetworkCookieBlockedReasonNotOnPath -> "NotOnPath"
+    NetworkCookieBlockedReasonDomainMismatch -> "DomainMismatch"
+    NetworkCookieBlockedReasonSameSiteStrict -> "SameSiteStrict"
+    NetworkCookieBlockedReasonSameSiteLax -> "SameSiteLax"
+    NetworkCookieBlockedReasonSameSiteUnspecifiedTreatedAsLax -> "SameSiteUnspecifiedTreatedAsLax"
+    NetworkCookieBlockedReasonSameSiteNoneInsecure -> "SameSiteNoneInsecure"
+    NetworkCookieBlockedReasonUserPreferences -> "UserPreferences"
+    NetworkCookieBlockedReasonUnknownError -> "UnknownError"
+    NetworkCookieBlockedReasonSchemefulSameSiteStrict -> "SchemefulSameSiteStrict"
+    NetworkCookieBlockedReasonSchemefulSameSiteLax -> "SchemefulSameSiteLax"
+    NetworkCookieBlockedReasonSchemefulSameSiteUnspecifiedTreatedAsLax -> "SchemefulSameSiteUnspecifiedTreatedAsLax"
+    NetworkCookieBlockedReasonSamePartyFromCrossPartyContext -> "SamePartyFromCrossPartyContext"
+    NetworkCookieBlockedReasonNameValuePairExceedsMaxSize -> "NameValuePairExceedsMaxSize"
+
+-- | Type 'Network.BlockedSetCookieWithReason'.
+--   A cookie which was not stored from a response with the corresponding reason.
+data NetworkBlockedSetCookieWithReason = NetworkBlockedSetCookieWithReason
+  {
+    -- | The reason(s) this cookie was blocked.
+    networkBlockedSetCookieWithReasonBlockedReasons :: [NetworkSetCookieBlockedReason],
+    -- | The string representing this individual cookie as it would appear in the header.
+    --   This is not the entire "cookie" or "set-cookie" header which could have multiple cookies.
+    networkBlockedSetCookieWithReasonCookieLine :: T.Text,
+    -- | The cookie object which represents the cookie which was not stored. It is optional because
+    --   sometimes complete cookie information is not available, such as in the case of parsing
+    --   errors.
+    networkBlockedSetCookieWithReasonCookie :: Maybe NetworkCookie
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkBlockedSetCookieWithReason where
+  parseJSON = A.withObject "NetworkBlockedSetCookieWithReason" $ \o -> NetworkBlockedSetCookieWithReason
+    <$> o A..: "blockedReasons"
+    <*> o A..: "cookieLine"
+    <*> o A..:? "cookie"
+instance ToJSON NetworkBlockedSetCookieWithReason where
+  toJSON p = A.object $ catMaybes [
+    ("blockedReasons" A..=) <$> Just (networkBlockedSetCookieWithReasonBlockedReasons p),
+    ("cookieLine" A..=) <$> Just (networkBlockedSetCookieWithReasonCookieLine p),
+    ("cookie" A..=) <$> (networkBlockedSetCookieWithReasonCookie p)
+    ]
+
+-- | Type 'Network.BlockedCookieWithReason'.
+--   A cookie with was not sent with a request with the corresponding reason.
+data NetworkBlockedCookieWithReason = NetworkBlockedCookieWithReason
+  {
+    -- | The reason(s) the cookie was blocked.
+    networkBlockedCookieWithReasonBlockedReasons :: [NetworkCookieBlockedReason],
+    -- | The cookie object representing the cookie which was not sent.
+    networkBlockedCookieWithReasonCookie :: NetworkCookie
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkBlockedCookieWithReason where
+  parseJSON = A.withObject "NetworkBlockedCookieWithReason" $ \o -> NetworkBlockedCookieWithReason
+    <$> o A..: "blockedReasons"
+    <*> o A..: "cookie"
+instance ToJSON NetworkBlockedCookieWithReason where
+  toJSON p = A.object $ catMaybes [
+    ("blockedReasons" A..=) <$> Just (networkBlockedCookieWithReasonBlockedReasons p),
+    ("cookie" A..=) <$> Just (networkBlockedCookieWithReasonCookie p)
+    ]
+
+-- | Type 'Network.CookieParam'.
+--   Cookie parameter object
+data NetworkCookieParam = NetworkCookieParam
+  {
+    -- | Cookie name.
+    networkCookieParamName :: T.Text,
+    -- | Cookie value.
+    networkCookieParamValue :: T.Text,
+    -- | The request-URI to associate with the setting of the cookie. This value can affect the
+    --   default domain, path, source port, and source scheme values of the created cookie.
+    networkCookieParamUrl :: Maybe T.Text,
+    -- | Cookie domain.
+    networkCookieParamDomain :: Maybe T.Text,
+    -- | Cookie path.
+    networkCookieParamPath :: Maybe T.Text,
+    -- | True if cookie is secure.
+    networkCookieParamSecure :: Maybe Bool,
+    -- | True if cookie is http-only.
+    networkCookieParamHttpOnly :: Maybe Bool,
+    -- | Cookie SameSite type.
+    networkCookieParamSameSite :: Maybe NetworkCookieSameSite,
+    -- | Cookie expiration date, session cookie if not set
+    networkCookieParamExpires :: Maybe NetworkTimeSinceEpoch,
+    -- | Cookie Priority.
+    networkCookieParamPriority :: Maybe NetworkCookiePriority,
+    -- | True if cookie is SameParty.
+    networkCookieParamSameParty :: Maybe Bool,
+    -- | Cookie source scheme type.
+    networkCookieParamSourceScheme :: Maybe NetworkCookieSourceScheme,
+    -- | Cookie source port. Valid values are {-1, [1, 65535]}, -1 indicates an unspecified port.
+    --   An unspecified port value allows protocol clients to emulate legacy cookie scope for the port.
+    --   This is a temporary ability and it will be removed in the future.
+    networkCookieParamSourcePort :: Maybe Int,
+    -- | Cookie partition key. The site of the top-level URL the browser was visiting at the start
+    --   of the request to the endpoint that set the cookie.
+    --   If not set, the cookie will be set as not partitioned.
+    networkCookieParamPartitionKey :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkCookieParam where
+  parseJSON = A.withObject "NetworkCookieParam" $ \o -> NetworkCookieParam
+    <$> o A..: "name"
+    <*> o A..: "value"
+    <*> o A..:? "url"
+    <*> o A..:? "domain"
+    <*> o A..:? "path"
+    <*> o A..:? "secure"
+    <*> o A..:? "httpOnly"
+    <*> o A..:? "sameSite"
+    <*> o A..:? "expires"
+    <*> o A..:? "priority"
+    <*> o A..:? "sameParty"
+    <*> o A..:? "sourceScheme"
+    <*> o A..:? "sourcePort"
+    <*> o A..:? "partitionKey"
+instance ToJSON NetworkCookieParam where
+  toJSON p = A.object $ catMaybes [
+    ("name" A..=) <$> Just (networkCookieParamName p),
+    ("value" A..=) <$> Just (networkCookieParamValue p),
+    ("url" A..=) <$> (networkCookieParamUrl p),
+    ("domain" A..=) <$> (networkCookieParamDomain p),
+    ("path" A..=) <$> (networkCookieParamPath p),
+    ("secure" A..=) <$> (networkCookieParamSecure p),
+    ("httpOnly" A..=) <$> (networkCookieParamHttpOnly p),
+    ("sameSite" A..=) <$> (networkCookieParamSameSite p),
+    ("expires" A..=) <$> (networkCookieParamExpires p),
+    ("priority" A..=) <$> (networkCookieParamPriority p),
+    ("sameParty" A..=) <$> (networkCookieParamSameParty p),
+    ("sourceScheme" A..=) <$> (networkCookieParamSourceScheme p),
+    ("sourcePort" A..=) <$> (networkCookieParamSourcePort p),
+    ("partitionKey" A..=) <$> (networkCookieParamPartitionKey p)
+    ]
+
+-- | Type 'Network.AuthChallenge'.
+--   Authorization challenge for HTTP status code 401 or 407.
+data NetworkAuthChallengeSource = NetworkAuthChallengeSourceServer | NetworkAuthChallengeSourceProxy
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON NetworkAuthChallengeSource where
+  parseJSON = A.withText "NetworkAuthChallengeSource" $ \v -> case v of
+    "Server" -> pure NetworkAuthChallengeSourceServer
+    "Proxy" -> pure NetworkAuthChallengeSourceProxy
+    "_" -> fail "failed to parse NetworkAuthChallengeSource"
+instance ToJSON NetworkAuthChallengeSource where
+  toJSON v = A.String $ case v of
+    NetworkAuthChallengeSourceServer -> "Server"
+    NetworkAuthChallengeSourceProxy -> "Proxy"
+data NetworkAuthChallenge = NetworkAuthChallenge
+  {
+    -- | Source of the authentication challenge.
+    networkAuthChallengeSource :: Maybe NetworkAuthChallengeSource,
+    -- | Origin of the challenger.
+    networkAuthChallengeOrigin :: T.Text,
+    -- | The authentication scheme used, such as basic or digest
+    networkAuthChallengeScheme :: T.Text,
+    -- | The realm of the challenge. May be empty.
+    networkAuthChallengeRealm :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkAuthChallenge where
+  parseJSON = A.withObject "NetworkAuthChallenge" $ \o -> NetworkAuthChallenge
+    <$> o A..:? "source"
+    <*> o A..: "origin"
+    <*> o A..: "scheme"
+    <*> o A..: "realm"
+instance ToJSON NetworkAuthChallenge where
+  toJSON p = A.object $ catMaybes [
+    ("source" A..=) <$> (networkAuthChallengeSource p),
+    ("origin" A..=) <$> Just (networkAuthChallengeOrigin p),
+    ("scheme" A..=) <$> Just (networkAuthChallengeScheme p),
+    ("realm" A..=) <$> Just (networkAuthChallengeRealm p)
+    ]
+
+-- | Type 'Network.AuthChallengeResponse'.
+--   Response to an AuthChallenge.
+data NetworkAuthChallengeResponseResponse = NetworkAuthChallengeResponseResponseDefault | NetworkAuthChallengeResponseResponseCancelAuth | NetworkAuthChallengeResponseResponseProvideCredentials
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON NetworkAuthChallengeResponseResponse where
+  parseJSON = A.withText "NetworkAuthChallengeResponseResponse" $ \v -> case v of
+    "Default" -> pure NetworkAuthChallengeResponseResponseDefault
+    "CancelAuth" -> pure NetworkAuthChallengeResponseResponseCancelAuth
+    "ProvideCredentials" -> pure NetworkAuthChallengeResponseResponseProvideCredentials
+    "_" -> fail "failed to parse NetworkAuthChallengeResponseResponse"
+instance ToJSON NetworkAuthChallengeResponseResponse where
+  toJSON v = A.String $ case v of
+    NetworkAuthChallengeResponseResponseDefault -> "Default"
+    NetworkAuthChallengeResponseResponseCancelAuth -> "CancelAuth"
+    NetworkAuthChallengeResponseResponseProvideCredentials -> "ProvideCredentials"
+data NetworkAuthChallengeResponse = NetworkAuthChallengeResponse
+  {
+    -- | The decision on what to do in response to the authorization challenge.  Default means
+    --   deferring to the default behavior of the net stack, which will likely either the Cancel
+    --   authentication or display a popup dialog box.
+    networkAuthChallengeResponseResponse :: NetworkAuthChallengeResponseResponse,
+    -- | The username to provide, possibly empty. Should only be set if response is
+    --   ProvideCredentials.
+    networkAuthChallengeResponseUsername :: Maybe T.Text,
+    -- | The password to provide, possibly empty. Should only be set if response is
+    --   ProvideCredentials.
+    networkAuthChallengeResponsePassword :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkAuthChallengeResponse where
+  parseJSON = A.withObject "NetworkAuthChallengeResponse" $ \o -> NetworkAuthChallengeResponse
+    <$> o A..: "response"
+    <*> o A..:? "username"
+    <*> o A..:? "password"
+instance ToJSON NetworkAuthChallengeResponse where
+  toJSON p = A.object $ catMaybes [
+    ("response" A..=) <$> Just (networkAuthChallengeResponseResponse p),
+    ("username" A..=) <$> (networkAuthChallengeResponseUsername p),
+    ("password" A..=) <$> (networkAuthChallengeResponsePassword p)
+    ]
+
+-- | Type 'Network.InterceptionStage'.
+--   Stages of the interception to begin intercepting. Request will intercept before the request is
+--   sent. Response will intercept after the response is received.
+data NetworkInterceptionStage = NetworkInterceptionStageRequest | NetworkInterceptionStageHeadersReceived
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON NetworkInterceptionStage where
+  parseJSON = A.withText "NetworkInterceptionStage" $ \v -> case v of
+    "Request" -> pure NetworkInterceptionStageRequest
+    "HeadersReceived" -> pure NetworkInterceptionStageHeadersReceived
+    "_" -> fail "failed to parse NetworkInterceptionStage"
+instance ToJSON NetworkInterceptionStage where
+  toJSON v = A.String $ case v of
+    NetworkInterceptionStageRequest -> "Request"
+    NetworkInterceptionStageHeadersReceived -> "HeadersReceived"
+
+-- | Type 'Network.RequestPattern'.
+--   Request pattern for interception.
+data NetworkRequestPattern = NetworkRequestPattern
+  {
+    -- | Wildcards (`'*'` -> zero or more, `'?'` -> exactly one) are allowed. Escape character is
+    --   backslash. Omitting is equivalent to `"*"`.
+    networkRequestPatternUrlPattern :: Maybe T.Text,
+    -- | If set, only requests for matching resource types will be intercepted.
+    networkRequestPatternResourceType :: Maybe NetworkResourceType,
+    -- | Stage at which to begin intercepting requests. Default is Request.
+    networkRequestPatternInterceptionStage :: Maybe NetworkInterceptionStage
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkRequestPattern where
+  parseJSON = A.withObject "NetworkRequestPattern" $ \o -> NetworkRequestPattern
+    <$> o A..:? "urlPattern"
+    <*> o A..:? "resourceType"
+    <*> o A..:? "interceptionStage"
+instance ToJSON NetworkRequestPattern where
+  toJSON p = A.object $ catMaybes [
+    ("urlPattern" A..=) <$> (networkRequestPatternUrlPattern p),
+    ("resourceType" A..=) <$> (networkRequestPatternResourceType p),
+    ("interceptionStage" A..=) <$> (networkRequestPatternInterceptionStage p)
+    ]
+
+-- | Type 'Network.SignedExchangeSignature'.
+--   Information about a signed exchange signature.
+--   https://wicg.github.io/webpackage/draft-yasskin-httpbis-origin-signed-exchanges-impl.html#rfc.section.3.1
+data NetworkSignedExchangeSignature = NetworkSignedExchangeSignature
+  {
+    -- | Signed exchange signature label.
+    networkSignedExchangeSignatureLabel :: T.Text,
+    -- | The hex string of signed exchange signature.
+    networkSignedExchangeSignatureSignature :: T.Text,
+    -- | Signed exchange signature integrity.
+    networkSignedExchangeSignatureIntegrity :: T.Text,
+    -- | Signed exchange signature cert Url.
+    networkSignedExchangeSignatureCertUrl :: Maybe T.Text,
+    -- | The hex string of signed exchange signature cert sha256.
+    networkSignedExchangeSignatureCertSha256 :: Maybe T.Text,
+    -- | Signed exchange signature validity Url.
+    networkSignedExchangeSignatureValidityUrl :: T.Text,
+    -- | Signed exchange signature date.
+    networkSignedExchangeSignatureDate :: Int,
+    -- | Signed exchange signature expires.
+    networkSignedExchangeSignatureExpires :: Int,
+    -- | The encoded certificates.
+    networkSignedExchangeSignatureCertificates :: Maybe [T.Text]
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkSignedExchangeSignature where
+  parseJSON = A.withObject "NetworkSignedExchangeSignature" $ \o -> NetworkSignedExchangeSignature
+    <$> o A..: "label"
+    <*> o A..: "signature"
+    <*> o A..: "integrity"
+    <*> o A..:? "certUrl"
+    <*> o A..:? "certSha256"
+    <*> o A..: "validityUrl"
+    <*> o A..: "date"
+    <*> o A..: "expires"
+    <*> o A..:? "certificates"
+instance ToJSON NetworkSignedExchangeSignature where
+  toJSON p = A.object $ catMaybes [
+    ("label" A..=) <$> Just (networkSignedExchangeSignatureLabel p),
+    ("signature" A..=) <$> Just (networkSignedExchangeSignatureSignature p),
+    ("integrity" A..=) <$> Just (networkSignedExchangeSignatureIntegrity p),
+    ("certUrl" A..=) <$> (networkSignedExchangeSignatureCertUrl p),
+    ("certSha256" A..=) <$> (networkSignedExchangeSignatureCertSha256 p),
+    ("validityUrl" A..=) <$> Just (networkSignedExchangeSignatureValidityUrl p),
+    ("date" A..=) <$> Just (networkSignedExchangeSignatureDate p),
+    ("expires" A..=) <$> Just (networkSignedExchangeSignatureExpires p),
+    ("certificates" A..=) <$> (networkSignedExchangeSignatureCertificates p)
+    ]
+
+-- | Type 'Network.SignedExchangeHeader'.
+--   Information about a signed exchange header.
+--   https://wicg.github.io/webpackage/draft-yasskin-httpbis-origin-signed-exchanges-impl.html#cbor-representation
+data NetworkSignedExchangeHeader = NetworkSignedExchangeHeader
+  {
+    -- | Signed exchange request URL.
+    networkSignedExchangeHeaderRequestUrl :: T.Text,
+    -- | Signed exchange response code.
+    networkSignedExchangeHeaderResponseCode :: Int,
+    -- | Signed exchange response headers.
+    networkSignedExchangeHeaderResponseHeaders :: NetworkHeaders,
+    -- | Signed exchange response signature.
+    networkSignedExchangeHeaderSignatures :: [NetworkSignedExchangeSignature],
+    -- | Signed exchange header integrity hash in the form of "sha256-<base64-hash-value>".
+    networkSignedExchangeHeaderHeaderIntegrity :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkSignedExchangeHeader where
+  parseJSON = A.withObject "NetworkSignedExchangeHeader" $ \o -> NetworkSignedExchangeHeader
+    <$> o A..: "requestUrl"
+    <*> o A..: "responseCode"
+    <*> o A..: "responseHeaders"
+    <*> o A..: "signatures"
+    <*> o A..: "headerIntegrity"
+instance ToJSON NetworkSignedExchangeHeader where
+  toJSON p = A.object $ catMaybes [
+    ("requestUrl" A..=) <$> Just (networkSignedExchangeHeaderRequestUrl p),
+    ("responseCode" A..=) <$> Just (networkSignedExchangeHeaderResponseCode p),
+    ("responseHeaders" A..=) <$> Just (networkSignedExchangeHeaderResponseHeaders p),
+    ("signatures" A..=) <$> Just (networkSignedExchangeHeaderSignatures p),
+    ("headerIntegrity" A..=) <$> Just (networkSignedExchangeHeaderHeaderIntegrity p)
+    ]
+
+-- | Type 'Network.SignedExchangeErrorField'.
+--   Field type for a signed exchange related error.
+data NetworkSignedExchangeErrorField = NetworkSignedExchangeErrorFieldSignatureSig | NetworkSignedExchangeErrorFieldSignatureIntegrity | NetworkSignedExchangeErrorFieldSignatureCertUrl | NetworkSignedExchangeErrorFieldSignatureCertSha256 | NetworkSignedExchangeErrorFieldSignatureValidityUrl | NetworkSignedExchangeErrorFieldSignatureTimestamps
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON NetworkSignedExchangeErrorField where
+  parseJSON = A.withText "NetworkSignedExchangeErrorField" $ \v -> case v of
+    "signatureSig" -> pure NetworkSignedExchangeErrorFieldSignatureSig
+    "signatureIntegrity" -> pure NetworkSignedExchangeErrorFieldSignatureIntegrity
+    "signatureCertUrl" -> pure NetworkSignedExchangeErrorFieldSignatureCertUrl
+    "signatureCertSha256" -> pure NetworkSignedExchangeErrorFieldSignatureCertSha256
+    "signatureValidityUrl" -> pure NetworkSignedExchangeErrorFieldSignatureValidityUrl
+    "signatureTimestamps" -> pure NetworkSignedExchangeErrorFieldSignatureTimestamps
+    "_" -> fail "failed to parse NetworkSignedExchangeErrorField"
+instance ToJSON NetworkSignedExchangeErrorField where
+  toJSON v = A.String $ case v of
+    NetworkSignedExchangeErrorFieldSignatureSig -> "signatureSig"
+    NetworkSignedExchangeErrorFieldSignatureIntegrity -> "signatureIntegrity"
+    NetworkSignedExchangeErrorFieldSignatureCertUrl -> "signatureCertUrl"
+    NetworkSignedExchangeErrorFieldSignatureCertSha256 -> "signatureCertSha256"
+    NetworkSignedExchangeErrorFieldSignatureValidityUrl -> "signatureValidityUrl"
+    NetworkSignedExchangeErrorFieldSignatureTimestamps -> "signatureTimestamps"
+
+-- | Type 'Network.SignedExchangeError'.
+--   Information about a signed exchange response.
+data NetworkSignedExchangeError = NetworkSignedExchangeError
+  {
+    -- | Error message.
+    networkSignedExchangeErrorMessage :: T.Text,
+    -- | The index of the signature which caused the error.
+    networkSignedExchangeErrorSignatureIndex :: Maybe Int,
+    -- | The field which caused the error.
+    networkSignedExchangeErrorErrorField :: Maybe NetworkSignedExchangeErrorField
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkSignedExchangeError where
+  parseJSON = A.withObject "NetworkSignedExchangeError" $ \o -> NetworkSignedExchangeError
+    <$> o A..: "message"
+    <*> o A..:? "signatureIndex"
+    <*> o A..:? "errorField"
+instance ToJSON NetworkSignedExchangeError where
+  toJSON p = A.object $ catMaybes [
+    ("message" A..=) <$> Just (networkSignedExchangeErrorMessage p),
+    ("signatureIndex" A..=) <$> (networkSignedExchangeErrorSignatureIndex p),
+    ("errorField" A..=) <$> (networkSignedExchangeErrorErrorField p)
+    ]
+
+-- | Type 'Network.SignedExchangeInfo'.
+--   Information about a signed exchange response.
+data NetworkSignedExchangeInfo = NetworkSignedExchangeInfo
+  {
+    -- | The outer response of signed HTTP exchange which was received from network.
+    networkSignedExchangeInfoOuterResponse :: NetworkResponse,
+    -- | Information about the signed exchange header.
+    networkSignedExchangeInfoHeader :: Maybe NetworkSignedExchangeHeader,
+    -- | Security details for the signed exchange header.
+    networkSignedExchangeInfoSecurityDetails :: Maybe NetworkSecurityDetails,
+    -- | Errors occurred while handling the signed exchagne.
+    networkSignedExchangeInfoErrors :: Maybe [NetworkSignedExchangeError]
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkSignedExchangeInfo where
+  parseJSON = A.withObject "NetworkSignedExchangeInfo" $ \o -> NetworkSignedExchangeInfo
+    <$> o A..: "outerResponse"
+    <*> o A..:? "header"
+    <*> o A..:? "securityDetails"
+    <*> o A..:? "errors"
+instance ToJSON NetworkSignedExchangeInfo where
+  toJSON p = A.object $ catMaybes [
+    ("outerResponse" A..=) <$> Just (networkSignedExchangeInfoOuterResponse p),
+    ("header" A..=) <$> (networkSignedExchangeInfoHeader p),
+    ("securityDetails" A..=) <$> (networkSignedExchangeInfoSecurityDetails p),
+    ("errors" A..=) <$> (networkSignedExchangeInfoErrors p)
+    ]
+
+-- | Type 'Network.ContentEncoding'.
+--   List of content encodings supported by the backend.
+data NetworkContentEncoding = NetworkContentEncodingDeflate | NetworkContentEncodingGzip | NetworkContentEncodingBr
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON NetworkContentEncoding where
+  parseJSON = A.withText "NetworkContentEncoding" $ \v -> case v of
+    "deflate" -> pure NetworkContentEncodingDeflate
+    "gzip" -> pure NetworkContentEncodingGzip
+    "br" -> pure NetworkContentEncodingBr
+    "_" -> fail "failed to parse NetworkContentEncoding"
+instance ToJSON NetworkContentEncoding where
+  toJSON v = A.String $ case v of
+    NetworkContentEncodingDeflate -> "deflate"
+    NetworkContentEncodingGzip -> "gzip"
+    NetworkContentEncodingBr -> "br"
+
+-- | Type 'Network.PrivateNetworkRequestPolicy'.
+data NetworkPrivateNetworkRequestPolicy = NetworkPrivateNetworkRequestPolicyAllow | NetworkPrivateNetworkRequestPolicyBlockFromInsecureToMorePrivate | NetworkPrivateNetworkRequestPolicyWarnFromInsecureToMorePrivate | NetworkPrivateNetworkRequestPolicyPreflightBlock | NetworkPrivateNetworkRequestPolicyPreflightWarn
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON NetworkPrivateNetworkRequestPolicy where
+  parseJSON = A.withText "NetworkPrivateNetworkRequestPolicy" $ \v -> case v of
+    "Allow" -> pure NetworkPrivateNetworkRequestPolicyAllow
+    "BlockFromInsecureToMorePrivate" -> pure NetworkPrivateNetworkRequestPolicyBlockFromInsecureToMorePrivate
+    "WarnFromInsecureToMorePrivate" -> pure NetworkPrivateNetworkRequestPolicyWarnFromInsecureToMorePrivate
+    "PreflightBlock" -> pure NetworkPrivateNetworkRequestPolicyPreflightBlock
+    "PreflightWarn" -> pure NetworkPrivateNetworkRequestPolicyPreflightWarn
+    "_" -> fail "failed to parse NetworkPrivateNetworkRequestPolicy"
+instance ToJSON NetworkPrivateNetworkRequestPolicy where
+  toJSON v = A.String $ case v of
+    NetworkPrivateNetworkRequestPolicyAllow -> "Allow"
+    NetworkPrivateNetworkRequestPolicyBlockFromInsecureToMorePrivate -> "BlockFromInsecureToMorePrivate"
+    NetworkPrivateNetworkRequestPolicyWarnFromInsecureToMorePrivate -> "WarnFromInsecureToMorePrivate"
+    NetworkPrivateNetworkRequestPolicyPreflightBlock -> "PreflightBlock"
+    NetworkPrivateNetworkRequestPolicyPreflightWarn -> "PreflightWarn"
+
+-- | Type 'Network.IPAddressSpace'.
+data NetworkIPAddressSpace = NetworkIPAddressSpaceLocal | NetworkIPAddressSpacePrivate | NetworkIPAddressSpacePublic | NetworkIPAddressSpaceUnknown
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON NetworkIPAddressSpace where
+  parseJSON = A.withText "NetworkIPAddressSpace" $ \v -> case v of
+    "Local" -> pure NetworkIPAddressSpaceLocal
+    "Private" -> pure NetworkIPAddressSpacePrivate
+    "Public" -> pure NetworkIPAddressSpacePublic
+    "Unknown" -> pure NetworkIPAddressSpaceUnknown
+    "_" -> fail "failed to parse NetworkIPAddressSpace"
+instance ToJSON NetworkIPAddressSpace where
+  toJSON v = A.String $ case v of
+    NetworkIPAddressSpaceLocal -> "Local"
+    NetworkIPAddressSpacePrivate -> "Private"
+    NetworkIPAddressSpacePublic -> "Public"
+    NetworkIPAddressSpaceUnknown -> "Unknown"
+
+-- | Type 'Network.ConnectTiming'.
+data NetworkConnectTiming = NetworkConnectTiming
+  {
+    -- | Timing's requestTime is a baseline in seconds, while the other numbers are ticks in
+    --   milliseconds relatively to this requestTime. Matches ResourceTiming's requestTime for
+    --   the same request (but not for redirected requests).
+    networkConnectTimingRequestTime :: Double
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkConnectTiming where
+  parseJSON = A.withObject "NetworkConnectTiming" $ \o -> NetworkConnectTiming
+    <$> o A..: "requestTime"
+instance ToJSON NetworkConnectTiming where
+  toJSON p = A.object $ catMaybes [
+    ("requestTime" A..=) <$> Just (networkConnectTimingRequestTime p)
+    ]
+
+-- | Type 'Network.ClientSecurityState'.
+data NetworkClientSecurityState = NetworkClientSecurityState
+  {
+    networkClientSecurityStateInitiatorIsSecureContext :: Bool,
+    networkClientSecurityStateInitiatorIPAddressSpace :: NetworkIPAddressSpace,
+    networkClientSecurityStatePrivateNetworkRequestPolicy :: NetworkPrivateNetworkRequestPolicy
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkClientSecurityState where
+  parseJSON = A.withObject "NetworkClientSecurityState" $ \o -> NetworkClientSecurityState
+    <$> o A..: "initiatorIsSecureContext"
+    <*> o A..: "initiatorIPAddressSpace"
+    <*> o A..: "privateNetworkRequestPolicy"
+instance ToJSON NetworkClientSecurityState where
+  toJSON p = A.object $ catMaybes [
+    ("initiatorIsSecureContext" A..=) <$> Just (networkClientSecurityStateInitiatorIsSecureContext p),
+    ("initiatorIPAddressSpace" A..=) <$> Just (networkClientSecurityStateInitiatorIPAddressSpace p),
+    ("privateNetworkRequestPolicy" A..=) <$> Just (networkClientSecurityStatePrivateNetworkRequestPolicy p)
+    ]
+
+-- | Type 'Network.CrossOriginOpenerPolicyValue'.
+data NetworkCrossOriginOpenerPolicyValue = NetworkCrossOriginOpenerPolicyValueSameOrigin | NetworkCrossOriginOpenerPolicyValueSameOriginAllowPopups | NetworkCrossOriginOpenerPolicyValueRestrictProperties | NetworkCrossOriginOpenerPolicyValueUnsafeNone | NetworkCrossOriginOpenerPolicyValueSameOriginPlusCoep | NetworkCrossOriginOpenerPolicyValueRestrictPropertiesPlusCoep
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON NetworkCrossOriginOpenerPolicyValue where
+  parseJSON = A.withText "NetworkCrossOriginOpenerPolicyValue" $ \v -> case v of
+    "SameOrigin" -> pure NetworkCrossOriginOpenerPolicyValueSameOrigin
+    "SameOriginAllowPopups" -> pure NetworkCrossOriginOpenerPolicyValueSameOriginAllowPopups
+    "RestrictProperties" -> pure NetworkCrossOriginOpenerPolicyValueRestrictProperties
+    "UnsafeNone" -> pure NetworkCrossOriginOpenerPolicyValueUnsafeNone
+    "SameOriginPlusCoep" -> pure NetworkCrossOriginOpenerPolicyValueSameOriginPlusCoep
+    "RestrictPropertiesPlusCoep" -> pure NetworkCrossOriginOpenerPolicyValueRestrictPropertiesPlusCoep
+    "_" -> fail "failed to parse NetworkCrossOriginOpenerPolicyValue"
+instance ToJSON NetworkCrossOriginOpenerPolicyValue where
+  toJSON v = A.String $ case v of
+    NetworkCrossOriginOpenerPolicyValueSameOrigin -> "SameOrigin"
+    NetworkCrossOriginOpenerPolicyValueSameOriginAllowPopups -> "SameOriginAllowPopups"
+    NetworkCrossOriginOpenerPolicyValueRestrictProperties -> "RestrictProperties"
+    NetworkCrossOriginOpenerPolicyValueUnsafeNone -> "UnsafeNone"
+    NetworkCrossOriginOpenerPolicyValueSameOriginPlusCoep -> "SameOriginPlusCoep"
+    NetworkCrossOriginOpenerPolicyValueRestrictPropertiesPlusCoep -> "RestrictPropertiesPlusCoep"
+
+-- | Type 'Network.CrossOriginOpenerPolicyStatus'.
+data NetworkCrossOriginOpenerPolicyStatus = NetworkCrossOriginOpenerPolicyStatus
+  {
+    networkCrossOriginOpenerPolicyStatusValue :: NetworkCrossOriginOpenerPolicyValue,
+    networkCrossOriginOpenerPolicyStatusReportOnlyValue :: NetworkCrossOriginOpenerPolicyValue,
+    networkCrossOriginOpenerPolicyStatusReportingEndpoint :: Maybe T.Text,
+    networkCrossOriginOpenerPolicyStatusReportOnlyReportingEndpoint :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkCrossOriginOpenerPolicyStatus where
+  parseJSON = A.withObject "NetworkCrossOriginOpenerPolicyStatus" $ \o -> NetworkCrossOriginOpenerPolicyStatus
+    <$> o A..: "value"
+    <*> o A..: "reportOnlyValue"
+    <*> o A..:? "reportingEndpoint"
+    <*> o A..:? "reportOnlyReportingEndpoint"
+instance ToJSON NetworkCrossOriginOpenerPolicyStatus where
+  toJSON p = A.object $ catMaybes [
+    ("value" A..=) <$> Just (networkCrossOriginOpenerPolicyStatusValue p),
+    ("reportOnlyValue" A..=) <$> Just (networkCrossOriginOpenerPolicyStatusReportOnlyValue p),
+    ("reportingEndpoint" A..=) <$> (networkCrossOriginOpenerPolicyStatusReportingEndpoint p),
+    ("reportOnlyReportingEndpoint" A..=) <$> (networkCrossOriginOpenerPolicyStatusReportOnlyReportingEndpoint p)
+    ]
+
+-- | Type 'Network.CrossOriginEmbedderPolicyValue'.
+data NetworkCrossOriginEmbedderPolicyValue = NetworkCrossOriginEmbedderPolicyValueNone | NetworkCrossOriginEmbedderPolicyValueCredentialless | NetworkCrossOriginEmbedderPolicyValueRequireCorp
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON NetworkCrossOriginEmbedderPolicyValue where
+  parseJSON = A.withText "NetworkCrossOriginEmbedderPolicyValue" $ \v -> case v of
+    "None" -> pure NetworkCrossOriginEmbedderPolicyValueNone
+    "Credentialless" -> pure NetworkCrossOriginEmbedderPolicyValueCredentialless
+    "RequireCorp" -> pure NetworkCrossOriginEmbedderPolicyValueRequireCorp
+    "_" -> fail "failed to parse NetworkCrossOriginEmbedderPolicyValue"
+instance ToJSON NetworkCrossOriginEmbedderPolicyValue where
+  toJSON v = A.String $ case v of
+    NetworkCrossOriginEmbedderPolicyValueNone -> "None"
+    NetworkCrossOriginEmbedderPolicyValueCredentialless -> "Credentialless"
+    NetworkCrossOriginEmbedderPolicyValueRequireCorp -> "RequireCorp"
+
+-- | Type 'Network.CrossOriginEmbedderPolicyStatus'.
+data NetworkCrossOriginEmbedderPolicyStatus = NetworkCrossOriginEmbedderPolicyStatus
+  {
+    networkCrossOriginEmbedderPolicyStatusValue :: NetworkCrossOriginEmbedderPolicyValue,
+    networkCrossOriginEmbedderPolicyStatusReportOnlyValue :: NetworkCrossOriginEmbedderPolicyValue,
+    networkCrossOriginEmbedderPolicyStatusReportingEndpoint :: Maybe T.Text,
+    networkCrossOriginEmbedderPolicyStatusReportOnlyReportingEndpoint :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkCrossOriginEmbedderPolicyStatus where
+  parseJSON = A.withObject "NetworkCrossOriginEmbedderPolicyStatus" $ \o -> NetworkCrossOriginEmbedderPolicyStatus
+    <$> o A..: "value"
+    <*> o A..: "reportOnlyValue"
+    <*> o A..:? "reportingEndpoint"
+    <*> o A..:? "reportOnlyReportingEndpoint"
+instance ToJSON NetworkCrossOriginEmbedderPolicyStatus where
+  toJSON p = A.object $ catMaybes [
+    ("value" A..=) <$> Just (networkCrossOriginEmbedderPolicyStatusValue p),
+    ("reportOnlyValue" A..=) <$> Just (networkCrossOriginEmbedderPolicyStatusReportOnlyValue p),
+    ("reportingEndpoint" A..=) <$> (networkCrossOriginEmbedderPolicyStatusReportingEndpoint p),
+    ("reportOnlyReportingEndpoint" A..=) <$> (networkCrossOriginEmbedderPolicyStatusReportOnlyReportingEndpoint p)
+    ]
+
+-- | Type 'Network.SecurityIsolationStatus'.
+data NetworkSecurityIsolationStatus = NetworkSecurityIsolationStatus
+  {
+    networkSecurityIsolationStatusCoop :: Maybe NetworkCrossOriginOpenerPolicyStatus,
+    networkSecurityIsolationStatusCoep :: Maybe NetworkCrossOriginEmbedderPolicyStatus
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkSecurityIsolationStatus where
+  parseJSON = A.withObject "NetworkSecurityIsolationStatus" $ \o -> NetworkSecurityIsolationStatus
+    <$> o A..:? "coop"
+    <*> o A..:? "coep"
+instance ToJSON NetworkSecurityIsolationStatus where
+  toJSON p = A.object $ catMaybes [
+    ("coop" A..=) <$> (networkSecurityIsolationStatusCoop p),
+    ("coep" A..=) <$> (networkSecurityIsolationStatusCoep p)
+    ]
+
+-- | Type 'Network.ReportStatus'.
+--   The status of a Reporting API report.
+data NetworkReportStatus = NetworkReportStatusQueued | NetworkReportStatusPending | NetworkReportStatusMarkedForRemoval | NetworkReportStatusSuccess
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON NetworkReportStatus where
+  parseJSON = A.withText "NetworkReportStatus" $ \v -> case v of
+    "Queued" -> pure NetworkReportStatusQueued
+    "Pending" -> pure NetworkReportStatusPending
+    "MarkedForRemoval" -> pure NetworkReportStatusMarkedForRemoval
+    "Success" -> pure NetworkReportStatusSuccess
+    "_" -> fail "failed to parse NetworkReportStatus"
+instance ToJSON NetworkReportStatus where
+  toJSON v = A.String $ case v of
+    NetworkReportStatusQueued -> "Queued"
+    NetworkReportStatusPending -> "Pending"
+    NetworkReportStatusMarkedForRemoval -> "MarkedForRemoval"
+    NetworkReportStatusSuccess -> "Success"
+
+-- | Type 'Network.ReportId'.
+type NetworkReportId = T.Text
+
+-- | Type 'Network.ReportingApiReport'.
+--   An object representing a report generated by the Reporting API.
+data NetworkReportingApiReport = NetworkReportingApiReport
+  {
+    networkReportingApiReportId :: NetworkReportId,
+    -- | The URL of the document that triggered the report.
+    networkReportingApiReportInitiatorUrl :: T.Text,
+    -- | The name of the endpoint group that should be used to deliver the report.
+    networkReportingApiReportDestination :: T.Text,
+    -- | The type of the report (specifies the set of data that is contained in the report body).
+    networkReportingApiReportType :: T.Text,
+    -- | When the report was generated.
+    networkReportingApiReportTimestamp :: NetworkTimeSinceEpoch,
+    -- | How many uploads deep the related request was.
+    networkReportingApiReportDepth :: Int,
+    -- | The number of delivery attempts made so far, not including an active attempt.
+    networkReportingApiReportCompletedAttempts :: Int,
+    networkReportingApiReportBody :: [(T.Text, T.Text)],
+    networkReportingApiReportStatus :: NetworkReportStatus
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkReportingApiReport where
+  parseJSON = A.withObject "NetworkReportingApiReport" $ \o -> NetworkReportingApiReport
+    <$> o A..: "id"
+    <*> o A..: "initiatorUrl"
+    <*> o A..: "destination"
+    <*> o A..: "type"
+    <*> o A..: "timestamp"
+    <*> o A..: "depth"
+    <*> o A..: "completedAttempts"
+    <*> o A..: "body"
+    <*> o A..: "status"
+instance ToJSON NetworkReportingApiReport where
+  toJSON p = A.object $ catMaybes [
+    ("id" A..=) <$> Just (networkReportingApiReportId p),
+    ("initiatorUrl" A..=) <$> Just (networkReportingApiReportInitiatorUrl p),
+    ("destination" A..=) <$> Just (networkReportingApiReportDestination p),
+    ("type" A..=) <$> Just (networkReportingApiReportType p),
+    ("timestamp" A..=) <$> Just (networkReportingApiReportTimestamp p),
+    ("depth" A..=) <$> Just (networkReportingApiReportDepth p),
+    ("completedAttempts" A..=) <$> Just (networkReportingApiReportCompletedAttempts p),
+    ("body" A..=) <$> Just (networkReportingApiReportBody p),
+    ("status" A..=) <$> Just (networkReportingApiReportStatus p)
+    ]
+
+-- | Type 'Network.ReportingApiEndpoint'.
+data NetworkReportingApiEndpoint = NetworkReportingApiEndpoint
+  {
+    -- | The URL of the endpoint to which reports may be delivered.
+    networkReportingApiEndpointUrl :: T.Text,
+    -- | Name of the endpoint group.
+    networkReportingApiEndpointGroupName :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkReportingApiEndpoint where
+  parseJSON = A.withObject "NetworkReportingApiEndpoint" $ \o -> NetworkReportingApiEndpoint
+    <$> o A..: "url"
+    <*> o A..: "groupName"
+instance ToJSON NetworkReportingApiEndpoint where
+  toJSON p = A.object $ catMaybes [
+    ("url" A..=) <$> Just (networkReportingApiEndpointUrl p),
+    ("groupName" A..=) <$> Just (networkReportingApiEndpointGroupName p)
+    ]
+
+-- | Type 'Network.LoadNetworkResourcePageResult'.
+--   An object providing the result of a network resource load.
+data NetworkLoadNetworkResourcePageResult = NetworkLoadNetworkResourcePageResult
+  {
+    networkLoadNetworkResourcePageResultSuccess :: Bool,
+    -- | Optional values used for error reporting.
+    networkLoadNetworkResourcePageResultNetError :: Maybe Double,
+    networkLoadNetworkResourcePageResultNetErrorName :: Maybe T.Text,
+    networkLoadNetworkResourcePageResultHttpStatusCode :: Maybe Double,
+    -- | If successful, one of the following two fields holds the result.
+    networkLoadNetworkResourcePageResultStream :: Maybe IO.IOStreamHandle,
+    -- | Response headers.
+    networkLoadNetworkResourcePageResultHeaders :: Maybe NetworkHeaders
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkLoadNetworkResourcePageResult where
+  parseJSON = A.withObject "NetworkLoadNetworkResourcePageResult" $ \o -> NetworkLoadNetworkResourcePageResult
+    <$> o A..: "success"
+    <*> o A..:? "netError"
+    <*> o A..:? "netErrorName"
+    <*> o A..:? "httpStatusCode"
+    <*> o A..:? "stream"
+    <*> o A..:? "headers"
+instance ToJSON NetworkLoadNetworkResourcePageResult where
+  toJSON p = A.object $ catMaybes [
+    ("success" A..=) <$> Just (networkLoadNetworkResourcePageResultSuccess p),
+    ("netError" A..=) <$> (networkLoadNetworkResourcePageResultNetError p),
+    ("netErrorName" A..=) <$> (networkLoadNetworkResourcePageResultNetErrorName p),
+    ("httpStatusCode" A..=) <$> (networkLoadNetworkResourcePageResultHttpStatusCode p),
+    ("stream" A..=) <$> (networkLoadNetworkResourcePageResultStream p),
+    ("headers" A..=) <$> (networkLoadNetworkResourcePageResultHeaders p)
+    ]
+
+-- | Type 'Network.LoadNetworkResourceOptions'.
+--   An options object that may be extended later to better support CORS,
+--   CORB and streaming.
+data NetworkLoadNetworkResourceOptions = NetworkLoadNetworkResourceOptions
+  {
+    networkLoadNetworkResourceOptionsDisableCache :: Bool,
+    networkLoadNetworkResourceOptionsIncludeCredentials :: Bool
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkLoadNetworkResourceOptions where
+  parseJSON = A.withObject "NetworkLoadNetworkResourceOptions" $ \o -> NetworkLoadNetworkResourceOptions
+    <$> o A..: "disableCache"
+    <*> o A..: "includeCredentials"
+instance ToJSON NetworkLoadNetworkResourceOptions where
+  toJSON p = A.object $ catMaybes [
+    ("disableCache" A..=) <$> Just (networkLoadNetworkResourceOptionsDisableCache p),
+    ("includeCredentials" A..=) <$> Just (networkLoadNetworkResourceOptionsIncludeCredentials p)
+    ]
+
+-- | Type of the 'Network.dataReceived' event.
+data NetworkDataReceived = NetworkDataReceived
+  {
+    -- | Request identifier.
+    networkDataReceivedRequestId :: NetworkRequestId,
+    -- | Timestamp.
+    networkDataReceivedTimestamp :: NetworkMonotonicTime,
+    -- | Data chunk length.
+    networkDataReceivedDataLength :: Int,
+    -- | Actual bytes received (might be less than dataLength for compressed encodings).
+    networkDataReceivedEncodedDataLength :: Int
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkDataReceived where
+  parseJSON = A.withObject "NetworkDataReceived" $ \o -> NetworkDataReceived
+    <$> o A..: "requestId"
+    <*> o A..: "timestamp"
+    <*> o A..: "dataLength"
+    <*> o A..: "encodedDataLength"
+instance Event NetworkDataReceived where
+  eventName _ = "Network.dataReceived"
+
+-- | Type of the 'Network.eventSourceMessageReceived' event.
+data NetworkEventSourceMessageReceived = NetworkEventSourceMessageReceived
+  {
+    -- | Request identifier.
+    networkEventSourceMessageReceivedRequestId :: NetworkRequestId,
+    -- | Timestamp.
+    networkEventSourceMessageReceivedTimestamp :: NetworkMonotonicTime,
+    -- | Message type.
+    networkEventSourceMessageReceivedEventName :: T.Text,
+    -- | Message identifier.
+    networkEventSourceMessageReceivedEventId :: T.Text,
+    -- | Message content.
+    networkEventSourceMessageReceivedData :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkEventSourceMessageReceived where
+  parseJSON = A.withObject "NetworkEventSourceMessageReceived" $ \o -> NetworkEventSourceMessageReceived
+    <$> o A..: "requestId"
+    <*> o A..: "timestamp"
+    <*> o A..: "eventName"
+    <*> o A..: "eventId"
+    <*> o A..: "data"
+instance Event NetworkEventSourceMessageReceived where
+  eventName _ = "Network.eventSourceMessageReceived"
+
+-- | Type of the 'Network.loadingFailed' event.
+data NetworkLoadingFailed = NetworkLoadingFailed
+  {
+    -- | Request identifier.
+    networkLoadingFailedRequestId :: NetworkRequestId,
+    -- | Timestamp.
+    networkLoadingFailedTimestamp :: NetworkMonotonicTime,
+    -- | Resource type.
+    networkLoadingFailedType :: NetworkResourceType,
+    -- | User friendly error message.
+    networkLoadingFailedErrorText :: T.Text,
+    -- | True if loading was canceled.
+    networkLoadingFailedCanceled :: Maybe Bool,
+    -- | The reason why loading was blocked, if any.
+    networkLoadingFailedBlockedReason :: Maybe NetworkBlockedReason,
+    -- | The reason why loading was blocked by CORS, if any.
+    networkLoadingFailedCorsErrorStatus :: Maybe NetworkCorsErrorStatus
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkLoadingFailed where
+  parseJSON = A.withObject "NetworkLoadingFailed" $ \o -> NetworkLoadingFailed
+    <$> o A..: "requestId"
+    <*> o A..: "timestamp"
+    <*> o A..: "type"
+    <*> o A..: "errorText"
+    <*> o A..:? "canceled"
+    <*> o A..:? "blockedReason"
+    <*> o A..:? "corsErrorStatus"
+instance Event NetworkLoadingFailed where
+  eventName _ = "Network.loadingFailed"
+
+-- | Type of the 'Network.loadingFinished' event.
+data NetworkLoadingFinished = NetworkLoadingFinished
+  {
+    -- | Request identifier.
+    networkLoadingFinishedRequestId :: NetworkRequestId,
+    -- | Timestamp.
+    networkLoadingFinishedTimestamp :: NetworkMonotonicTime,
+    -- | Total number of bytes received for this request.
+    networkLoadingFinishedEncodedDataLength :: Double,
+    -- | Set when 1) response was blocked by Cross-Origin Read Blocking and also
+    --   2) this needs to be reported to the DevTools console.
+    networkLoadingFinishedShouldReportCorbBlocking :: Maybe Bool
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkLoadingFinished where
+  parseJSON = A.withObject "NetworkLoadingFinished" $ \o -> NetworkLoadingFinished
+    <$> o A..: "requestId"
+    <*> o A..: "timestamp"
+    <*> o A..: "encodedDataLength"
+    <*> o A..:? "shouldReportCorbBlocking"
+instance Event NetworkLoadingFinished where
+  eventName _ = "Network.loadingFinished"
+
+-- | Type of the 'Network.requestServedFromCache' event.
+data NetworkRequestServedFromCache = NetworkRequestServedFromCache
+  {
+    -- | Request identifier.
+    networkRequestServedFromCacheRequestId :: NetworkRequestId
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkRequestServedFromCache where
+  parseJSON = A.withObject "NetworkRequestServedFromCache" $ \o -> NetworkRequestServedFromCache
+    <$> o A..: "requestId"
+instance Event NetworkRequestServedFromCache where
+  eventName _ = "Network.requestServedFromCache"
+
+-- | Type of the 'Network.requestWillBeSent' event.
+data NetworkRequestWillBeSent = NetworkRequestWillBeSent
+  {
+    -- | Request identifier.
+    networkRequestWillBeSentRequestId :: NetworkRequestId,
+    -- | Loader identifier. Empty string if the request is fetched from worker.
+    networkRequestWillBeSentLoaderId :: NetworkLoaderId,
+    -- | URL of the document this request is loaded for.
+    networkRequestWillBeSentDocumentURL :: T.Text,
+    -- | Request data.
+    networkRequestWillBeSentRequest :: NetworkRequest,
+    -- | Timestamp.
+    networkRequestWillBeSentTimestamp :: NetworkMonotonicTime,
+    -- | Timestamp.
+    networkRequestWillBeSentWallTime :: NetworkTimeSinceEpoch,
+    -- | Request initiator.
+    networkRequestWillBeSentInitiator :: NetworkInitiator,
+    -- | In the case that redirectResponse is populated, this flag indicates whether
+    --   requestWillBeSentExtraInfo and responseReceivedExtraInfo events will be or were emitted
+    --   for the request which was just redirected.
+    networkRequestWillBeSentRedirectHasExtraInfo :: Bool,
+    -- | Redirect response data.
+    networkRequestWillBeSentRedirectResponse :: Maybe NetworkResponse,
+    -- | Type of this resource.
+    networkRequestWillBeSentType :: Maybe NetworkResourceType,
+    -- | Frame identifier.
+    networkRequestWillBeSentFrameId :: Maybe PageFrameId,
+    -- | Whether the request is initiated by a user gesture. Defaults to false.
+    networkRequestWillBeSentHasUserGesture :: Maybe Bool
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkRequestWillBeSent where
+  parseJSON = A.withObject "NetworkRequestWillBeSent" $ \o -> NetworkRequestWillBeSent
+    <$> o A..: "requestId"
+    <*> o A..: "loaderId"
+    <*> o A..: "documentURL"
+    <*> o A..: "request"
+    <*> o A..: "timestamp"
+    <*> o A..: "wallTime"
+    <*> o A..: "initiator"
+    <*> o A..: "redirectHasExtraInfo"
+    <*> o A..:? "redirectResponse"
+    <*> o A..:? "type"
+    <*> o A..:? "frameId"
+    <*> o A..:? "hasUserGesture"
+instance Event NetworkRequestWillBeSent where
+  eventName _ = "Network.requestWillBeSent"
+
+-- | Type of the 'Network.resourceChangedPriority' event.
+data NetworkResourceChangedPriority = NetworkResourceChangedPriority
+  {
+    -- | Request identifier.
+    networkResourceChangedPriorityRequestId :: NetworkRequestId,
+    -- | New priority
+    networkResourceChangedPriorityNewPriority :: NetworkResourcePriority,
+    -- | Timestamp.
+    networkResourceChangedPriorityTimestamp :: NetworkMonotonicTime
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkResourceChangedPriority where
+  parseJSON = A.withObject "NetworkResourceChangedPriority" $ \o -> NetworkResourceChangedPriority
+    <$> o A..: "requestId"
+    <*> o A..: "newPriority"
+    <*> o A..: "timestamp"
+instance Event NetworkResourceChangedPriority where
+  eventName _ = "Network.resourceChangedPriority"
+
+-- | Type of the 'Network.signedExchangeReceived' event.
+data NetworkSignedExchangeReceived = NetworkSignedExchangeReceived
+  {
+    -- | Request identifier.
+    networkSignedExchangeReceivedRequestId :: NetworkRequestId,
+    -- | Information about the signed exchange response.
+    networkSignedExchangeReceivedInfo :: NetworkSignedExchangeInfo
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkSignedExchangeReceived where
+  parseJSON = A.withObject "NetworkSignedExchangeReceived" $ \o -> NetworkSignedExchangeReceived
+    <$> o A..: "requestId"
+    <*> o A..: "info"
+instance Event NetworkSignedExchangeReceived where
+  eventName _ = "Network.signedExchangeReceived"
+
+-- | Type of the 'Network.responseReceived' event.
+data NetworkResponseReceived = NetworkResponseReceived
+  {
+    -- | Request identifier.
+    networkResponseReceivedRequestId :: NetworkRequestId,
+    -- | Loader identifier. Empty string if the request is fetched from worker.
+    networkResponseReceivedLoaderId :: NetworkLoaderId,
+    -- | Timestamp.
+    networkResponseReceivedTimestamp :: NetworkMonotonicTime,
+    -- | Resource type.
+    networkResponseReceivedType :: NetworkResourceType,
+    -- | Response data.
+    networkResponseReceivedResponse :: NetworkResponse,
+    -- | Indicates whether requestWillBeSentExtraInfo and responseReceivedExtraInfo events will be
+    --   or were emitted for this request.
+    networkResponseReceivedHasExtraInfo :: Bool,
+    -- | Frame identifier.
+    networkResponseReceivedFrameId :: Maybe PageFrameId
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkResponseReceived where
+  parseJSON = A.withObject "NetworkResponseReceived" $ \o -> NetworkResponseReceived
+    <$> o A..: "requestId"
+    <*> o A..: "loaderId"
+    <*> o A..: "timestamp"
+    <*> o A..: "type"
+    <*> o A..: "response"
+    <*> o A..: "hasExtraInfo"
+    <*> o A..:? "frameId"
+instance Event NetworkResponseReceived where
+  eventName _ = "Network.responseReceived"
+
+-- | Type of the 'Network.webSocketClosed' event.
+data NetworkWebSocketClosed = NetworkWebSocketClosed
+  {
+    -- | Request identifier.
+    networkWebSocketClosedRequestId :: NetworkRequestId,
+    -- | Timestamp.
+    networkWebSocketClosedTimestamp :: NetworkMonotonicTime
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkWebSocketClosed where
+  parseJSON = A.withObject "NetworkWebSocketClosed" $ \o -> NetworkWebSocketClosed
+    <$> o A..: "requestId"
+    <*> o A..: "timestamp"
+instance Event NetworkWebSocketClosed where
+  eventName _ = "Network.webSocketClosed"
+
+-- | Type of the 'Network.webSocketCreated' event.
+data NetworkWebSocketCreated = NetworkWebSocketCreated
+  {
+    -- | Request identifier.
+    networkWebSocketCreatedRequestId :: NetworkRequestId,
+    -- | WebSocket request URL.
+    networkWebSocketCreatedUrl :: T.Text,
+    -- | Request initiator.
+    networkWebSocketCreatedInitiator :: Maybe NetworkInitiator
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkWebSocketCreated where
+  parseJSON = A.withObject "NetworkWebSocketCreated" $ \o -> NetworkWebSocketCreated
+    <$> o A..: "requestId"
+    <*> o A..: "url"
+    <*> o A..:? "initiator"
+instance Event NetworkWebSocketCreated where
+  eventName _ = "Network.webSocketCreated"
+
+-- | Type of the 'Network.webSocketFrameError' event.
+data NetworkWebSocketFrameError = NetworkWebSocketFrameError
+  {
+    -- | Request identifier.
+    networkWebSocketFrameErrorRequestId :: NetworkRequestId,
+    -- | Timestamp.
+    networkWebSocketFrameErrorTimestamp :: NetworkMonotonicTime,
+    -- | WebSocket error message.
+    networkWebSocketFrameErrorErrorMessage :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkWebSocketFrameError where
+  parseJSON = A.withObject "NetworkWebSocketFrameError" $ \o -> NetworkWebSocketFrameError
+    <$> o A..: "requestId"
+    <*> o A..: "timestamp"
+    <*> o A..: "errorMessage"
+instance Event NetworkWebSocketFrameError where
+  eventName _ = "Network.webSocketFrameError"
+
+-- | Type of the 'Network.webSocketFrameReceived' event.
+data NetworkWebSocketFrameReceived = NetworkWebSocketFrameReceived
+  {
+    -- | Request identifier.
+    networkWebSocketFrameReceivedRequestId :: NetworkRequestId,
+    -- | Timestamp.
+    networkWebSocketFrameReceivedTimestamp :: NetworkMonotonicTime,
+    -- | WebSocket response data.
+    networkWebSocketFrameReceivedResponse :: NetworkWebSocketFrame
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkWebSocketFrameReceived where
+  parseJSON = A.withObject "NetworkWebSocketFrameReceived" $ \o -> NetworkWebSocketFrameReceived
+    <$> o A..: "requestId"
+    <*> o A..: "timestamp"
+    <*> o A..: "response"
+instance Event NetworkWebSocketFrameReceived where
+  eventName _ = "Network.webSocketFrameReceived"
+
+-- | Type of the 'Network.webSocketFrameSent' event.
+data NetworkWebSocketFrameSent = NetworkWebSocketFrameSent
+  {
+    -- | Request identifier.
+    networkWebSocketFrameSentRequestId :: NetworkRequestId,
+    -- | Timestamp.
+    networkWebSocketFrameSentTimestamp :: NetworkMonotonicTime,
+    -- | WebSocket response data.
+    networkWebSocketFrameSentResponse :: NetworkWebSocketFrame
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkWebSocketFrameSent where
+  parseJSON = A.withObject "NetworkWebSocketFrameSent" $ \o -> NetworkWebSocketFrameSent
+    <$> o A..: "requestId"
+    <*> o A..: "timestamp"
+    <*> o A..: "response"
+instance Event NetworkWebSocketFrameSent where
+  eventName _ = "Network.webSocketFrameSent"
+
+-- | Type of the 'Network.webSocketHandshakeResponseReceived' event.
+data NetworkWebSocketHandshakeResponseReceived = NetworkWebSocketHandshakeResponseReceived
+  {
+    -- | Request identifier.
+    networkWebSocketHandshakeResponseReceivedRequestId :: NetworkRequestId,
+    -- | Timestamp.
+    networkWebSocketHandshakeResponseReceivedTimestamp :: NetworkMonotonicTime,
+    -- | WebSocket response data.
+    networkWebSocketHandshakeResponseReceivedResponse :: NetworkWebSocketResponse
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkWebSocketHandshakeResponseReceived where
+  parseJSON = A.withObject "NetworkWebSocketHandshakeResponseReceived" $ \o -> NetworkWebSocketHandshakeResponseReceived
+    <$> o A..: "requestId"
+    <*> o A..: "timestamp"
+    <*> o A..: "response"
+instance Event NetworkWebSocketHandshakeResponseReceived where
+  eventName _ = "Network.webSocketHandshakeResponseReceived"
+
+-- | Type of the 'Network.webSocketWillSendHandshakeRequest' event.
+data NetworkWebSocketWillSendHandshakeRequest = NetworkWebSocketWillSendHandshakeRequest
+  {
+    -- | Request identifier.
+    networkWebSocketWillSendHandshakeRequestRequestId :: NetworkRequestId,
+    -- | Timestamp.
+    networkWebSocketWillSendHandshakeRequestTimestamp :: NetworkMonotonicTime,
+    -- | UTC Timestamp.
+    networkWebSocketWillSendHandshakeRequestWallTime :: NetworkTimeSinceEpoch,
+    -- | WebSocket request data.
+    networkWebSocketWillSendHandshakeRequestRequest :: NetworkWebSocketRequest
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkWebSocketWillSendHandshakeRequest where
+  parseJSON = A.withObject "NetworkWebSocketWillSendHandshakeRequest" $ \o -> NetworkWebSocketWillSendHandshakeRequest
+    <$> o A..: "requestId"
+    <*> o A..: "timestamp"
+    <*> o A..: "wallTime"
+    <*> o A..: "request"
+instance Event NetworkWebSocketWillSendHandshakeRequest where
+  eventName _ = "Network.webSocketWillSendHandshakeRequest"
+
+-- | Type of the 'Network.webTransportCreated' event.
+data NetworkWebTransportCreated = NetworkWebTransportCreated
+  {
+    -- | WebTransport identifier.
+    networkWebTransportCreatedTransportId :: NetworkRequestId,
+    -- | WebTransport request URL.
+    networkWebTransportCreatedUrl :: T.Text,
+    -- | Timestamp.
+    networkWebTransportCreatedTimestamp :: NetworkMonotonicTime,
+    -- | Request initiator.
+    networkWebTransportCreatedInitiator :: Maybe NetworkInitiator
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkWebTransportCreated where
+  parseJSON = A.withObject "NetworkWebTransportCreated" $ \o -> NetworkWebTransportCreated
+    <$> o A..: "transportId"
+    <*> o A..: "url"
+    <*> o A..: "timestamp"
+    <*> o A..:? "initiator"
+instance Event NetworkWebTransportCreated where
+  eventName _ = "Network.webTransportCreated"
+
+-- | Type of the 'Network.webTransportConnectionEstablished' event.
+data NetworkWebTransportConnectionEstablished = NetworkWebTransportConnectionEstablished
+  {
+    -- | WebTransport identifier.
+    networkWebTransportConnectionEstablishedTransportId :: NetworkRequestId,
+    -- | Timestamp.
+    networkWebTransportConnectionEstablishedTimestamp :: NetworkMonotonicTime
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkWebTransportConnectionEstablished where
+  parseJSON = A.withObject "NetworkWebTransportConnectionEstablished" $ \o -> NetworkWebTransportConnectionEstablished
+    <$> o A..: "transportId"
+    <*> o A..: "timestamp"
+instance Event NetworkWebTransportConnectionEstablished where
+  eventName _ = "Network.webTransportConnectionEstablished"
+
+-- | Type of the 'Network.webTransportClosed' event.
+data NetworkWebTransportClosed = NetworkWebTransportClosed
+  {
+    -- | WebTransport identifier.
+    networkWebTransportClosedTransportId :: NetworkRequestId,
+    -- | Timestamp.
+    networkWebTransportClosedTimestamp :: NetworkMonotonicTime
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkWebTransportClosed where
+  parseJSON = A.withObject "NetworkWebTransportClosed" $ \o -> NetworkWebTransportClosed
+    <$> o A..: "transportId"
+    <*> o A..: "timestamp"
+instance Event NetworkWebTransportClosed where
+  eventName _ = "Network.webTransportClosed"
+
+-- | Type of the 'Network.requestWillBeSentExtraInfo' event.
+data NetworkRequestWillBeSentExtraInfo = NetworkRequestWillBeSentExtraInfo
+  {
+    -- | Request identifier. Used to match this information to an existing requestWillBeSent event.
+    networkRequestWillBeSentExtraInfoRequestId :: NetworkRequestId,
+    -- | A list of cookies potentially associated to the requested URL. This includes both cookies sent with
+    --   the request and the ones not sent; the latter are distinguished by having blockedReason field set.
+    networkRequestWillBeSentExtraInfoAssociatedCookies :: [NetworkBlockedCookieWithReason],
+    -- | Raw request headers as they will be sent over the wire.
+    networkRequestWillBeSentExtraInfoHeaders :: NetworkHeaders,
+    -- | Connection timing information for the request.
+    networkRequestWillBeSentExtraInfoConnectTiming :: NetworkConnectTiming,
+    -- | The client security state set for the request.
+    networkRequestWillBeSentExtraInfoClientSecurityState :: Maybe NetworkClientSecurityState
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkRequestWillBeSentExtraInfo where
+  parseJSON = A.withObject "NetworkRequestWillBeSentExtraInfo" $ \o -> NetworkRequestWillBeSentExtraInfo
+    <$> o A..: "requestId"
+    <*> o A..: "associatedCookies"
+    <*> o A..: "headers"
+    <*> o A..: "connectTiming"
+    <*> o A..:? "clientSecurityState"
+instance Event NetworkRequestWillBeSentExtraInfo where
+  eventName _ = "Network.requestWillBeSentExtraInfo"
+
+-- | Type of the 'Network.responseReceivedExtraInfo' event.
+data NetworkResponseReceivedExtraInfo = NetworkResponseReceivedExtraInfo
+  {
+    -- | Request identifier. Used to match this information to another responseReceived event.
+    networkResponseReceivedExtraInfoRequestId :: NetworkRequestId,
+    -- | A list of cookies which were not stored from the response along with the corresponding
+    --   reasons for blocking. The cookies here may not be valid due to syntax errors, which
+    --   are represented by the invalid cookie line string instead of a proper cookie.
+    networkResponseReceivedExtraInfoBlockedCookies :: [NetworkBlockedSetCookieWithReason],
+    -- | Raw response headers as they were received over the wire.
+    networkResponseReceivedExtraInfoHeaders :: NetworkHeaders,
+    -- | The IP address space of the resource. The address space can only be determined once the transport
+    --   established the connection, so we can't send it in `requestWillBeSentExtraInfo`.
+    networkResponseReceivedExtraInfoResourceIPAddressSpace :: NetworkIPAddressSpace,
+    -- | The status code of the response. This is useful in cases the request failed and no responseReceived
+    --   event is triggered, which is the case for, e.g., CORS errors. This is also the correct status code
+    --   for cached requests, where the status in responseReceived is a 200 and this will be 304.
+    networkResponseReceivedExtraInfoStatusCode :: Int,
+    -- | Raw response header text as it was received over the wire. The raw text may not always be
+    --   available, such as in the case of HTTP/2 or QUIC.
+    networkResponseReceivedExtraInfoHeadersText :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkResponseReceivedExtraInfo where
+  parseJSON = A.withObject "NetworkResponseReceivedExtraInfo" $ \o -> NetworkResponseReceivedExtraInfo
+    <$> o A..: "requestId"
+    <*> o A..: "blockedCookies"
+    <*> o A..: "headers"
+    <*> o A..: "resourceIPAddressSpace"
+    <*> o A..: "statusCode"
+    <*> o A..:? "headersText"
+instance Event NetworkResponseReceivedExtraInfo where
+  eventName _ = "Network.responseReceivedExtraInfo"
+
+-- | Type of the 'Network.trustTokenOperationDone' event.
+data NetworkTrustTokenOperationDoneStatus = NetworkTrustTokenOperationDoneStatusOk | NetworkTrustTokenOperationDoneStatusInvalidArgument | NetworkTrustTokenOperationDoneStatusFailedPrecondition | NetworkTrustTokenOperationDoneStatusResourceExhausted | NetworkTrustTokenOperationDoneStatusAlreadyExists | NetworkTrustTokenOperationDoneStatusUnavailable | NetworkTrustTokenOperationDoneStatusBadResponse | NetworkTrustTokenOperationDoneStatusInternalError | NetworkTrustTokenOperationDoneStatusUnknownError | NetworkTrustTokenOperationDoneStatusFulfilledLocally
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON NetworkTrustTokenOperationDoneStatus where
+  parseJSON = A.withText "NetworkTrustTokenOperationDoneStatus" $ \v -> case v of
+    "Ok" -> pure NetworkTrustTokenOperationDoneStatusOk
+    "InvalidArgument" -> pure NetworkTrustTokenOperationDoneStatusInvalidArgument
+    "FailedPrecondition" -> pure NetworkTrustTokenOperationDoneStatusFailedPrecondition
+    "ResourceExhausted" -> pure NetworkTrustTokenOperationDoneStatusResourceExhausted
+    "AlreadyExists" -> pure NetworkTrustTokenOperationDoneStatusAlreadyExists
+    "Unavailable" -> pure NetworkTrustTokenOperationDoneStatusUnavailable
+    "BadResponse" -> pure NetworkTrustTokenOperationDoneStatusBadResponse
+    "InternalError" -> pure NetworkTrustTokenOperationDoneStatusInternalError
+    "UnknownError" -> pure NetworkTrustTokenOperationDoneStatusUnknownError
+    "FulfilledLocally" -> pure NetworkTrustTokenOperationDoneStatusFulfilledLocally
+    "_" -> fail "failed to parse NetworkTrustTokenOperationDoneStatus"
+instance ToJSON NetworkTrustTokenOperationDoneStatus where
+  toJSON v = A.String $ case v of
+    NetworkTrustTokenOperationDoneStatusOk -> "Ok"
+    NetworkTrustTokenOperationDoneStatusInvalidArgument -> "InvalidArgument"
+    NetworkTrustTokenOperationDoneStatusFailedPrecondition -> "FailedPrecondition"
+    NetworkTrustTokenOperationDoneStatusResourceExhausted -> "ResourceExhausted"
+    NetworkTrustTokenOperationDoneStatusAlreadyExists -> "AlreadyExists"
+    NetworkTrustTokenOperationDoneStatusUnavailable -> "Unavailable"
+    NetworkTrustTokenOperationDoneStatusBadResponse -> "BadResponse"
+    NetworkTrustTokenOperationDoneStatusInternalError -> "InternalError"
+    NetworkTrustTokenOperationDoneStatusUnknownError -> "UnknownError"
+    NetworkTrustTokenOperationDoneStatusFulfilledLocally -> "FulfilledLocally"
+data NetworkTrustTokenOperationDone = NetworkTrustTokenOperationDone
+  {
+    -- | Detailed success or error status of the operation.
+    --   'AlreadyExists' also signifies a successful operation, as the result
+    --   of the operation already exists und thus, the operation was abort
+    --   preemptively (e.g. a cache hit).
+    networkTrustTokenOperationDoneStatus :: NetworkTrustTokenOperationDoneStatus,
+    networkTrustTokenOperationDoneType :: NetworkTrustTokenOperationType,
+    networkTrustTokenOperationDoneRequestId :: NetworkRequestId,
+    -- | Top level origin. The context in which the operation was attempted.
+    networkTrustTokenOperationDoneTopLevelOrigin :: Maybe T.Text,
+    -- | Origin of the issuer in case of a "Issuance" or "Redemption" operation.
+    networkTrustTokenOperationDoneIssuerOrigin :: Maybe T.Text,
+    -- | The number of obtained Trust Tokens on a successful "Issuance" operation.
+    networkTrustTokenOperationDoneIssuedTokenCount :: Maybe Int
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkTrustTokenOperationDone where
+  parseJSON = A.withObject "NetworkTrustTokenOperationDone" $ \o -> NetworkTrustTokenOperationDone
+    <$> o A..: "status"
+    <*> o A..: "type"
+    <*> o A..: "requestId"
+    <*> o A..:? "topLevelOrigin"
+    <*> o A..:? "issuerOrigin"
+    <*> o A..:? "issuedTokenCount"
+instance Event NetworkTrustTokenOperationDone where
+  eventName _ = "Network.trustTokenOperationDone"
+
+-- | Type of the 'Network.subresourceWebBundleMetadataReceived' event.
+data NetworkSubresourceWebBundleMetadataReceived = NetworkSubresourceWebBundleMetadataReceived
+  {
+    -- | Request identifier. Used to match this information to another event.
+    networkSubresourceWebBundleMetadataReceivedRequestId :: NetworkRequestId,
+    -- | A list of URLs of resources in the subresource Web Bundle.
+    networkSubresourceWebBundleMetadataReceivedUrls :: [T.Text]
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkSubresourceWebBundleMetadataReceived where
+  parseJSON = A.withObject "NetworkSubresourceWebBundleMetadataReceived" $ \o -> NetworkSubresourceWebBundleMetadataReceived
+    <$> o A..: "requestId"
+    <*> o A..: "urls"
+instance Event NetworkSubresourceWebBundleMetadataReceived where
+  eventName _ = "Network.subresourceWebBundleMetadataReceived"
+
+-- | Type of the 'Network.subresourceWebBundleMetadataError' event.
+data NetworkSubresourceWebBundleMetadataError = NetworkSubresourceWebBundleMetadataError
+  {
+    -- | Request identifier. Used to match this information to another event.
+    networkSubresourceWebBundleMetadataErrorRequestId :: NetworkRequestId,
+    -- | Error message
+    networkSubresourceWebBundleMetadataErrorErrorMessage :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkSubresourceWebBundleMetadataError where
+  parseJSON = A.withObject "NetworkSubresourceWebBundleMetadataError" $ \o -> NetworkSubresourceWebBundleMetadataError
+    <$> o A..: "requestId"
+    <*> o A..: "errorMessage"
+instance Event NetworkSubresourceWebBundleMetadataError where
+  eventName _ = "Network.subresourceWebBundleMetadataError"
+
+-- | Type of the 'Network.subresourceWebBundleInnerResponseParsed' event.
+data NetworkSubresourceWebBundleInnerResponseParsed = NetworkSubresourceWebBundleInnerResponseParsed
+  {
+    -- | Request identifier of the subresource request
+    networkSubresourceWebBundleInnerResponseParsedInnerRequestId :: NetworkRequestId,
+    -- | URL of the subresource resource.
+    networkSubresourceWebBundleInnerResponseParsedInnerRequestURL :: T.Text,
+    -- | Bundle request identifier. Used to match this information to another event.
+    --   This made be absent in case when the instrumentation was enabled only
+    --   after webbundle was parsed.
+    networkSubresourceWebBundleInnerResponseParsedBundleRequestId :: Maybe NetworkRequestId
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkSubresourceWebBundleInnerResponseParsed where
+  parseJSON = A.withObject "NetworkSubresourceWebBundleInnerResponseParsed" $ \o -> NetworkSubresourceWebBundleInnerResponseParsed
+    <$> o A..: "innerRequestId"
+    <*> o A..: "innerRequestURL"
+    <*> o A..:? "bundleRequestId"
+instance Event NetworkSubresourceWebBundleInnerResponseParsed where
+  eventName _ = "Network.subresourceWebBundleInnerResponseParsed"
+
+-- | Type of the 'Network.subresourceWebBundleInnerResponseError' event.
+data NetworkSubresourceWebBundleInnerResponseError = NetworkSubresourceWebBundleInnerResponseError
+  {
+    -- | Request identifier of the subresource request
+    networkSubresourceWebBundleInnerResponseErrorInnerRequestId :: NetworkRequestId,
+    -- | URL of the subresource resource.
+    networkSubresourceWebBundleInnerResponseErrorInnerRequestURL :: T.Text,
+    -- | Error message
+    networkSubresourceWebBundleInnerResponseErrorErrorMessage :: T.Text,
+    -- | Bundle request identifier. Used to match this information to another event.
+    --   This made be absent in case when the instrumentation was enabled only
+    --   after webbundle was parsed.
+    networkSubresourceWebBundleInnerResponseErrorBundleRequestId :: Maybe NetworkRequestId
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkSubresourceWebBundleInnerResponseError where
+  parseJSON = A.withObject "NetworkSubresourceWebBundleInnerResponseError" $ \o -> NetworkSubresourceWebBundleInnerResponseError
+    <$> o A..: "innerRequestId"
+    <*> o A..: "innerRequestURL"
+    <*> o A..: "errorMessage"
+    <*> o A..:? "bundleRequestId"
+instance Event NetworkSubresourceWebBundleInnerResponseError where
+  eventName _ = "Network.subresourceWebBundleInnerResponseError"
+
+-- | Type of the 'Network.reportingApiReportAdded' event.
+data NetworkReportingApiReportAdded = NetworkReportingApiReportAdded
+  {
+    networkReportingApiReportAddedReport :: NetworkReportingApiReport
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkReportingApiReportAdded where
+  parseJSON = A.withObject "NetworkReportingApiReportAdded" $ \o -> NetworkReportingApiReportAdded
+    <$> o A..: "report"
+instance Event NetworkReportingApiReportAdded where
+  eventName _ = "Network.reportingApiReportAdded"
+
+-- | Type of the 'Network.reportingApiReportUpdated' event.
+data NetworkReportingApiReportUpdated = NetworkReportingApiReportUpdated
+  {
+    networkReportingApiReportUpdatedReport :: NetworkReportingApiReport
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkReportingApiReportUpdated where
+  parseJSON = A.withObject "NetworkReportingApiReportUpdated" $ \o -> NetworkReportingApiReportUpdated
+    <$> o A..: "report"
+instance Event NetworkReportingApiReportUpdated where
+  eventName _ = "Network.reportingApiReportUpdated"
+
+-- | Type of the 'Network.reportingApiEndpointsChangedForOrigin' event.
+data NetworkReportingApiEndpointsChangedForOrigin = NetworkReportingApiEndpointsChangedForOrigin
+  {
+    -- | Origin of the document(s) which configured the endpoints.
+    networkReportingApiEndpointsChangedForOriginOrigin :: T.Text,
+    networkReportingApiEndpointsChangedForOriginEndpoints :: [NetworkReportingApiEndpoint]
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkReportingApiEndpointsChangedForOrigin where
+  parseJSON = A.withObject "NetworkReportingApiEndpointsChangedForOrigin" $ \o -> NetworkReportingApiEndpointsChangedForOrigin
+    <$> o A..: "origin"
+    <*> o A..: "endpoints"
+instance Event NetworkReportingApiEndpointsChangedForOrigin where
+  eventName _ = "Network.reportingApiEndpointsChangedForOrigin"
+
+-- | Sets a list of content encodings that will be accepted. Empty list means no encoding is accepted.
+
+-- | Parameters of the 'Network.setAcceptedEncodings' command.
+data PNetworkSetAcceptedEncodings = PNetworkSetAcceptedEncodings
+  {
+    -- | List of accepted content encodings.
+    pNetworkSetAcceptedEncodingsEncodings :: [NetworkContentEncoding]
+  }
+  deriving (Eq, Show)
+pNetworkSetAcceptedEncodings
+  {-
+  -- | List of accepted content encodings.
+  -}
+  :: [NetworkContentEncoding]
+  -> PNetworkSetAcceptedEncodings
+pNetworkSetAcceptedEncodings
+  arg_pNetworkSetAcceptedEncodingsEncodings
+  = PNetworkSetAcceptedEncodings
+    arg_pNetworkSetAcceptedEncodingsEncodings
+instance ToJSON PNetworkSetAcceptedEncodings where
+  toJSON p = A.object $ catMaybes [
+    ("encodings" A..=) <$> Just (pNetworkSetAcceptedEncodingsEncodings p)
+    ]
+instance Command PNetworkSetAcceptedEncodings where
+  type CommandResponse PNetworkSetAcceptedEncodings = ()
+  commandName _ = "Network.setAcceptedEncodings"
+  fromJSON = const . A.Success . const ()
+
+-- | Clears accepted encodings set by setAcceptedEncodings
+
+-- | Parameters of the 'Network.clearAcceptedEncodingsOverride' command.
+data PNetworkClearAcceptedEncodingsOverride = PNetworkClearAcceptedEncodingsOverride
+  deriving (Eq, Show)
+pNetworkClearAcceptedEncodingsOverride
+  :: PNetworkClearAcceptedEncodingsOverride
+pNetworkClearAcceptedEncodingsOverride
+  = PNetworkClearAcceptedEncodingsOverride
+instance ToJSON PNetworkClearAcceptedEncodingsOverride where
+  toJSON _ = A.Null
+instance Command PNetworkClearAcceptedEncodingsOverride where
+  type CommandResponse PNetworkClearAcceptedEncodingsOverride = ()
+  commandName _ = "Network.clearAcceptedEncodingsOverride"
+  fromJSON = const . A.Success . const ()
+
+-- | Clears browser cache.
+
+-- | Parameters of the 'Network.clearBrowserCache' command.
+data PNetworkClearBrowserCache = PNetworkClearBrowserCache
+  deriving (Eq, Show)
+pNetworkClearBrowserCache
+  :: PNetworkClearBrowserCache
+pNetworkClearBrowserCache
+  = PNetworkClearBrowserCache
+instance ToJSON PNetworkClearBrowserCache where
+  toJSON _ = A.Null
+instance Command PNetworkClearBrowserCache where
+  type CommandResponse PNetworkClearBrowserCache = ()
+  commandName _ = "Network.clearBrowserCache"
+  fromJSON = const . A.Success . const ()
+
+-- | Clears browser cookies.
+
+-- | Parameters of the 'Network.clearBrowserCookies' command.
+data PNetworkClearBrowserCookies = PNetworkClearBrowserCookies
+  deriving (Eq, Show)
+pNetworkClearBrowserCookies
+  :: PNetworkClearBrowserCookies
+pNetworkClearBrowserCookies
+  = PNetworkClearBrowserCookies
+instance ToJSON PNetworkClearBrowserCookies where
+  toJSON _ = A.Null
+instance Command PNetworkClearBrowserCookies where
+  type CommandResponse PNetworkClearBrowserCookies = ()
+  commandName _ = "Network.clearBrowserCookies"
+  fromJSON = const . A.Success . const ()
+
+-- | Deletes browser cookies with matching name and url or domain/path pair.
+
+-- | Parameters of the 'Network.deleteCookies' command.
+data PNetworkDeleteCookies = PNetworkDeleteCookies
+  {
+    -- | Name of the cookies to remove.
+    pNetworkDeleteCookiesName :: T.Text,
+    -- | If specified, deletes all the cookies with the given name where domain and path match
+    --   provided URL.
+    pNetworkDeleteCookiesUrl :: Maybe T.Text,
+    -- | If specified, deletes only cookies with the exact domain.
+    pNetworkDeleteCookiesDomain :: Maybe T.Text,
+    -- | If specified, deletes only cookies with the exact path.
+    pNetworkDeleteCookiesPath :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+pNetworkDeleteCookies
+  {-
+  -- | Name of the cookies to remove.
+  -}
+  :: T.Text
+  -> PNetworkDeleteCookies
+pNetworkDeleteCookies
+  arg_pNetworkDeleteCookiesName
+  = PNetworkDeleteCookies
+    arg_pNetworkDeleteCookiesName
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PNetworkDeleteCookies where
+  toJSON p = A.object $ catMaybes [
+    ("name" A..=) <$> Just (pNetworkDeleteCookiesName p),
+    ("url" A..=) <$> (pNetworkDeleteCookiesUrl p),
+    ("domain" A..=) <$> (pNetworkDeleteCookiesDomain p),
+    ("path" A..=) <$> (pNetworkDeleteCookiesPath p)
+    ]
+instance Command PNetworkDeleteCookies where
+  type CommandResponse PNetworkDeleteCookies = ()
+  commandName _ = "Network.deleteCookies"
+  fromJSON = const . A.Success . const ()
+
+-- | Disables network tracking, prevents network events from being sent to the client.
+
+-- | Parameters of the 'Network.disable' command.
+data PNetworkDisable = PNetworkDisable
+  deriving (Eq, Show)
+pNetworkDisable
+  :: PNetworkDisable
+pNetworkDisable
+  = PNetworkDisable
+instance ToJSON PNetworkDisable where
+  toJSON _ = A.Null
+instance Command PNetworkDisable where
+  type CommandResponse PNetworkDisable = ()
+  commandName _ = "Network.disable"
+  fromJSON = const . A.Success . const ()
+
+-- | Activates emulation of network conditions.
+
+-- | Parameters of the 'Network.emulateNetworkConditions' command.
+data PNetworkEmulateNetworkConditions = PNetworkEmulateNetworkConditions
+  {
+    -- | True to emulate internet disconnection.
+    pNetworkEmulateNetworkConditionsOffline :: Bool,
+    -- | Minimum latency from request sent to response headers received (ms).
+    pNetworkEmulateNetworkConditionsLatency :: Double,
+    -- | Maximal aggregated download throughput (bytes/sec). -1 disables download throttling.
+    pNetworkEmulateNetworkConditionsDownloadThroughput :: Double,
+    -- | Maximal aggregated upload throughput (bytes/sec).  -1 disables upload throttling.
+    pNetworkEmulateNetworkConditionsUploadThroughput :: Double,
+    -- | Connection type if known.
+    pNetworkEmulateNetworkConditionsConnectionType :: Maybe NetworkConnectionType
+  }
+  deriving (Eq, Show)
+pNetworkEmulateNetworkConditions
+  {-
+  -- | True to emulate internet disconnection.
+  -}
+  :: Bool
+  {-
+  -- | Minimum latency from request sent to response headers received (ms).
+  -}
+  -> Double
+  {-
+  -- | Maximal aggregated download throughput (bytes/sec). -1 disables download throttling.
+  -}
+  -> Double
+  {-
+  -- | Maximal aggregated upload throughput (bytes/sec).  -1 disables upload throttling.
+  -}
+  -> Double
+  -> PNetworkEmulateNetworkConditions
+pNetworkEmulateNetworkConditions
+  arg_pNetworkEmulateNetworkConditionsOffline
+  arg_pNetworkEmulateNetworkConditionsLatency
+  arg_pNetworkEmulateNetworkConditionsDownloadThroughput
+  arg_pNetworkEmulateNetworkConditionsUploadThroughput
+  = PNetworkEmulateNetworkConditions
+    arg_pNetworkEmulateNetworkConditionsOffline
+    arg_pNetworkEmulateNetworkConditionsLatency
+    arg_pNetworkEmulateNetworkConditionsDownloadThroughput
+    arg_pNetworkEmulateNetworkConditionsUploadThroughput
+    Nothing
+instance ToJSON PNetworkEmulateNetworkConditions where
+  toJSON p = A.object $ catMaybes [
+    ("offline" A..=) <$> Just (pNetworkEmulateNetworkConditionsOffline p),
+    ("latency" A..=) <$> Just (pNetworkEmulateNetworkConditionsLatency p),
+    ("downloadThroughput" A..=) <$> Just (pNetworkEmulateNetworkConditionsDownloadThroughput p),
+    ("uploadThroughput" A..=) <$> Just (pNetworkEmulateNetworkConditionsUploadThroughput p),
+    ("connectionType" A..=) <$> (pNetworkEmulateNetworkConditionsConnectionType p)
+    ]
+instance Command PNetworkEmulateNetworkConditions where
+  type CommandResponse PNetworkEmulateNetworkConditions = ()
+  commandName _ = "Network.emulateNetworkConditions"
+  fromJSON = const . A.Success . const ()
+
+-- | Enables network tracking, network events will now be delivered to the client.
+
+-- | Parameters of the 'Network.enable' command.
+data PNetworkEnable = PNetworkEnable
+  {
+    -- | Buffer size in bytes to use when preserving network payloads (XHRs, etc).
+    pNetworkEnableMaxTotalBufferSize :: Maybe Int,
+    -- | Per-resource buffer size in bytes to use when preserving network payloads (XHRs, etc).
+    pNetworkEnableMaxResourceBufferSize :: Maybe Int,
+    -- | Longest post body size (in bytes) that would be included in requestWillBeSent notification
+    pNetworkEnableMaxPostDataSize :: Maybe Int
+  }
+  deriving (Eq, Show)
+pNetworkEnable
+  :: PNetworkEnable
+pNetworkEnable
+  = PNetworkEnable
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PNetworkEnable where
+  toJSON p = A.object $ catMaybes [
+    ("maxTotalBufferSize" A..=) <$> (pNetworkEnableMaxTotalBufferSize p),
+    ("maxResourceBufferSize" A..=) <$> (pNetworkEnableMaxResourceBufferSize p),
+    ("maxPostDataSize" A..=) <$> (pNetworkEnableMaxPostDataSize p)
+    ]
+instance Command PNetworkEnable where
+  type CommandResponse PNetworkEnable = ()
+  commandName _ = "Network.enable"
+  fromJSON = const . A.Success . const ()
+
+-- | Returns all browser cookies. Depending on the backend support, will return detailed cookie
+--   information in the `cookies` field.
+
+-- | Parameters of the 'Network.getAllCookies' command.
+data PNetworkGetAllCookies = PNetworkGetAllCookies
+  deriving (Eq, Show)
+pNetworkGetAllCookies
+  :: PNetworkGetAllCookies
+pNetworkGetAllCookies
+  = PNetworkGetAllCookies
+instance ToJSON PNetworkGetAllCookies where
+  toJSON _ = A.Null
+data NetworkGetAllCookies = NetworkGetAllCookies
+  {
+    -- | Array of cookie objects.
+    networkGetAllCookiesCookies :: [NetworkCookie]
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkGetAllCookies where
+  parseJSON = A.withObject "NetworkGetAllCookies" $ \o -> NetworkGetAllCookies
+    <$> o A..: "cookies"
+instance Command PNetworkGetAllCookies where
+  type CommandResponse PNetworkGetAllCookies = NetworkGetAllCookies
+  commandName _ = "Network.getAllCookies"
+
+-- | Returns the DER-encoded certificate.
+
+-- | Parameters of the 'Network.getCertificate' command.
+data PNetworkGetCertificate = PNetworkGetCertificate
+  {
+    -- | Origin to get certificate for.
+    pNetworkGetCertificateOrigin :: T.Text
+  }
+  deriving (Eq, Show)
+pNetworkGetCertificate
+  {-
+  -- | Origin to get certificate for.
+  -}
+  :: T.Text
+  -> PNetworkGetCertificate
+pNetworkGetCertificate
+  arg_pNetworkGetCertificateOrigin
+  = PNetworkGetCertificate
+    arg_pNetworkGetCertificateOrigin
+instance ToJSON PNetworkGetCertificate where
+  toJSON p = A.object $ catMaybes [
+    ("origin" A..=) <$> Just (pNetworkGetCertificateOrigin p)
+    ]
+data NetworkGetCertificate = NetworkGetCertificate
+  {
+    networkGetCertificateTableNames :: [T.Text]
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkGetCertificate where
+  parseJSON = A.withObject "NetworkGetCertificate" $ \o -> NetworkGetCertificate
+    <$> o A..: "tableNames"
+instance Command PNetworkGetCertificate where
+  type CommandResponse PNetworkGetCertificate = NetworkGetCertificate
+  commandName _ = "Network.getCertificate"
+
+-- | Returns all browser cookies for the current URL. Depending on the backend support, will return
+--   detailed cookie information in the `cookies` field.
+
+-- | Parameters of the 'Network.getCookies' command.
+data PNetworkGetCookies = PNetworkGetCookies
+  {
+    -- | The list of URLs for which applicable cookies will be fetched.
+    --   If not specified, it's assumed to be set to the list containing
+    --   the URLs of the page and all of its subframes.
+    pNetworkGetCookiesUrls :: Maybe [T.Text]
+  }
+  deriving (Eq, Show)
+pNetworkGetCookies
+  :: PNetworkGetCookies
+pNetworkGetCookies
+  = PNetworkGetCookies
+    Nothing
+instance ToJSON PNetworkGetCookies where
+  toJSON p = A.object $ catMaybes [
+    ("urls" A..=) <$> (pNetworkGetCookiesUrls p)
+    ]
+data NetworkGetCookies = NetworkGetCookies
+  {
+    -- | Array of cookie objects.
+    networkGetCookiesCookies :: [NetworkCookie]
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkGetCookies where
+  parseJSON = A.withObject "NetworkGetCookies" $ \o -> NetworkGetCookies
+    <$> o A..: "cookies"
+instance Command PNetworkGetCookies where
+  type CommandResponse PNetworkGetCookies = NetworkGetCookies
+  commandName _ = "Network.getCookies"
+
+-- | Returns content served for the given request.
+
+-- | Parameters of the 'Network.getResponseBody' command.
+data PNetworkGetResponseBody = PNetworkGetResponseBody
+  {
+    -- | Identifier of the network request to get content for.
+    pNetworkGetResponseBodyRequestId :: NetworkRequestId
+  }
+  deriving (Eq, Show)
+pNetworkGetResponseBody
+  {-
+  -- | Identifier of the network request to get content for.
+  -}
+  :: NetworkRequestId
+  -> PNetworkGetResponseBody
+pNetworkGetResponseBody
+  arg_pNetworkGetResponseBodyRequestId
+  = PNetworkGetResponseBody
+    arg_pNetworkGetResponseBodyRequestId
+instance ToJSON PNetworkGetResponseBody where
+  toJSON p = A.object $ catMaybes [
+    ("requestId" A..=) <$> Just (pNetworkGetResponseBodyRequestId p)
+    ]
+data NetworkGetResponseBody = NetworkGetResponseBody
+  {
+    -- | Response body.
+    networkGetResponseBodyBody :: T.Text,
+    -- | True, if content was sent as base64.
+    networkGetResponseBodyBase64Encoded :: Bool
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkGetResponseBody where
+  parseJSON = A.withObject "NetworkGetResponseBody" $ \o -> NetworkGetResponseBody
+    <$> o A..: "body"
+    <*> o A..: "base64Encoded"
+instance Command PNetworkGetResponseBody where
+  type CommandResponse PNetworkGetResponseBody = NetworkGetResponseBody
+  commandName _ = "Network.getResponseBody"
+
+-- | Returns post data sent with the request. Returns an error when no data was sent with the request.
+
+-- | Parameters of the 'Network.getRequestPostData' command.
+data PNetworkGetRequestPostData = PNetworkGetRequestPostData
+  {
+    -- | Identifier of the network request to get content for.
+    pNetworkGetRequestPostDataRequestId :: NetworkRequestId
+  }
+  deriving (Eq, Show)
+pNetworkGetRequestPostData
+  {-
+  -- | Identifier of the network request to get content for.
+  -}
+  :: NetworkRequestId
+  -> PNetworkGetRequestPostData
+pNetworkGetRequestPostData
+  arg_pNetworkGetRequestPostDataRequestId
+  = PNetworkGetRequestPostData
+    arg_pNetworkGetRequestPostDataRequestId
+instance ToJSON PNetworkGetRequestPostData where
+  toJSON p = A.object $ catMaybes [
+    ("requestId" A..=) <$> Just (pNetworkGetRequestPostDataRequestId p)
+    ]
+data NetworkGetRequestPostData = NetworkGetRequestPostData
+  {
+    -- | Request body string, omitting files from multipart requests
+    networkGetRequestPostDataPostData :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkGetRequestPostData where
+  parseJSON = A.withObject "NetworkGetRequestPostData" $ \o -> NetworkGetRequestPostData
+    <$> o A..: "postData"
+instance Command PNetworkGetRequestPostData where
+  type CommandResponse PNetworkGetRequestPostData = NetworkGetRequestPostData
+  commandName _ = "Network.getRequestPostData"
+
+-- | Returns content served for the given currently intercepted request.
+
+-- | Parameters of the 'Network.getResponseBodyForInterception' command.
+data PNetworkGetResponseBodyForInterception = PNetworkGetResponseBodyForInterception
+  {
+    -- | Identifier for the intercepted request to get body for.
+    pNetworkGetResponseBodyForInterceptionInterceptionId :: NetworkInterceptionId
+  }
+  deriving (Eq, Show)
+pNetworkGetResponseBodyForInterception
+  {-
+  -- | Identifier for the intercepted request to get body for.
+  -}
+  :: NetworkInterceptionId
+  -> PNetworkGetResponseBodyForInterception
+pNetworkGetResponseBodyForInterception
+  arg_pNetworkGetResponseBodyForInterceptionInterceptionId
+  = PNetworkGetResponseBodyForInterception
+    arg_pNetworkGetResponseBodyForInterceptionInterceptionId
+instance ToJSON PNetworkGetResponseBodyForInterception where
+  toJSON p = A.object $ catMaybes [
+    ("interceptionId" A..=) <$> Just (pNetworkGetResponseBodyForInterceptionInterceptionId p)
+    ]
+data NetworkGetResponseBodyForInterception = NetworkGetResponseBodyForInterception
+  {
+    -- | Response body.
+    networkGetResponseBodyForInterceptionBody :: T.Text,
+    -- | True, if content was sent as base64.
+    networkGetResponseBodyForInterceptionBase64Encoded :: Bool
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkGetResponseBodyForInterception where
+  parseJSON = A.withObject "NetworkGetResponseBodyForInterception" $ \o -> NetworkGetResponseBodyForInterception
+    <$> o A..: "body"
+    <*> o A..: "base64Encoded"
+instance Command PNetworkGetResponseBodyForInterception where
+  type CommandResponse PNetworkGetResponseBodyForInterception = NetworkGetResponseBodyForInterception
+  commandName _ = "Network.getResponseBodyForInterception"
+
+-- | Returns a handle to the stream representing the response body. Note that after this command,
+--   the intercepted request can't be continued as is -- you either need to cancel it or to provide
+--   the response body. The stream only supports sequential read, IO.read will fail if the position
+--   is specified.
+
+-- | Parameters of the 'Network.takeResponseBodyForInterceptionAsStream' command.
+data PNetworkTakeResponseBodyForInterceptionAsStream = PNetworkTakeResponseBodyForInterceptionAsStream
+  {
+    pNetworkTakeResponseBodyForInterceptionAsStreamInterceptionId :: NetworkInterceptionId
+  }
+  deriving (Eq, Show)
+pNetworkTakeResponseBodyForInterceptionAsStream
+  :: NetworkInterceptionId
+  -> PNetworkTakeResponseBodyForInterceptionAsStream
+pNetworkTakeResponseBodyForInterceptionAsStream
+  arg_pNetworkTakeResponseBodyForInterceptionAsStreamInterceptionId
+  = PNetworkTakeResponseBodyForInterceptionAsStream
+    arg_pNetworkTakeResponseBodyForInterceptionAsStreamInterceptionId
+instance ToJSON PNetworkTakeResponseBodyForInterceptionAsStream where
+  toJSON p = A.object $ catMaybes [
+    ("interceptionId" A..=) <$> Just (pNetworkTakeResponseBodyForInterceptionAsStreamInterceptionId p)
+    ]
+data NetworkTakeResponseBodyForInterceptionAsStream = NetworkTakeResponseBodyForInterceptionAsStream
+  {
+    networkTakeResponseBodyForInterceptionAsStreamStream :: IO.IOStreamHandle
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkTakeResponseBodyForInterceptionAsStream where
+  parseJSON = A.withObject "NetworkTakeResponseBodyForInterceptionAsStream" $ \o -> NetworkTakeResponseBodyForInterceptionAsStream
+    <$> o A..: "stream"
+instance Command PNetworkTakeResponseBodyForInterceptionAsStream where
+  type CommandResponse PNetworkTakeResponseBodyForInterceptionAsStream = NetworkTakeResponseBodyForInterceptionAsStream
+  commandName _ = "Network.takeResponseBodyForInterceptionAsStream"
+
+-- | This method sends a new XMLHttpRequest which is identical to the original one. The following
+--   parameters should be identical: method, url, async, request body, extra headers, withCredentials
+--   attribute, user, password.
+
+-- | Parameters of the 'Network.replayXHR' command.
+data PNetworkReplayXHR = PNetworkReplayXHR
+  {
+    -- | Identifier of XHR to replay.
+    pNetworkReplayXHRRequestId :: NetworkRequestId
+  }
+  deriving (Eq, Show)
+pNetworkReplayXHR
+  {-
+  -- | Identifier of XHR to replay.
+  -}
+  :: NetworkRequestId
+  -> PNetworkReplayXHR
+pNetworkReplayXHR
+  arg_pNetworkReplayXHRRequestId
+  = PNetworkReplayXHR
+    arg_pNetworkReplayXHRRequestId
+instance ToJSON PNetworkReplayXHR where
+  toJSON p = A.object $ catMaybes [
+    ("requestId" A..=) <$> Just (pNetworkReplayXHRRequestId p)
+    ]
+instance Command PNetworkReplayXHR where
+  type CommandResponse PNetworkReplayXHR = ()
+  commandName _ = "Network.replayXHR"
+  fromJSON = const . A.Success . const ()
+
+-- | Searches for given string in response content.
+
+-- | Parameters of the 'Network.searchInResponseBody' command.
+data PNetworkSearchInResponseBody = PNetworkSearchInResponseBody
+  {
+    -- | Identifier of the network response to search.
+    pNetworkSearchInResponseBodyRequestId :: NetworkRequestId,
+    -- | String to search for.
+    pNetworkSearchInResponseBodyQuery :: T.Text,
+    -- | If true, search is case sensitive.
+    pNetworkSearchInResponseBodyCaseSensitive :: Maybe Bool,
+    -- | If true, treats string parameter as regex.
+    pNetworkSearchInResponseBodyIsRegex :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pNetworkSearchInResponseBody
+  {-
+  -- | Identifier of the network response to search.
+  -}
+  :: NetworkRequestId
+  {-
+  -- | String to search for.
+  -}
+  -> T.Text
+  -> PNetworkSearchInResponseBody
+pNetworkSearchInResponseBody
+  arg_pNetworkSearchInResponseBodyRequestId
+  arg_pNetworkSearchInResponseBodyQuery
+  = PNetworkSearchInResponseBody
+    arg_pNetworkSearchInResponseBodyRequestId
+    arg_pNetworkSearchInResponseBodyQuery
+    Nothing
+    Nothing
+instance ToJSON PNetworkSearchInResponseBody where
+  toJSON p = A.object $ catMaybes [
+    ("requestId" A..=) <$> Just (pNetworkSearchInResponseBodyRequestId p),
+    ("query" A..=) <$> Just (pNetworkSearchInResponseBodyQuery p),
+    ("caseSensitive" A..=) <$> (pNetworkSearchInResponseBodyCaseSensitive p),
+    ("isRegex" A..=) <$> (pNetworkSearchInResponseBodyIsRegex p)
+    ]
+data NetworkSearchInResponseBody = NetworkSearchInResponseBody
+  {
+    -- | List of search matches.
+    networkSearchInResponseBodyResult :: [Debugger.DebuggerSearchMatch]
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkSearchInResponseBody where
+  parseJSON = A.withObject "NetworkSearchInResponseBody" $ \o -> NetworkSearchInResponseBody
+    <$> o A..: "result"
+instance Command PNetworkSearchInResponseBody where
+  type CommandResponse PNetworkSearchInResponseBody = NetworkSearchInResponseBody
+  commandName _ = "Network.searchInResponseBody"
+
+-- | Blocks URLs from loading.
+
+-- | Parameters of the 'Network.setBlockedURLs' command.
+data PNetworkSetBlockedURLs = PNetworkSetBlockedURLs
+  {
+    -- | URL patterns to block. Wildcards ('*') are allowed.
+    pNetworkSetBlockedURLsUrls :: [T.Text]
+  }
+  deriving (Eq, Show)
+pNetworkSetBlockedURLs
+  {-
+  -- | URL patterns to block. Wildcards ('*') are allowed.
+  -}
+  :: [T.Text]
+  -> PNetworkSetBlockedURLs
+pNetworkSetBlockedURLs
+  arg_pNetworkSetBlockedURLsUrls
+  = PNetworkSetBlockedURLs
+    arg_pNetworkSetBlockedURLsUrls
+instance ToJSON PNetworkSetBlockedURLs where
+  toJSON p = A.object $ catMaybes [
+    ("urls" A..=) <$> Just (pNetworkSetBlockedURLsUrls p)
+    ]
+instance Command PNetworkSetBlockedURLs where
+  type CommandResponse PNetworkSetBlockedURLs = ()
+  commandName _ = "Network.setBlockedURLs"
+  fromJSON = const . A.Success . const ()
+
+-- | Toggles ignoring of service worker for each request.
+
+-- | Parameters of the 'Network.setBypassServiceWorker' command.
+data PNetworkSetBypassServiceWorker = PNetworkSetBypassServiceWorker
+  {
+    -- | Bypass service worker and load from network.
+    pNetworkSetBypassServiceWorkerBypass :: Bool
+  }
+  deriving (Eq, Show)
+pNetworkSetBypassServiceWorker
+  {-
+  -- | Bypass service worker and load from network.
+  -}
+  :: Bool
+  -> PNetworkSetBypassServiceWorker
+pNetworkSetBypassServiceWorker
+  arg_pNetworkSetBypassServiceWorkerBypass
+  = PNetworkSetBypassServiceWorker
+    arg_pNetworkSetBypassServiceWorkerBypass
+instance ToJSON PNetworkSetBypassServiceWorker where
+  toJSON p = A.object $ catMaybes [
+    ("bypass" A..=) <$> Just (pNetworkSetBypassServiceWorkerBypass p)
+    ]
+instance Command PNetworkSetBypassServiceWorker where
+  type CommandResponse PNetworkSetBypassServiceWorker = ()
+  commandName _ = "Network.setBypassServiceWorker"
+  fromJSON = const . A.Success . const ()
+
+-- | Toggles ignoring cache for each request. If `true`, cache will not be used.
+
+-- | Parameters of the 'Network.setCacheDisabled' command.
+data PNetworkSetCacheDisabled = PNetworkSetCacheDisabled
+  {
+    -- | Cache disabled state.
+    pNetworkSetCacheDisabledCacheDisabled :: Bool
+  }
+  deriving (Eq, Show)
+pNetworkSetCacheDisabled
+  {-
+  -- | Cache disabled state.
+  -}
+  :: Bool
+  -> PNetworkSetCacheDisabled
+pNetworkSetCacheDisabled
+  arg_pNetworkSetCacheDisabledCacheDisabled
+  = PNetworkSetCacheDisabled
+    arg_pNetworkSetCacheDisabledCacheDisabled
+instance ToJSON PNetworkSetCacheDisabled where
+  toJSON p = A.object $ catMaybes [
+    ("cacheDisabled" A..=) <$> Just (pNetworkSetCacheDisabledCacheDisabled p)
+    ]
+instance Command PNetworkSetCacheDisabled where
+  type CommandResponse PNetworkSetCacheDisabled = ()
+  commandName _ = "Network.setCacheDisabled"
+  fromJSON = const . A.Success . const ()
+
+-- | Sets a cookie with the given cookie data; may overwrite equivalent cookies if they exist.
+
+-- | Parameters of the 'Network.setCookie' command.
+data PNetworkSetCookie = PNetworkSetCookie
+  {
+    -- | Cookie name.
+    pNetworkSetCookieName :: T.Text,
+    -- | Cookie value.
+    pNetworkSetCookieValue :: T.Text,
+    -- | The request-URI to associate with the setting of the cookie. This value can affect the
+    --   default domain, path, source port, and source scheme values of the created cookie.
+    pNetworkSetCookieUrl :: Maybe T.Text,
+    -- | Cookie domain.
+    pNetworkSetCookieDomain :: Maybe T.Text,
+    -- | Cookie path.
+    pNetworkSetCookiePath :: Maybe T.Text,
+    -- | True if cookie is secure.
+    pNetworkSetCookieSecure :: Maybe Bool,
+    -- | True if cookie is http-only.
+    pNetworkSetCookieHttpOnly :: Maybe Bool,
+    -- | Cookie SameSite type.
+    pNetworkSetCookieSameSite :: Maybe NetworkCookieSameSite,
+    -- | Cookie expiration date, session cookie if not set
+    pNetworkSetCookieExpires :: Maybe NetworkTimeSinceEpoch,
+    -- | Cookie Priority type.
+    pNetworkSetCookiePriority :: Maybe NetworkCookiePriority,
+    -- | True if cookie is SameParty.
+    pNetworkSetCookieSameParty :: Maybe Bool,
+    -- | Cookie source scheme type.
+    pNetworkSetCookieSourceScheme :: Maybe NetworkCookieSourceScheme,
+    -- | Cookie source port. Valid values are {-1, [1, 65535]}, -1 indicates an unspecified port.
+    --   An unspecified port value allows protocol clients to emulate legacy cookie scope for the port.
+    --   This is a temporary ability and it will be removed in the future.
+    pNetworkSetCookieSourcePort :: Maybe Int,
+    -- | Cookie partition key. The site of the top-level URL the browser was visiting at the start
+    --   of the request to the endpoint that set the cookie.
+    --   If not set, the cookie will be set as not partitioned.
+    pNetworkSetCookiePartitionKey :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+pNetworkSetCookie
+  {-
+  -- | Cookie name.
+  -}
+  :: T.Text
+  {-
+  -- | Cookie value.
+  -}
+  -> T.Text
+  -> PNetworkSetCookie
+pNetworkSetCookie
+  arg_pNetworkSetCookieName
+  arg_pNetworkSetCookieValue
+  = PNetworkSetCookie
+    arg_pNetworkSetCookieName
+    arg_pNetworkSetCookieValue
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PNetworkSetCookie where
+  toJSON p = A.object $ catMaybes [
+    ("name" A..=) <$> Just (pNetworkSetCookieName p),
+    ("value" A..=) <$> Just (pNetworkSetCookieValue p),
+    ("url" A..=) <$> (pNetworkSetCookieUrl p),
+    ("domain" A..=) <$> (pNetworkSetCookieDomain p),
+    ("path" A..=) <$> (pNetworkSetCookiePath p),
+    ("secure" A..=) <$> (pNetworkSetCookieSecure p),
+    ("httpOnly" A..=) <$> (pNetworkSetCookieHttpOnly p),
+    ("sameSite" A..=) <$> (pNetworkSetCookieSameSite p),
+    ("expires" A..=) <$> (pNetworkSetCookieExpires p),
+    ("priority" A..=) <$> (pNetworkSetCookiePriority p),
+    ("sameParty" A..=) <$> (pNetworkSetCookieSameParty p),
+    ("sourceScheme" A..=) <$> (pNetworkSetCookieSourceScheme p),
+    ("sourcePort" A..=) <$> (pNetworkSetCookieSourcePort p),
+    ("partitionKey" A..=) <$> (pNetworkSetCookiePartitionKey p)
+    ]
+instance Command PNetworkSetCookie where
+  type CommandResponse PNetworkSetCookie = ()
+  commandName _ = "Network.setCookie"
+  fromJSON = const . A.Success . const ()
+
+-- | Sets given cookies.
+
+-- | Parameters of the 'Network.setCookies' command.
+data PNetworkSetCookies = PNetworkSetCookies
+  {
+    -- | Cookies to be set.
+    pNetworkSetCookiesCookies :: [NetworkCookieParam]
+  }
+  deriving (Eq, Show)
+pNetworkSetCookies
+  {-
+  -- | Cookies to be set.
+  -}
+  :: [NetworkCookieParam]
+  -> PNetworkSetCookies
+pNetworkSetCookies
+  arg_pNetworkSetCookiesCookies
+  = PNetworkSetCookies
+    arg_pNetworkSetCookiesCookies
+instance ToJSON PNetworkSetCookies where
+  toJSON p = A.object $ catMaybes [
+    ("cookies" A..=) <$> Just (pNetworkSetCookiesCookies p)
+    ]
+instance Command PNetworkSetCookies where
+  type CommandResponse PNetworkSetCookies = ()
+  commandName _ = "Network.setCookies"
+  fromJSON = const . A.Success . const ()
+
+-- | Specifies whether to always send extra HTTP headers with the requests from this page.
+
+-- | Parameters of the 'Network.setExtraHTTPHeaders' command.
+data PNetworkSetExtraHTTPHeaders = PNetworkSetExtraHTTPHeaders
+  {
+    -- | Map with extra HTTP headers.
+    pNetworkSetExtraHTTPHeadersHeaders :: NetworkHeaders
+  }
+  deriving (Eq, Show)
+pNetworkSetExtraHTTPHeaders
+  {-
+  -- | Map with extra HTTP headers.
+  -}
+  :: NetworkHeaders
+  -> PNetworkSetExtraHTTPHeaders
+pNetworkSetExtraHTTPHeaders
+  arg_pNetworkSetExtraHTTPHeadersHeaders
+  = PNetworkSetExtraHTTPHeaders
+    arg_pNetworkSetExtraHTTPHeadersHeaders
+instance ToJSON PNetworkSetExtraHTTPHeaders where
+  toJSON p = A.object $ catMaybes [
+    ("headers" A..=) <$> Just (pNetworkSetExtraHTTPHeadersHeaders p)
+    ]
+instance Command PNetworkSetExtraHTTPHeaders where
+  type CommandResponse PNetworkSetExtraHTTPHeaders = ()
+  commandName _ = "Network.setExtraHTTPHeaders"
+  fromJSON = const . A.Success . const ()
+
+-- | Specifies whether to attach a page script stack id in requests
+
+-- | Parameters of the 'Network.setAttachDebugStack' command.
+data PNetworkSetAttachDebugStack = PNetworkSetAttachDebugStack
+  {
+    -- | Whether to attach a page script stack for debugging purpose.
+    pNetworkSetAttachDebugStackEnabled :: Bool
+  }
+  deriving (Eq, Show)
+pNetworkSetAttachDebugStack
+  {-
+  -- | Whether to attach a page script stack for debugging purpose.
+  -}
+  :: Bool
+  -> PNetworkSetAttachDebugStack
+pNetworkSetAttachDebugStack
+  arg_pNetworkSetAttachDebugStackEnabled
+  = PNetworkSetAttachDebugStack
+    arg_pNetworkSetAttachDebugStackEnabled
+instance ToJSON PNetworkSetAttachDebugStack where
+  toJSON p = A.object $ catMaybes [
+    ("enabled" A..=) <$> Just (pNetworkSetAttachDebugStackEnabled p)
+    ]
+instance Command PNetworkSetAttachDebugStack where
+  type CommandResponse PNetworkSetAttachDebugStack = ()
+  commandName _ = "Network.setAttachDebugStack"
+  fromJSON = const . A.Success . const ()
+
+-- | Allows overriding user agent with the given string.
+
+-- | Parameters of the 'Network.setUserAgentOverride' command.
+data PNetworkSetUserAgentOverride = PNetworkSetUserAgentOverride
+  {
+    -- | User agent to use.
+    pNetworkSetUserAgentOverrideUserAgent :: T.Text,
+    -- | Browser langugage to emulate.
+    pNetworkSetUserAgentOverrideAcceptLanguage :: Maybe T.Text,
+    -- | The platform navigator.platform should return.
+    pNetworkSetUserAgentOverridePlatform :: Maybe T.Text,
+    -- | To be sent in Sec-CH-UA-* headers and returned in navigator.userAgentData
+    pNetworkSetUserAgentOverrideUserAgentMetadata :: Maybe EmulationUserAgentMetadata
+  }
+  deriving (Eq, Show)
+pNetworkSetUserAgentOverride
+  {-
+  -- | User agent to use.
+  -}
+  :: T.Text
+  -> PNetworkSetUserAgentOverride
+pNetworkSetUserAgentOverride
+  arg_pNetworkSetUserAgentOverrideUserAgent
+  = PNetworkSetUserAgentOverride
+    arg_pNetworkSetUserAgentOverrideUserAgent
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PNetworkSetUserAgentOverride where
+  toJSON p = A.object $ catMaybes [
+    ("userAgent" A..=) <$> Just (pNetworkSetUserAgentOverrideUserAgent p),
+    ("acceptLanguage" A..=) <$> (pNetworkSetUserAgentOverrideAcceptLanguage p),
+    ("platform" A..=) <$> (pNetworkSetUserAgentOverridePlatform p),
+    ("userAgentMetadata" A..=) <$> (pNetworkSetUserAgentOverrideUserAgentMetadata p)
+    ]
+instance Command PNetworkSetUserAgentOverride where
+  type CommandResponse PNetworkSetUserAgentOverride = ()
+  commandName _ = "Network.setUserAgentOverride"
+  fromJSON = const . A.Success . const ()
+
+-- | Returns information about the COEP/COOP isolation status.
+
+-- | Parameters of the 'Network.getSecurityIsolationStatus' command.
+data PNetworkGetSecurityIsolationStatus = PNetworkGetSecurityIsolationStatus
+  {
+    -- | If no frameId is provided, the status of the target is provided.
+    pNetworkGetSecurityIsolationStatusFrameId :: Maybe PageFrameId
+  }
+  deriving (Eq, Show)
+pNetworkGetSecurityIsolationStatus
+  :: PNetworkGetSecurityIsolationStatus
+pNetworkGetSecurityIsolationStatus
+  = PNetworkGetSecurityIsolationStatus
+    Nothing
+instance ToJSON PNetworkGetSecurityIsolationStatus where
+  toJSON p = A.object $ catMaybes [
+    ("frameId" A..=) <$> (pNetworkGetSecurityIsolationStatusFrameId p)
+    ]
+data NetworkGetSecurityIsolationStatus = NetworkGetSecurityIsolationStatus
+  {
+    networkGetSecurityIsolationStatusStatus :: NetworkSecurityIsolationStatus
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkGetSecurityIsolationStatus where
+  parseJSON = A.withObject "NetworkGetSecurityIsolationStatus" $ \o -> NetworkGetSecurityIsolationStatus
+    <$> o A..: "status"
+instance Command PNetworkGetSecurityIsolationStatus where
+  type CommandResponse PNetworkGetSecurityIsolationStatus = NetworkGetSecurityIsolationStatus
+  commandName _ = "Network.getSecurityIsolationStatus"
+
+-- | Enables tracking for the Reporting API, events generated by the Reporting API will now be delivered to the client.
+--   Enabling triggers 'reportingApiReportAdded' for all existing reports.
+
+-- | Parameters of the 'Network.enableReportingApi' command.
+data PNetworkEnableReportingApi = PNetworkEnableReportingApi
+  {
+    -- | Whether to enable or disable events for the Reporting API
+    pNetworkEnableReportingApiEnable :: Bool
+  }
+  deriving (Eq, Show)
+pNetworkEnableReportingApi
+  {-
+  -- | Whether to enable or disable events for the Reporting API
+  -}
+  :: Bool
+  -> PNetworkEnableReportingApi
+pNetworkEnableReportingApi
+  arg_pNetworkEnableReportingApiEnable
+  = PNetworkEnableReportingApi
+    arg_pNetworkEnableReportingApiEnable
+instance ToJSON PNetworkEnableReportingApi where
+  toJSON p = A.object $ catMaybes [
+    ("enable" A..=) <$> Just (pNetworkEnableReportingApiEnable p)
+    ]
+instance Command PNetworkEnableReportingApi where
+  type CommandResponse PNetworkEnableReportingApi = ()
+  commandName _ = "Network.enableReportingApi"
+  fromJSON = const . A.Success . const ()
+
+-- | Fetches the resource and returns the content.
+
+-- | Parameters of the 'Network.loadNetworkResource' command.
+data PNetworkLoadNetworkResource = PNetworkLoadNetworkResource
+  {
+    -- | Frame id to get the resource for. Mandatory for frame targets, and
+    --   should be omitted for worker targets.
+    pNetworkLoadNetworkResourceFrameId :: Maybe PageFrameId,
+    -- | URL of the resource to get content for.
+    pNetworkLoadNetworkResourceUrl :: T.Text,
+    -- | Options for the request.
+    pNetworkLoadNetworkResourceOptions :: NetworkLoadNetworkResourceOptions
+  }
+  deriving (Eq, Show)
+pNetworkLoadNetworkResource
+  {-
+  -- | URL of the resource to get content for.
+  -}
+  :: T.Text
+  {-
+  -- | Options for the request.
+  -}
+  -> NetworkLoadNetworkResourceOptions
+  -> PNetworkLoadNetworkResource
+pNetworkLoadNetworkResource
+  arg_pNetworkLoadNetworkResourceUrl
+  arg_pNetworkLoadNetworkResourceOptions
+  = PNetworkLoadNetworkResource
+    Nothing
+    arg_pNetworkLoadNetworkResourceUrl
+    arg_pNetworkLoadNetworkResourceOptions
+instance ToJSON PNetworkLoadNetworkResource where
+  toJSON p = A.object $ catMaybes [
+    ("frameId" A..=) <$> (pNetworkLoadNetworkResourceFrameId p),
+    ("url" A..=) <$> Just (pNetworkLoadNetworkResourceUrl p),
+    ("options" A..=) <$> Just (pNetworkLoadNetworkResourceOptions p)
+    ]
+data NetworkLoadNetworkResource = NetworkLoadNetworkResource
+  {
+    networkLoadNetworkResourceResource :: NetworkLoadNetworkResourcePageResult
+  }
+  deriving (Eq, Show)
+instance FromJSON NetworkLoadNetworkResource where
+  parseJSON = A.withObject "NetworkLoadNetworkResource" $ \o -> NetworkLoadNetworkResource
+    <$> o A..: "resource"
+instance Command PNetworkLoadNetworkResource where
+  type CommandResponse PNetworkLoadNetworkResource = NetworkLoadNetworkResource
+  commandName _ = "Network.loadNetworkResource"
+
+-- | Type 'Page.FrameId'.
+--   Unique frame identifier.
+type PageFrameId = T.Text
+
+-- | Type 'Page.AdFrameType'.
+--   Indicates whether a frame has been identified as an ad.
+data PageAdFrameType = PageAdFrameTypeNone | PageAdFrameTypeChild | PageAdFrameTypeRoot
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PageAdFrameType where
+  parseJSON = A.withText "PageAdFrameType" $ \v -> case v of
+    "none" -> pure PageAdFrameTypeNone
+    "child" -> pure PageAdFrameTypeChild
+    "root" -> pure PageAdFrameTypeRoot
+    "_" -> fail "failed to parse PageAdFrameType"
+instance ToJSON PageAdFrameType where
+  toJSON v = A.String $ case v of
+    PageAdFrameTypeNone -> "none"
+    PageAdFrameTypeChild -> "child"
+    PageAdFrameTypeRoot -> "root"
+
+-- | Type 'Page.AdFrameExplanation'.
+data PageAdFrameExplanation = PageAdFrameExplanationParentIsAd | PageAdFrameExplanationCreatedByAdScript | PageAdFrameExplanationMatchedBlockingRule
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PageAdFrameExplanation where
+  parseJSON = A.withText "PageAdFrameExplanation" $ \v -> case v of
+    "ParentIsAd" -> pure PageAdFrameExplanationParentIsAd
+    "CreatedByAdScript" -> pure PageAdFrameExplanationCreatedByAdScript
+    "MatchedBlockingRule" -> pure PageAdFrameExplanationMatchedBlockingRule
+    "_" -> fail "failed to parse PageAdFrameExplanation"
+instance ToJSON PageAdFrameExplanation where
+  toJSON v = A.String $ case v of
+    PageAdFrameExplanationParentIsAd -> "ParentIsAd"
+    PageAdFrameExplanationCreatedByAdScript -> "CreatedByAdScript"
+    PageAdFrameExplanationMatchedBlockingRule -> "MatchedBlockingRule"
+
+-- | Type 'Page.AdFrameStatus'.
+--   Indicates whether a frame has been identified as an ad and why.
+data PageAdFrameStatus = PageAdFrameStatus
+  {
+    pageAdFrameStatusAdFrameType :: PageAdFrameType,
+    pageAdFrameStatusExplanations :: Maybe [PageAdFrameExplanation]
+  }
+  deriving (Eq, Show)
+instance FromJSON PageAdFrameStatus where
+  parseJSON = A.withObject "PageAdFrameStatus" $ \o -> PageAdFrameStatus
+    <$> o A..: "adFrameType"
+    <*> o A..:? "explanations"
+instance ToJSON PageAdFrameStatus where
+  toJSON p = A.object $ catMaybes [
+    ("adFrameType" A..=) <$> Just (pageAdFrameStatusAdFrameType p),
+    ("explanations" A..=) <$> (pageAdFrameStatusExplanations p)
+    ]
+
+-- | Type 'Page.AdScriptId'.
+--   Identifies the bottom-most script which caused the frame to be labelled
+--   as an ad.
+data PageAdScriptId = PageAdScriptId
+  {
+    -- | Script Id of the bottom-most script which caused the frame to be labelled
+    --   as an ad.
+    pageAdScriptIdScriptId :: Runtime.RuntimeScriptId,
+    -- | Id of adScriptId's debugger.
+    pageAdScriptIdDebuggerId :: Runtime.RuntimeUniqueDebuggerId
+  }
+  deriving (Eq, Show)
+instance FromJSON PageAdScriptId where
+  parseJSON = A.withObject "PageAdScriptId" $ \o -> PageAdScriptId
+    <$> o A..: "scriptId"
+    <*> o A..: "debuggerId"
+instance ToJSON PageAdScriptId where
+  toJSON p = A.object $ catMaybes [
+    ("scriptId" A..=) <$> Just (pageAdScriptIdScriptId p),
+    ("debuggerId" A..=) <$> Just (pageAdScriptIdDebuggerId p)
+    ]
+
+-- | Type 'Page.SecureContextType'.
+--   Indicates whether the frame is a secure context and why it is the case.
+data PageSecureContextType = PageSecureContextTypeSecure | PageSecureContextTypeSecureLocalhost | PageSecureContextTypeInsecureScheme | PageSecureContextTypeInsecureAncestor
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PageSecureContextType where
+  parseJSON = A.withText "PageSecureContextType" $ \v -> case v of
+    "Secure" -> pure PageSecureContextTypeSecure
+    "SecureLocalhost" -> pure PageSecureContextTypeSecureLocalhost
+    "InsecureScheme" -> pure PageSecureContextTypeInsecureScheme
+    "InsecureAncestor" -> pure PageSecureContextTypeInsecureAncestor
+    "_" -> fail "failed to parse PageSecureContextType"
+instance ToJSON PageSecureContextType where
+  toJSON v = A.String $ case v of
+    PageSecureContextTypeSecure -> "Secure"
+    PageSecureContextTypeSecureLocalhost -> "SecureLocalhost"
+    PageSecureContextTypeInsecureScheme -> "InsecureScheme"
+    PageSecureContextTypeInsecureAncestor -> "InsecureAncestor"
+
+-- | Type 'Page.CrossOriginIsolatedContextType'.
+--   Indicates whether the frame is cross-origin isolated and why it is the case.
+data PageCrossOriginIsolatedContextType = PageCrossOriginIsolatedContextTypeIsolated | PageCrossOriginIsolatedContextTypeNotIsolated | PageCrossOriginIsolatedContextTypeNotIsolatedFeatureDisabled
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PageCrossOriginIsolatedContextType where
+  parseJSON = A.withText "PageCrossOriginIsolatedContextType" $ \v -> case v of
+    "Isolated" -> pure PageCrossOriginIsolatedContextTypeIsolated
+    "NotIsolated" -> pure PageCrossOriginIsolatedContextTypeNotIsolated
+    "NotIsolatedFeatureDisabled" -> pure PageCrossOriginIsolatedContextTypeNotIsolatedFeatureDisabled
+    "_" -> fail "failed to parse PageCrossOriginIsolatedContextType"
+instance ToJSON PageCrossOriginIsolatedContextType where
+  toJSON v = A.String $ case v of
+    PageCrossOriginIsolatedContextTypeIsolated -> "Isolated"
+    PageCrossOriginIsolatedContextTypeNotIsolated -> "NotIsolated"
+    PageCrossOriginIsolatedContextTypeNotIsolatedFeatureDisabled -> "NotIsolatedFeatureDisabled"
+
+-- | Type 'Page.GatedAPIFeatures'.
+data PageGatedAPIFeatures = PageGatedAPIFeaturesSharedArrayBuffers | PageGatedAPIFeaturesSharedArrayBuffersTransferAllowed | PageGatedAPIFeaturesPerformanceMeasureMemory | PageGatedAPIFeaturesPerformanceProfile
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PageGatedAPIFeatures where
+  parseJSON = A.withText "PageGatedAPIFeatures" $ \v -> case v of
+    "SharedArrayBuffers" -> pure PageGatedAPIFeaturesSharedArrayBuffers
+    "SharedArrayBuffersTransferAllowed" -> pure PageGatedAPIFeaturesSharedArrayBuffersTransferAllowed
+    "PerformanceMeasureMemory" -> pure PageGatedAPIFeaturesPerformanceMeasureMemory
+    "PerformanceProfile" -> pure PageGatedAPIFeaturesPerformanceProfile
+    "_" -> fail "failed to parse PageGatedAPIFeatures"
+instance ToJSON PageGatedAPIFeatures where
+  toJSON v = A.String $ case v of
+    PageGatedAPIFeaturesSharedArrayBuffers -> "SharedArrayBuffers"
+    PageGatedAPIFeaturesSharedArrayBuffersTransferAllowed -> "SharedArrayBuffersTransferAllowed"
+    PageGatedAPIFeaturesPerformanceMeasureMemory -> "PerformanceMeasureMemory"
+    PageGatedAPIFeaturesPerformanceProfile -> "PerformanceProfile"
+
+-- | Type 'Page.PermissionsPolicyFeature'.
+--   All Permissions Policy features. This enum should match the one defined
+--   in third_party/blink/renderer/core/permissions_policy/permissions_policy_features.json5.
+data PagePermissionsPolicyFeature = PagePermissionsPolicyFeatureAccelerometer | PagePermissionsPolicyFeatureAmbientLightSensor | PagePermissionsPolicyFeatureAttributionReporting | PagePermissionsPolicyFeatureAutoplay | PagePermissionsPolicyFeatureBluetooth | PagePermissionsPolicyFeatureBrowsingTopics | PagePermissionsPolicyFeatureCamera | PagePermissionsPolicyFeatureChDpr | PagePermissionsPolicyFeatureChDeviceMemory | PagePermissionsPolicyFeatureChDownlink | PagePermissionsPolicyFeatureChEct | PagePermissionsPolicyFeatureChPrefersColorScheme | PagePermissionsPolicyFeatureChPrefersReducedMotion | PagePermissionsPolicyFeatureChRtt | PagePermissionsPolicyFeatureChSaveData | PagePermissionsPolicyFeatureChUa | PagePermissionsPolicyFeatureChUaArch | PagePermissionsPolicyFeatureChUaBitness | PagePermissionsPolicyFeatureChUaPlatform | PagePermissionsPolicyFeatureChUaModel | PagePermissionsPolicyFeatureChUaMobile | PagePermissionsPolicyFeatureChUaFull | PagePermissionsPolicyFeatureChUaFullVersion | PagePermissionsPolicyFeatureChUaFullVersionList | PagePermissionsPolicyFeatureChUaPlatformVersion | PagePermissionsPolicyFeatureChUaReduced | PagePermissionsPolicyFeatureChUaWow64 | PagePermissionsPolicyFeatureChViewportHeight | PagePermissionsPolicyFeatureChViewportWidth | PagePermissionsPolicyFeatureChWidth | PagePermissionsPolicyFeatureClipboardRead | PagePermissionsPolicyFeatureClipboardWrite | PagePermissionsPolicyFeatureCrossOriginIsolated | PagePermissionsPolicyFeatureDirectSockets | PagePermissionsPolicyFeatureDisplayCapture | PagePermissionsPolicyFeatureDocumentDomain | PagePermissionsPolicyFeatureEncryptedMedia | PagePermissionsPolicyFeatureExecutionWhileOutOfViewport | PagePermissionsPolicyFeatureExecutionWhileNotRendered | PagePermissionsPolicyFeatureFocusWithoutUserActivation | PagePermissionsPolicyFeatureFullscreen | PagePermissionsPolicyFeatureFrobulate | PagePermissionsPolicyFeatureGamepad | PagePermissionsPolicyFeatureGeolocation | PagePermissionsPolicyFeatureGyroscope | PagePermissionsPolicyFeatureHid | PagePermissionsPolicyFeatureIdentityCredentialsGet | PagePermissionsPolicyFeatureIdleDetection | PagePermissionsPolicyFeatureInterestCohort | PagePermissionsPolicyFeatureJoinAdInterestGroup | PagePermissionsPolicyFeatureKeyboardMap | PagePermissionsPolicyFeatureLocalFonts | PagePermissionsPolicyFeatureMagnetometer | PagePermissionsPolicyFeatureMicrophone | PagePermissionsPolicyFeatureMidi | PagePermissionsPolicyFeatureOtpCredentials | PagePermissionsPolicyFeaturePayment | PagePermissionsPolicyFeaturePictureInPicture | PagePermissionsPolicyFeaturePublickeyCredentialsGet | PagePermissionsPolicyFeatureRunAdAuction | PagePermissionsPolicyFeatureScreenWakeLock | PagePermissionsPolicyFeatureSerial | PagePermissionsPolicyFeatureSharedAutofill | PagePermissionsPolicyFeatureSharedStorage | PagePermissionsPolicyFeatureStorageAccess | PagePermissionsPolicyFeatureSyncXhr | PagePermissionsPolicyFeatureTrustTokenRedemption | PagePermissionsPolicyFeatureUnload | PagePermissionsPolicyFeatureUsb | PagePermissionsPolicyFeatureVerticalScroll | PagePermissionsPolicyFeatureWebShare | PagePermissionsPolicyFeatureWindowPlacement | PagePermissionsPolicyFeatureXrSpatialTracking
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PagePermissionsPolicyFeature where
+  parseJSON = A.withText "PagePermissionsPolicyFeature" $ \v -> case v of
+    "accelerometer" -> pure PagePermissionsPolicyFeatureAccelerometer
+    "ambient-light-sensor" -> pure PagePermissionsPolicyFeatureAmbientLightSensor
+    "attribution-reporting" -> pure PagePermissionsPolicyFeatureAttributionReporting
+    "autoplay" -> pure PagePermissionsPolicyFeatureAutoplay
+    "bluetooth" -> pure PagePermissionsPolicyFeatureBluetooth
+    "browsing-topics" -> pure PagePermissionsPolicyFeatureBrowsingTopics
+    "camera" -> pure PagePermissionsPolicyFeatureCamera
+    "ch-dpr" -> pure PagePermissionsPolicyFeatureChDpr
+    "ch-device-memory" -> pure PagePermissionsPolicyFeatureChDeviceMemory
+    "ch-downlink" -> pure PagePermissionsPolicyFeatureChDownlink
+    "ch-ect" -> pure PagePermissionsPolicyFeatureChEct
+    "ch-prefers-color-scheme" -> pure PagePermissionsPolicyFeatureChPrefersColorScheme
+    "ch-prefers-reduced-motion" -> pure PagePermissionsPolicyFeatureChPrefersReducedMotion
+    "ch-rtt" -> pure PagePermissionsPolicyFeatureChRtt
+    "ch-save-data" -> pure PagePermissionsPolicyFeatureChSaveData
+    "ch-ua" -> pure PagePermissionsPolicyFeatureChUa
+    "ch-ua-arch" -> pure PagePermissionsPolicyFeatureChUaArch
+    "ch-ua-bitness" -> pure PagePermissionsPolicyFeatureChUaBitness
+    "ch-ua-platform" -> pure PagePermissionsPolicyFeatureChUaPlatform
+    "ch-ua-model" -> pure PagePermissionsPolicyFeatureChUaModel
+    "ch-ua-mobile" -> pure PagePermissionsPolicyFeatureChUaMobile
+    "ch-ua-full" -> pure PagePermissionsPolicyFeatureChUaFull
+    "ch-ua-full-version" -> pure PagePermissionsPolicyFeatureChUaFullVersion
+    "ch-ua-full-version-list" -> pure PagePermissionsPolicyFeatureChUaFullVersionList
+    "ch-ua-platform-version" -> pure PagePermissionsPolicyFeatureChUaPlatformVersion
+    "ch-ua-reduced" -> pure PagePermissionsPolicyFeatureChUaReduced
+    "ch-ua-wow64" -> pure PagePermissionsPolicyFeatureChUaWow64
+    "ch-viewport-height" -> pure PagePermissionsPolicyFeatureChViewportHeight
+    "ch-viewport-width" -> pure PagePermissionsPolicyFeatureChViewportWidth
+    "ch-width" -> pure PagePermissionsPolicyFeatureChWidth
+    "clipboard-read" -> pure PagePermissionsPolicyFeatureClipboardRead
+    "clipboard-write" -> pure PagePermissionsPolicyFeatureClipboardWrite
+    "cross-origin-isolated" -> pure PagePermissionsPolicyFeatureCrossOriginIsolated
+    "direct-sockets" -> pure PagePermissionsPolicyFeatureDirectSockets
+    "display-capture" -> pure PagePermissionsPolicyFeatureDisplayCapture
+    "document-domain" -> pure PagePermissionsPolicyFeatureDocumentDomain
+    "encrypted-media" -> pure PagePermissionsPolicyFeatureEncryptedMedia
+    "execution-while-out-of-viewport" -> pure PagePermissionsPolicyFeatureExecutionWhileOutOfViewport
+    "execution-while-not-rendered" -> pure PagePermissionsPolicyFeatureExecutionWhileNotRendered
+    "focus-without-user-activation" -> pure PagePermissionsPolicyFeatureFocusWithoutUserActivation
+    "fullscreen" -> pure PagePermissionsPolicyFeatureFullscreen
+    "frobulate" -> pure PagePermissionsPolicyFeatureFrobulate
+    "gamepad" -> pure PagePermissionsPolicyFeatureGamepad
+    "geolocation" -> pure PagePermissionsPolicyFeatureGeolocation
+    "gyroscope" -> pure PagePermissionsPolicyFeatureGyroscope
+    "hid" -> pure PagePermissionsPolicyFeatureHid
+    "identity-credentials-get" -> pure PagePermissionsPolicyFeatureIdentityCredentialsGet
+    "idle-detection" -> pure PagePermissionsPolicyFeatureIdleDetection
+    "interest-cohort" -> pure PagePermissionsPolicyFeatureInterestCohort
+    "join-ad-interest-group" -> pure PagePermissionsPolicyFeatureJoinAdInterestGroup
+    "keyboard-map" -> pure PagePermissionsPolicyFeatureKeyboardMap
+    "local-fonts" -> pure PagePermissionsPolicyFeatureLocalFonts
+    "magnetometer" -> pure PagePermissionsPolicyFeatureMagnetometer
+    "microphone" -> pure PagePermissionsPolicyFeatureMicrophone
+    "midi" -> pure PagePermissionsPolicyFeatureMidi
+    "otp-credentials" -> pure PagePermissionsPolicyFeatureOtpCredentials
+    "payment" -> pure PagePermissionsPolicyFeaturePayment
+    "picture-in-picture" -> pure PagePermissionsPolicyFeaturePictureInPicture
+    "publickey-credentials-get" -> pure PagePermissionsPolicyFeaturePublickeyCredentialsGet
+    "run-ad-auction" -> pure PagePermissionsPolicyFeatureRunAdAuction
+    "screen-wake-lock" -> pure PagePermissionsPolicyFeatureScreenWakeLock
+    "serial" -> pure PagePermissionsPolicyFeatureSerial
+    "shared-autofill" -> pure PagePermissionsPolicyFeatureSharedAutofill
+    "shared-storage" -> pure PagePermissionsPolicyFeatureSharedStorage
+    "storage-access" -> pure PagePermissionsPolicyFeatureStorageAccess
+    "sync-xhr" -> pure PagePermissionsPolicyFeatureSyncXhr
+    "trust-token-redemption" -> pure PagePermissionsPolicyFeatureTrustTokenRedemption
+    "unload" -> pure PagePermissionsPolicyFeatureUnload
+    "usb" -> pure PagePermissionsPolicyFeatureUsb
+    "vertical-scroll" -> pure PagePermissionsPolicyFeatureVerticalScroll
+    "web-share" -> pure PagePermissionsPolicyFeatureWebShare
+    "window-placement" -> pure PagePermissionsPolicyFeatureWindowPlacement
+    "xr-spatial-tracking" -> pure PagePermissionsPolicyFeatureXrSpatialTracking
+    "_" -> fail "failed to parse PagePermissionsPolicyFeature"
+instance ToJSON PagePermissionsPolicyFeature where
+  toJSON v = A.String $ case v of
+    PagePermissionsPolicyFeatureAccelerometer -> "accelerometer"
+    PagePermissionsPolicyFeatureAmbientLightSensor -> "ambient-light-sensor"
+    PagePermissionsPolicyFeatureAttributionReporting -> "attribution-reporting"
+    PagePermissionsPolicyFeatureAutoplay -> "autoplay"
+    PagePermissionsPolicyFeatureBluetooth -> "bluetooth"
+    PagePermissionsPolicyFeatureBrowsingTopics -> "browsing-topics"
+    PagePermissionsPolicyFeatureCamera -> "camera"
+    PagePermissionsPolicyFeatureChDpr -> "ch-dpr"
+    PagePermissionsPolicyFeatureChDeviceMemory -> "ch-device-memory"
+    PagePermissionsPolicyFeatureChDownlink -> "ch-downlink"
+    PagePermissionsPolicyFeatureChEct -> "ch-ect"
+    PagePermissionsPolicyFeatureChPrefersColorScheme -> "ch-prefers-color-scheme"
+    PagePermissionsPolicyFeatureChPrefersReducedMotion -> "ch-prefers-reduced-motion"
+    PagePermissionsPolicyFeatureChRtt -> "ch-rtt"
+    PagePermissionsPolicyFeatureChSaveData -> "ch-save-data"
+    PagePermissionsPolicyFeatureChUa -> "ch-ua"
+    PagePermissionsPolicyFeatureChUaArch -> "ch-ua-arch"
+    PagePermissionsPolicyFeatureChUaBitness -> "ch-ua-bitness"
+    PagePermissionsPolicyFeatureChUaPlatform -> "ch-ua-platform"
+    PagePermissionsPolicyFeatureChUaModel -> "ch-ua-model"
+    PagePermissionsPolicyFeatureChUaMobile -> "ch-ua-mobile"
+    PagePermissionsPolicyFeatureChUaFull -> "ch-ua-full"
+    PagePermissionsPolicyFeatureChUaFullVersion -> "ch-ua-full-version"
+    PagePermissionsPolicyFeatureChUaFullVersionList -> "ch-ua-full-version-list"
+    PagePermissionsPolicyFeatureChUaPlatformVersion -> "ch-ua-platform-version"
+    PagePermissionsPolicyFeatureChUaReduced -> "ch-ua-reduced"
+    PagePermissionsPolicyFeatureChUaWow64 -> "ch-ua-wow64"
+    PagePermissionsPolicyFeatureChViewportHeight -> "ch-viewport-height"
+    PagePermissionsPolicyFeatureChViewportWidth -> "ch-viewport-width"
+    PagePermissionsPolicyFeatureChWidth -> "ch-width"
+    PagePermissionsPolicyFeatureClipboardRead -> "clipboard-read"
+    PagePermissionsPolicyFeatureClipboardWrite -> "clipboard-write"
+    PagePermissionsPolicyFeatureCrossOriginIsolated -> "cross-origin-isolated"
+    PagePermissionsPolicyFeatureDirectSockets -> "direct-sockets"
+    PagePermissionsPolicyFeatureDisplayCapture -> "display-capture"
+    PagePermissionsPolicyFeatureDocumentDomain -> "document-domain"
+    PagePermissionsPolicyFeatureEncryptedMedia -> "encrypted-media"
+    PagePermissionsPolicyFeatureExecutionWhileOutOfViewport -> "execution-while-out-of-viewport"
+    PagePermissionsPolicyFeatureExecutionWhileNotRendered -> "execution-while-not-rendered"
+    PagePermissionsPolicyFeatureFocusWithoutUserActivation -> "focus-without-user-activation"
+    PagePermissionsPolicyFeatureFullscreen -> "fullscreen"
+    PagePermissionsPolicyFeatureFrobulate -> "frobulate"
+    PagePermissionsPolicyFeatureGamepad -> "gamepad"
+    PagePermissionsPolicyFeatureGeolocation -> "geolocation"
+    PagePermissionsPolicyFeatureGyroscope -> "gyroscope"
+    PagePermissionsPolicyFeatureHid -> "hid"
+    PagePermissionsPolicyFeatureIdentityCredentialsGet -> "identity-credentials-get"
+    PagePermissionsPolicyFeatureIdleDetection -> "idle-detection"
+    PagePermissionsPolicyFeatureInterestCohort -> "interest-cohort"
+    PagePermissionsPolicyFeatureJoinAdInterestGroup -> "join-ad-interest-group"
+    PagePermissionsPolicyFeatureKeyboardMap -> "keyboard-map"
+    PagePermissionsPolicyFeatureLocalFonts -> "local-fonts"
+    PagePermissionsPolicyFeatureMagnetometer -> "magnetometer"
+    PagePermissionsPolicyFeatureMicrophone -> "microphone"
+    PagePermissionsPolicyFeatureMidi -> "midi"
+    PagePermissionsPolicyFeatureOtpCredentials -> "otp-credentials"
+    PagePermissionsPolicyFeaturePayment -> "payment"
+    PagePermissionsPolicyFeaturePictureInPicture -> "picture-in-picture"
+    PagePermissionsPolicyFeaturePublickeyCredentialsGet -> "publickey-credentials-get"
+    PagePermissionsPolicyFeatureRunAdAuction -> "run-ad-auction"
+    PagePermissionsPolicyFeatureScreenWakeLock -> "screen-wake-lock"
+    PagePermissionsPolicyFeatureSerial -> "serial"
+    PagePermissionsPolicyFeatureSharedAutofill -> "shared-autofill"
+    PagePermissionsPolicyFeatureSharedStorage -> "shared-storage"
+    PagePermissionsPolicyFeatureStorageAccess -> "storage-access"
+    PagePermissionsPolicyFeatureSyncXhr -> "sync-xhr"
+    PagePermissionsPolicyFeatureTrustTokenRedemption -> "trust-token-redemption"
+    PagePermissionsPolicyFeatureUnload -> "unload"
+    PagePermissionsPolicyFeatureUsb -> "usb"
+    PagePermissionsPolicyFeatureVerticalScroll -> "vertical-scroll"
+    PagePermissionsPolicyFeatureWebShare -> "web-share"
+    PagePermissionsPolicyFeatureWindowPlacement -> "window-placement"
+    PagePermissionsPolicyFeatureXrSpatialTracking -> "xr-spatial-tracking"
+
+-- | Type 'Page.PermissionsPolicyBlockReason'.
+--   Reason for a permissions policy feature to be disabled.
+data PagePermissionsPolicyBlockReason = PagePermissionsPolicyBlockReasonHeader | PagePermissionsPolicyBlockReasonIframeAttribute | PagePermissionsPolicyBlockReasonInFencedFrameTree | PagePermissionsPolicyBlockReasonInIsolatedApp
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PagePermissionsPolicyBlockReason where
+  parseJSON = A.withText "PagePermissionsPolicyBlockReason" $ \v -> case v of
+    "Header" -> pure PagePermissionsPolicyBlockReasonHeader
+    "IframeAttribute" -> pure PagePermissionsPolicyBlockReasonIframeAttribute
+    "InFencedFrameTree" -> pure PagePermissionsPolicyBlockReasonInFencedFrameTree
+    "InIsolatedApp" -> pure PagePermissionsPolicyBlockReasonInIsolatedApp
+    "_" -> fail "failed to parse PagePermissionsPolicyBlockReason"
+instance ToJSON PagePermissionsPolicyBlockReason where
+  toJSON v = A.String $ case v of
+    PagePermissionsPolicyBlockReasonHeader -> "Header"
+    PagePermissionsPolicyBlockReasonIframeAttribute -> "IframeAttribute"
+    PagePermissionsPolicyBlockReasonInFencedFrameTree -> "InFencedFrameTree"
+    PagePermissionsPolicyBlockReasonInIsolatedApp -> "InIsolatedApp"
+
+-- | Type 'Page.PermissionsPolicyBlockLocator'.
+data PagePermissionsPolicyBlockLocator = PagePermissionsPolicyBlockLocator
+  {
+    pagePermissionsPolicyBlockLocatorFrameId :: PageFrameId,
+    pagePermissionsPolicyBlockLocatorBlockReason :: PagePermissionsPolicyBlockReason
+  }
+  deriving (Eq, Show)
+instance FromJSON PagePermissionsPolicyBlockLocator where
+  parseJSON = A.withObject "PagePermissionsPolicyBlockLocator" $ \o -> PagePermissionsPolicyBlockLocator
+    <$> o A..: "frameId"
+    <*> o A..: "blockReason"
+instance ToJSON PagePermissionsPolicyBlockLocator where
+  toJSON p = A.object $ catMaybes [
+    ("frameId" A..=) <$> Just (pagePermissionsPolicyBlockLocatorFrameId p),
+    ("blockReason" A..=) <$> Just (pagePermissionsPolicyBlockLocatorBlockReason p)
+    ]
+
+-- | Type 'Page.PermissionsPolicyFeatureState'.
+data PagePermissionsPolicyFeatureState = PagePermissionsPolicyFeatureState
+  {
+    pagePermissionsPolicyFeatureStateFeature :: PagePermissionsPolicyFeature,
+    pagePermissionsPolicyFeatureStateAllowed :: Bool,
+    pagePermissionsPolicyFeatureStateLocator :: Maybe PagePermissionsPolicyBlockLocator
+  }
+  deriving (Eq, Show)
+instance FromJSON PagePermissionsPolicyFeatureState where
+  parseJSON = A.withObject "PagePermissionsPolicyFeatureState" $ \o -> PagePermissionsPolicyFeatureState
+    <$> o A..: "feature"
+    <*> o A..: "allowed"
+    <*> o A..:? "locator"
+instance ToJSON PagePermissionsPolicyFeatureState where
+  toJSON p = A.object $ catMaybes [
+    ("feature" A..=) <$> Just (pagePermissionsPolicyFeatureStateFeature p),
+    ("allowed" A..=) <$> Just (pagePermissionsPolicyFeatureStateAllowed p),
+    ("locator" A..=) <$> (pagePermissionsPolicyFeatureStateLocator p)
+    ]
+
+-- | Type 'Page.OriginTrialTokenStatus'.
+--   Origin Trial(https://www.chromium.org/blink/origin-trials) support.
+--   Status for an Origin Trial token.
+data PageOriginTrialTokenStatus = PageOriginTrialTokenStatusSuccess | PageOriginTrialTokenStatusNotSupported | PageOriginTrialTokenStatusInsecure | PageOriginTrialTokenStatusExpired | PageOriginTrialTokenStatusWrongOrigin | PageOriginTrialTokenStatusInvalidSignature | PageOriginTrialTokenStatusMalformed | PageOriginTrialTokenStatusWrongVersion | PageOriginTrialTokenStatusFeatureDisabled | PageOriginTrialTokenStatusTokenDisabled | PageOriginTrialTokenStatusFeatureDisabledForUser | PageOriginTrialTokenStatusUnknownTrial
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PageOriginTrialTokenStatus where
+  parseJSON = A.withText "PageOriginTrialTokenStatus" $ \v -> case v of
+    "Success" -> pure PageOriginTrialTokenStatusSuccess
+    "NotSupported" -> pure PageOriginTrialTokenStatusNotSupported
+    "Insecure" -> pure PageOriginTrialTokenStatusInsecure
+    "Expired" -> pure PageOriginTrialTokenStatusExpired
+    "WrongOrigin" -> pure PageOriginTrialTokenStatusWrongOrigin
+    "InvalidSignature" -> pure PageOriginTrialTokenStatusInvalidSignature
+    "Malformed" -> pure PageOriginTrialTokenStatusMalformed
+    "WrongVersion" -> pure PageOriginTrialTokenStatusWrongVersion
+    "FeatureDisabled" -> pure PageOriginTrialTokenStatusFeatureDisabled
+    "TokenDisabled" -> pure PageOriginTrialTokenStatusTokenDisabled
+    "FeatureDisabledForUser" -> pure PageOriginTrialTokenStatusFeatureDisabledForUser
+    "UnknownTrial" -> pure PageOriginTrialTokenStatusUnknownTrial
+    "_" -> fail "failed to parse PageOriginTrialTokenStatus"
+instance ToJSON PageOriginTrialTokenStatus where
+  toJSON v = A.String $ case v of
+    PageOriginTrialTokenStatusSuccess -> "Success"
+    PageOriginTrialTokenStatusNotSupported -> "NotSupported"
+    PageOriginTrialTokenStatusInsecure -> "Insecure"
+    PageOriginTrialTokenStatusExpired -> "Expired"
+    PageOriginTrialTokenStatusWrongOrigin -> "WrongOrigin"
+    PageOriginTrialTokenStatusInvalidSignature -> "InvalidSignature"
+    PageOriginTrialTokenStatusMalformed -> "Malformed"
+    PageOriginTrialTokenStatusWrongVersion -> "WrongVersion"
+    PageOriginTrialTokenStatusFeatureDisabled -> "FeatureDisabled"
+    PageOriginTrialTokenStatusTokenDisabled -> "TokenDisabled"
+    PageOriginTrialTokenStatusFeatureDisabledForUser -> "FeatureDisabledForUser"
+    PageOriginTrialTokenStatusUnknownTrial -> "UnknownTrial"
+
+-- | Type 'Page.OriginTrialStatus'.
+--   Status for an Origin Trial.
+data PageOriginTrialStatus = PageOriginTrialStatusEnabled | PageOriginTrialStatusValidTokenNotProvided | PageOriginTrialStatusOSNotSupported | PageOriginTrialStatusTrialNotAllowed
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PageOriginTrialStatus where
+  parseJSON = A.withText "PageOriginTrialStatus" $ \v -> case v of
+    "Enabled" -> pure PageOriginTrialStatusEnabled
+    "ValidTokenNotProvided" -> pure PageOriginTrialStatusValidTokenNotProvided
+    "OSNotSupported" -> pure PageOriginTrialStatusOSNotSupported
+    "TrialNotAllowed" -> pure PageOriginTrialStatusTrialNotAllowed
+    "_" -> fail "failed to parse PageOriginTrialStatus"
+instance ToJSON PageOriginTrialStatus where
+  toJSON v = A.String $ case v of
+    PageOriginTrialStatusEnabled -> "Enabled"
+    PageOriginTrialStatusValidTokenNotProvided -> "ValidTokenNotProvided"
+    PageOriginTrialStatusOSNotSupported -> "OSNotSupported"
+    PageOriginTrialStatusTrialNotAllowed -> "TrialNotAllowed"
+
+-- | Type 'Page.OriginTrialUsageRestriction'.
+data PageOriginTrialUsageRestriction = PageOriginTrialUsageRestrictionNone | PageOriginTrialUsageRestrictionSubset
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PageOriginTrialUsageRestriction where
+  parseJSON = A.withText "PageOriginTrialUsageRestriction" $ \v -> case v of
+    "None" -> pure PageOriginTrialUsageRestrictionNone
+    "Subset" -> pure PageOriginTrialUsageRestrictionSubset
+    "_" -> fail "failed to parse PageOriginTrialUsageRestriction"
+instance ToJSON PageOriginTrialUsageRestriction where
+  toJSON v = A.String $ case v of
+    PageOriginTrialUsageRestrictionNone -> "None"
+    PageOriginTrialUsageRestrictionSubset -> "Subset"
+
+-- | Type 'Page.OriginTrialToken'.
+data PageOriginTrialToken = PageOriginTrialToken
+  {
+    pageOriginTrialTokenOrigin :: T.Text,
+    pageOriginTrialTokenMatchSubDomains :: Bool,
+    pageOriginTrialTokenTrialName :: T.Text,
+    pageOriginTrialTokenExpiryTime :: NetworkTimeSinceEpoch,
+    pageOriginTrialTokenIsThirdParty :: Bool,
+    pageOriginTrialTokenUsageRestriction :: PageOriginTrialUsageRestriction
+  }
+  deriving (Eq, Show)
+instance FromJSON PageOriginTrialToken where
+  parseJSON = A.withObject "PageOriginTrialToken" $ \o -> PageOriginTrialToken
+    <$> o A..: "origin"
+    <*> o A..: "matchSubDomains"
+    <*> o A..: "trialName"
+    <*> o A..: "expiryTime"
+    <*> o A..: "isThirdParty"
+    <*> o A..: "usageRestriction"
+instance ToJSON PageOriginTrialToken where
+  toJSON p = A.object $ catMaybes [
+    ("origin" A..=) <$> Just (pageOriginTrialTokenOrigin p),
+    ("matchSubDomains" A..=) <$> Just (pageOriginTrialTokenMatchSubDomains p),
+    ("trialName" A..=) <$> Just (pageOriginTrialTokenTrialName p),
+    ("expiryTime" A..=) <$> Just (pageOriginTrialTokenExpiryTime p),
+    ("isThirdParty" A..=) <$> Just (pageOriginTrialTokenIsThirdParty p),
+    ("usageRestriction" A..=) <$> Just (pageOriginTrialTokenUsageRestriction p)
+    ]
+
+-- | Type 'Page.OriginTrialTokenWithStatus'.
+data PageOriginTrialTokenWithStatus = PageOriginTrialTokenWithStatus
+  {
+    pageOriginTrialTokenWithStatusRawTokenText :: T.Text,
+    -- | `parsedToken` is present only when the token is extractable and
+    --   parsable.
+    pageOriginTrialTokenWithStatusParsedToken :: Maybe PageOriginTrialToken,
+    pageOriginTrialTokenWithStatusStatus :: PageOriginTrialTokenStatus
+  }
+  deriving (Eq, Show)
+instance FromJSON PageOriginTrialTokenWithStatus where
+  parseJSON = A.withObject "PageOriginTrialTokenWithStatus" $ \o -> PageOriginTrialTokenWithStatus
+    <$> o A..: "rawTokenText"
+    <*> o A..:? "parsedToken"
+    <*> o A..: "status"
+instance ToJSON PageOriginTrialTokenWithStatus where
+  toJSON p = A.object $ catMaybes [
+    ("rawTokenText" A..=) <$> Just (pageOriginTrialTokenWithStatusRawTokenText p),
+    ("parsedToken" A..=) <$> (pageOriginTrialTokenWithStatusParsedToken p),
+    ("status" A..=) <$> Just (pageOriginTrialTokenWithStatusStatus p)
+    ]
+
+-- | Type 'Page.OriginTrial'.
+data PageOriginTrial = PageOriginTrial
+  {
+    pageOriginTrialTrialName :: T.Text,
+    pageOriginTrialStatus :: PageOriginTrialStatus,
+    pageOriginTrialTokensWithStatus :: [PageOriginTrialTokenWithStatus]
+  }
+  deriving (Eq, Show)
+instance FromJSON PageOriginTrial where
+  parseJSON = A.withObject "PageOriginTrial" $ \o -> PageOriginTrial
+    <$> o A..: "trialName"
+    <*> o A..: "status"
+    <*> o A..: "tokensWithStatus"
+instance ToJSON PageOriginTrial where
+  toJSON p = A.object $ catMaybes [
+    ("trialName" A..=) <$> Just (pageOriginTrialTrialName p),
+    ("status" A..=) <$> Just (pageOriginTrialStatus p),
+    ("tokensWithStatus" A..=) <$> Just (pageOriginTrialTokensWithStatus p)
+    ]
+
+-- | Type 'Page.Frame'.
+--   Information about the Frame on the page.
+data PageFrame = PageFrame
+  {
+    -- | Frame unique identifier.
+    pageFrameId :: PageFrameId,
+    -- | Parent frame identifier.
+    pageFrameParentId :: Maybe PageFrameId,
+    -- | Identifier of the loader associated with this frame.
+    pageFrameLoaderId :: NetworkLoaderId,
+    -- | Frame's name as specified in the tag.
+    pageFrameName :: Maybe T.Text,
+    -- | Frame document's URL without fragment.
+    pageFrameUrl :: T.Text,
+    -- | Frame document's URL fragment including the '#'.
+    pageFrameUrlFragment :: Maybe T.Text,
+    -- | Frame document's registered domain, taking the public suffixes list into account.
+    --   Extracted from the Frame's url.
+    --   Example URLs: http://www.google.com/file.html -> "google.com"
+    --                 http://a.b.co.uk/file.html      -> "b.co.uk"
+    pageFrameDomainAndRegistry :: T.Text,
+    -- | Frame document's security origin.
+    pageFrameSecurityOrigin :: T.Text,
+    -- | Frame document's mimeType as determined by the browser.
+    pageFrameMimeType :: T.Text,
+    -- | If the frame failed to load, this contains the URL that could not be loaded. Note that unlike url above, this URL may contain a fragment.
+    pageFrameUnreachableUrl :: Maybe T.Text,
+    -- | Indicates whether this frame was tagged as an ad and why.
+    pageFrameAdFrameStatus :: Maybe PageAdFrameStatus,
+    -- | Indicates whether the main document is a secure context and explains why that is the case.
+    pageFrameSecureContextType :: PageSecureContextType,
+    -- | Indicates whether this is a cross origin isolated context.
+    pageFrameCrossOriginIsolatedContextType :: PageCrossOriginIsolatedContextType,
+    -- | Indicated which gated APIs / features are available.
+    pageFrameGatedAPIFeatures :: [PageGatedAPIFeatures]
+  }
+  deriving (Eq, Show)
+instance FromJSON PageFrame where
+  parseJSON = A.withObject "PageFrame" $ \o -> PageFrame
+    <$> o A..: "id"
+    <*> o A..:? "parentId"
+    <*> o A..: "loaderId"
+    <*> o A..:? "name"
+    <*> o A..: "url"
+    <*> o A..:? "urlFragment"
+    <*> o A..: "domainAndRegistry"
+    <*> o A..: "securityOrigin"
+    <*> o A..: "mimeType"
+    <*> o A..:? "unreachableUrl"
+    <*> o A..:? "adFrameStatus"
+    <*> o A..: "secureContextType"
+    <*> o A..: "crossOriginIsolatedContextType"
+    <*> o A..: "gatedAPIFeatures"
+instance ToJSON PageFrame where
+  toJSON p = A.object $ catMaybes [
+    ("id" A..=) <$> Just (pageFrameId p),
+    ("parentId" A..=) <$> (pageFrameParentId p),
+    ("loaderId" A..=) <$> Just (pageFrameLoaderId p),
+    ("name" A..=) <$> (pageFrameName p),
+    ("url" A..=) <$> Just (pageFrameUrl p),
+    ("urlFragment" A..=) <$> (pageFrameUrlFragment p),
+    ("domainAndRegistry" A..=) <$> Just (pageFrameDomainAndRegistry p),
+    ("securityOrigin" A..=) <$> Just (pageFrameSecurityOrigin p),
+    ("mimeType" A..=) <$> Just (pageFrameMimeType p),
+    ("unreachableUrl" A..=) <$> (pageFrameUnreachableUrl p),
+    ("adFrameStatus" A..=) <$> (pageFrameAdFrameStatus p),
+    ("secureContextType" A..=) <$> Just (pageFrameSecureContextType p),
+    ("crossOriginIsolatedContextType" A..=) <$> Just (pageFrameCrossOriginIsolatedContextType p),
+    ("gatedAPIFeatures" A..=) <$> Just (pageFrameGatedAPIFeatures p)
+    ]
+
+-- | Type 'Page.FrameResource'.
+--   Information about the Resource on the page.
+data PageFrameResource = PageFrameResource
+  {
+    -- | Resource URL.
+    pageFrameResourceUrl :: T.Text,
+    -- | Type of this resource.
+    pageFrameResourceType :: NetworkResourceType,
+    -- | Resource mimeType as determined by the browser.
+    pageFrameResourceMimeType :: T.Text,
+    -- | last-modified timestamp as reported by server.
+    pageFrameResourceLastModified :: Maybe NetworkTimeSinceEpoch,
+    -- | Resource content size.
+    pageFrameResourceContentSize :: Maybe Double,
+    -- | True if the resource failed to load.
+    pageFrameResourceFailed :: Maybe Bool,
+    -- | True if the resource was canceled during loading.
+    pageFrameResourceCanceled :: Maybe Bool
+  }
+  deriving (Eq, Show)
+instance FromJSON PageFrameResource where
+  parseJSON = A.withObject "PageFrameResource" $ \o -> PageFrameResource
+    <$> o A..: "url"
+    <*> o A..: "type"
+    <*> o A..: "mimeType"
+    <*> o A..:? "lastModified"
+    <*> o A..:? "contentSize"
+    <*> o A..:? "failed"
+    <*> o A..:? "canceled"
+instance ToJSON PageFrameResource where
+  toJSON p = A.object $ catMaybes [
+    ("url" A..=) <$> Just (pageFrameResourceUrl p),
+    ("type" A..=) <$> Just (pageFrameResourceType p),
+    ("mimeType" A..=) <$> Just (pageFrameResourceMimeType p),
+    ("lastModified" A..=) <$> (pageFrameResourceLastModified p),
+    ("contentSize" A..=) <$> (pageFrameResourceContentSize p),
+    ("failed" A..=) <$> (pageFrameResourceFailed p),
+    ("canceled" A..=) <$> (pageFrameResourceCanceled p)
+    ]
+
+-- | Type 'Page.FrameResourceTree'.
+--   Information about the Frame hierarchy along with their cached resources.
+data PageFrameResourceTree = PageFrameResourceTree
+  {
+    -- | Frame information for this tree item.
+    pageFrameResourceTreeFrame :: PageFrame,
+    -- | Child frames.
+    pageFrameResourceTreeChildFrames :: Maybe [PageFrameResourceTree],
+    -- | Information about frame resources.
+    pageFrameResourceTreeResources :: [PageFrameResource]
+  }
+  deriving (Eq, Show)
+instance FromJSON PageFrameResourceTree where
+  parseJSON = A.withObject "PageFrameResourceTree" $ \o -> PageFrameResourceTree
+    <$> o A..: "frame"
+    <*> o A..:? "childFrames"
+    <*> o A..: "resources"
+instance ToJSON PageFrameResourceTree where
+  toJSON p = A.object $ catMaybes [
+    ("frame" A..=) <$> Just (pageFrameResourceTreeFrame p),
+    ("childFrames" A..=) <$> (pageFrameResourceTreeChildFrames p),
+    ("resources" A..=) <$> Just (pageFrameResourceTreeResources p)
+    ]
+
+-- | Type 'Page.FrameTree'.
+--   Information about the Frame hierarchy.
+data PageFrameTree = PageFrameTree
+  {
+    -- | Frame information for this tree item.
+    pageFrameTreeFrame :: PageFrame,
+    -- | Child frames.
+    pageFrameTreeChildFrames :: Maybe [PageFrameTree]
+  }
+  deriving (Eq, Show)
+instance FromJSON PageFrameTree where
+  parseJSON = A.withObject "PageFrameTree" $ \o -> PageFrameTree
+    <$> o A..: "frame"
+    <*> o A..:? "childFrames"
+instance ToJSON PageFrameTree where
+  toJSON p = A.object $ catMaybes [
+    ("frame" A..=) <$> Just (pageFrameTreeFrame p),
+    ("childFrames" A..=) <$> (pageFrameTreeChildFrames p)
+    ]
+
+-- | Type 'Page.ScriptIdentifier'.
+--   Unique script identifier.
+type PageScriptIdentifier = T.Text
+
+-- | Type 'Page.TransitionType'.
+--   Transition type.
+data PageTransitionType = PageTransitionTypeLink | PageTransitionTypeTyped | PageTransitionTypeAddress_bar | PageTransitionTypeAuto_bookmark | PageTransitionTypeAuto_subframe | PageTransitionTypeManual_subframe | PageTransitionTypeGenerated | PageTransitionTypeAuto_toplevel | PageTransitionTypeForm_submit | PageTransitionTypeReload | PageTransitionTypeKeyword | PageTransitionTypeKeyword_generated | PageTransitionTypeOther
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PageTransitionType where
+  parseJSON = A.withText "PageTransitionType" $ \v -> case v of
+    "link" -> pure PageTransitionTypeLink
+    "typed" -> pure PageTransitionTypeTyped
+    "address_bar" -> pure PageTransitionTypeAddress_bar
+    "auto_bookmark" -> pure PageTransitionTypeAuto_bookmark
+    "auto_subframe" -> pure PageTransitionTypeAuto_subframe
+    "manual_subframe" -> pure PageTransitionTypeManual_subframe
+    "generated" -> pure PageTransitionTypeGenerated
+    "auto_toplevel" -> pure PageTransitionTypeAuto_toplevel
+    "form_submit" -> pure PageTransitionTypeForm_submit
+    "reload" -> pure PageTransitionTypeReload
+    "keyword" -> pure PageTransitionTypeKeyword
+    "keyword_generated" -> pure PageTransitionTypeKeyword_generated
+    "other" -> pure PageTransitionTypeOther
+    "_" -> fail "failed to parse PageTransitionType"
+instance ToJSON PageTransitionType where
+  toJSON v = A.String $ case v of
+    PageTransitionTypeLink -> "link"
+    PageTransitionTypeTyped -> "typed"
+    PageTransitionTypeAddress_bar -> "address_bar"
+    PageTransitionTypeAuto_bookmark -> "auto_bookmark"
+    PageTransitionTypeAuto_subframe -> "auto_subframe"
+    PageTransitionTypeManual_subframe -> "manual_subframe"
+    PageTransitionTypeGenerated -> "generated"
+    PageTransitionTypeAuto_toplevel -> "auto_toplevel"
+    PageTransitionTypeForm_submit -> "form_submit"
+    PageTransitionTypeReload -> "reload"
+    PageTransitionTypeKeyword -> "keyword"
+    PageTransitionTypeKeyword_generated -> "keyword_generated"
+    PageTransitionTypeOther -> "other"
+
+-- | Type 'Page.NavigationEntry'.
+--   Navigation history entry.
+data PageNavigationEntry = PageNavigationEntry
+  {
+    -- | Unique id of the navigation history entry.
+    pageNavigationEntryId :: Int,
+    -- | URL of the navigation history entry.
+    pageNavigationEntryUrl :: T.Text,
+    -- | URL that the user typed in the url bar.
+    pageNavigationEntryUserTypedURL :: T.Text,
+    -- | Title of the navigation history entry.
+    pageNavigationEntryTitle :: T.Text,
+    -- | Transition type.
+    pageNavigationEntryTransitionType :: PageTransitionType
+  }
+  deriving (Eq, Show)
+instance FromJSON PageNavigationEntry where
+  parseJSON = A.withObject "PageNavigationEntry" $ \o -> PageNavigationEntry
+    <$> o A..: "id"
+    <*> o A..: "url"
+    <*> o A..: "userTypedURL"
+    <*> o A..: "title"
+    <*> o A..: "transitionType"
+instance ToJSON PageNavigationEntry where
+  toJSON p = A.object $ catMaybes [
+    ("id" A..=) <$> Just (pageNavigationEntryId p),
+    ("url" A..=) <$> Just (pageNavigationEntryUrl p),
+    ("userTypedURL" A..=) <$> Just (pageNavigationEntryUserTypedURL p),
+    ("title" A..=) <$> Just (pageNavigationEntryTitle p),
+    ("transitionType" A..=) <$> Just (pageNavigationEntryTransitionType p)
+    ]
+
+-- | Type 'Page.ScreencastFrameMetadata'.
+--   Screencast frame metadata.
+data PageScreencastFrameMetadata = PageScreencastFrameMetadata
+  {
+    -- | Top offset in DIP.
+    pageScreencastFrameMetadataOffsetTop :: Double,
+    -- | Page scale factor.
+    pageScreencastFrameMetadataPageScaleFactor :: Double,
+    -- | Device screen width in DIP.
+    pageScreencastFrameMetadataDeviceWidth :: Double,
+    -- | Device screen height in DIP.
+    pageScreencastFrameMetadataDeviceHeight :: Double,
+    -- | Position of horizontal scroll in CSS pixels.
+    pageScreencastFrameMetadataScrollOffsetX :: Double,
+    -- | Position of vertical scroll in CSS pixels.
+    pageScreencastFrameMetadataScrollOffsetY :: Double,
+    -- | Frame swap timestamp.
+    pageScreencastFrameMetadataTimestamp :: Maybe NetworkTimeSinceEpoch
+  }
+  deriving (Eq, Show)
+instance FromJSON PageScreencastFrameMetadata where
+  parseJSON = A.withObject "PageScreencastFrameMetadata" $ \o -> PageScreencastFrameMetadata
+    <$> o A..: "offsetTop"
+    <*> o A..: "pageScaleFactor"
+    <*> o A..: "deviceWidth"
+    <*> o A..: "deviceHeight"
+    <*> o A..: "scrollOffsetX"
+    <*> o A..: "scrollOffsetY"
+    <*> o A..:? "timestamp"
+instance ToJSON PageScreencastFrameMetadata where
+  toJSON p = A.object $ catMaybes [
+    ("offsetTop" A..=) <$> Just (pageScreencastFrameMetadataOffsetTop p),
+    ("pageScaleFactor" A..=) <$> Just (pageScreencastFrameMetadataPageScaleFactor p),
+    ("deviceWidth" A..=) <$> Just (pageScreencastFrameMetadataDeviceWidth p),
+    ("deviceHeight" A..=) <$> Just (pageScreencastFrameMetadataDeviceHeight p),
+    ("scrollOffsetX" A..=) <$> Just (pageScreencastFrameMetadataScrollOffsetX p),
+    ("scrollOffsetY" A..=) <$> Just (pageScreencastFrameMetadataScrollOffsetY p),
+    ("timestamp" A..=) <$> (pageScreencastFrameMetadataTimestamp p)
+    ]
+
+-- | Type 'Page.DialogType'.
+--   Javascript dialog type.
+data PageDialogType = PageDialogTypeAlert | PageDialogTypeConfirm | PageDialogTypePrompt | PageDialogTypeBeforeunload
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PageDialogType where
+  parseJSON = A.withText "PageDialogType" $ \v -> case v of
+    "alert" -> pure PageDialogTypeAlert
+    "confirm" -> pure PageDialogTypeConfirm
+    "prompt" -> pure PageDialogTypePrompt
+    "beforeunload" -> pure PageDialogTypeBeforeunload
+    "_" -> fail "failed to parse PageDialogType"
+instance ToJSON PageDialogType where
+  toJSON v = A.String $ case v of
+    PageDialogTypeAlert -> "alert"
+    PageDialogTypeConfirm -> "confirm"
+    PageDialogTypePrompt -> "prompt"
+    PageDialogTypeBeforeunload -> "beforeunload"
+
+-- | Type 'Page.AppManifestError'.
+--   Error while paring app manifest.
+data PageAppManifestError = PageAppManifestError
+  {
+    -- | Error message.
+    pageAppManifestErrorMessage :: T.Text,
+    -- | If criticial, this is a non-recoverable parse error.
+    pageAppManifestErrorCritical :: Int,
+    -- | Error line.
+    pageAppManifestErrorLine :: Int,
+    -- | Error column.
+    pageAppManifestErrorColumn :: Int
+  }
+  deriving (Eq, Show)
+instance FromJSON PageAppManifestError where
+  parseJSON = A.withObject "PageAppManifestError" $ \o -> PageAppManifestError
+    <$> o A..: "message"
+    <*> o A..: "critical"
+    <*> o A..: "line"
+    <*> o A..: "column"
+instance ToJSON PageAppManifestError where
+  toJSON p = A.object $ catMaybes [
+    ("message" A..=) <$> Just (pageAppManifestErrorMessage p),
+    ("critical" A..=) <$> Just (pageAppManifestErrorCritical p),
+    ("line" A..=) <$> Just (pageAppManifestErrorLine p),
+    ("column" A..=) <$> Just (pageAppManifestErrorColumn p)
+    ]
+
+-- | Type 'Page.AppManifestParsedProperties'.
+--   Parsed app manifest properties.
+data PageAppManifestParsedProperties = PageAppManifestParsedProperties
+  {
+    -- | Computed scope value
+    pageAppManifestParsedPropertiesScope :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON PageAppManifestParsedProperties where
+  parseJSON = A.withObject "PageAppManifestParsedProperties" $ \o -> PageAppManifestParsedProperties
+    <$> o A..: "scope"
+instance ToJSON PageAppManifestParsedProperties where
+  toJSON p = A.object $ catMaybes [
+    ("scope" A..=) <$> Just (pageAppManifestParsedPropertiesScope p)
+    ]
+
+-- | Type 'Page.LayoutViewport'.
+--   Layout viewport position and dimensions.
+data PageLayoutViewport = PageLayoutViewport
+  {
+    -- | Horizontal offset relative to the document (CSS pixels).
+    pageLayoutViewportPageX :: Int,
+    -- | Vertical offset relative to the document (CSS pixels).
+    pageLayoutViewportPageY :: Int,
+    -- | Width (CSS pixels), excludes scrollbar if present.
+    pageLayoutViewportClientWidth :: Int,
+    -- | Height (CSS pixels), excludes scrollbar if present.
+    pageLayoutViewportClientHeight :: Int
+  }
+  deriving (Eq, Show)
+instance FromJSON PageLayoutViewport where
+  parseJSON = A.withObject "PageLayoutViewport" $ \o -> PageLayoutViewport
+    <$> o A..: "pageX"
+    <*> o A..: "pageY"
+    <*> o A..: "clientWidth"
+    <*> o A..: "clientHeight"
+instance ToJSON PageLayoutViewport where
+  toJSON p = A.object $ catMaybes [
+    ("pageX" A..=) <$> Just (pageLayoutViewportPageX p),
+    ("pageY" A..=) <$> Just (pageLayoutViewportPageY p),
+    ("clientWidth" A..=) <$> Just (pageLayoutViewportClientWidth p),
+    ("clientHeight" A..=) <$> Just (pageLayoutViewportClientHeight p)
+    ]
+
+-- | Type 'Page.VisualViewport'.
+--   Visual viewport position, dimensions, and scale.
+data PageVisualViewport = PageVisualViewport
+  {
+    -- | Horizontal offset relative to the layout viewport (CSS pixels).
+    pageVisualViewportOffsetX :: Double,
+    -- | Vertical offset relative to the layout viewport (CSS pixels).
+    pageVisualViewportOffsetY :: Double,
+    -- | Horizontal offset relative to the document (CSS pixels).
+    pageVisualViewportPageX :: Double,
+    -- | Vertical offset relative to the document (CSS pixels).
+    pageVisualViewportPageY :: Double,
+    -- | Width (CSS pixels), excludes scrollbar if present.
+    pageVisualViewportClientWidth :: Double,
+    -- | Height (CSS pixels), excludes scrollbar if present.
+    pageVisualViewportClientHeight :: Double,
+    -- | Scale relative to the ideal viewport (size at width=device-width).
+    pageVisualViewportScale :: Double,
+    -- | Page zoom factor (CSS to device independent pixels ratio).
+    pageVisualViewportZoom :: Maybe Double
+  }
+  deriving (Eq, Show)
+instance FromJSON PageVisualViewport where
+  parseJSON = A.withObject "PageVisualViewport" $ \o -> PageVisualViewport
+    <$> o A..: "offsetX"
+    <*> o A..: "offsetY"
+    <*> o A..: "pageX"
+    <*> o A..: "pageY"
+    <*> o A..: "clientWidth"
+    <*> o A..: "clientHeight"
+    <*> o A..: "scale"
+    <*> o A..:? "zoom"
+instance ToJSON PageVisualViewport where
+  toJSON p = A.object $ catMaybes [
+    ("offsetX" A..=) <$> Just (pageVisualViewportOffsetX p),
+    ("offsetY" A..=) <$> Just (pageVisualViewportOffsetY p),
+    ("pageX" A..=) <$> Just (pageVisualViewportPageX p),
+    ("pageY" A..=) <$> Just (pageVisualViewportPageY p),
+    ("clientWidth" A..=) <$> Just (pageVisualViewportClientWidth p),
+    ("clientHeight" A..=) <$> Just (pageVisualViewportClientHeight p),
+    ("scale" A..=) <$> Just (pageVisualViewportScale p),
+    ("zoom" A..=) <$> (pageVisualViewportZoom p)
+    ]
+
+-- | Type 'Page.Viewport'.
+--   Viewport for capturing screenshot.
+data PageViewport = PageViewport
+  {
+    -- | X offset in device independent pixels (dip).
+    pageViewportX :: Double,
+    -- | Y offset in device independent pixels (dip).
+    pageViewportY :: Double,
+    -- | Rectangle width in device independent pixels (dip).
+    pageViewportWidth :: Double,
+    -- | Rectangle height in device independent pixels (dip).
+    pageViewportHeight :: Double,
+    -- | Page scale factor.
+    pageViewportScale :: Double
+  }
+  deriving (Eq, Show)
+instance FromJSON PageViewport where
+  parseJSON = A.withObject "PageViewport" $ \o -> PageViewport
+    <$> o A..: "x"
+    <*> o A..: "y"
+    <*> o A..: "width"
+    <*> o A..: "height"
+    <*> o A..: "scale"
+instance ToJSON PageViewport where
+  toJSON p = A.object $ catMaybes [
+    ("x" A..=) <$> Just (pageViewportX p),
+    ("y" A..=) <$> Just (pageViewportY p),
+    ("width" A..=) <$> Just (pageViewportWidth p),
+    ("height" A..=) <$> Just (pageViewportHeight p),
+    ("scale" A..=) <$> Just (pageViewportScale p)
+    ]
+
+-- | Type 'Page.FontFamilies'.
+--   Generic font families collection.
+data PageFontFamilies = PageFontFamilies
+  {
+    -- | The standard font-family.
+    pageFontFamiliesStandard :: Maybe T.Text,
+    -- | The fixed font-family.
+    pageFontFamiliesFixed :: Maybe T.Text,
+    -- | The serif font-family.
+    pageFontFamiliesSerif :: Maybe T.Text,
+    -- | The sansSerif font-family.
+    pageFontFamiliesSansSerif :: Maybe T.Text,
+    -- | The cursive font-family.
+    pageFontFamiliesCursive :: Maybe T.Text,
+    -- | The fantasy font-family.
+    pageFontFamiliesFantasy :: Maybe T.Text,
+    -- | The math font-family.
+    pageFontFamiliesMath :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON PageFontFamilies where
+  parseJSON = A.withObject "PageFontFamilies" $ \o -> PageFontFamilies
+    <$> o A..:? "standard"
+    <*> o A..:? "fixed"
+    <*> o A..:? "serif"
+    <*> o A..:? "sansSerif"
+    <*> o A..:? "cursive"
+    <*> o A..:? "fantasy"
+    <*> o A..:? "math"
+instance ToJSON PageFontFamilies where
+  toJSON p = A.object $ catMaybes [
+    ("standard" A..=) <$> (pageFontFamiliesStandard p),
+    ("fixed" A..=) <$> (pageFontFamiliesFixed p),
+    ("serif" A..=) <$> (pageFontFamiliesSerif p),
+    ("sansSerif" A..=) <$> (pageFontFamiliesSansSerif p),
+    ("cursive" A..=) <$> (pageFontFamiliesCursive p),
+    ("fantasy" A..=) <$> (pageFontFamiliesFantasy p),
+    ("math" A..=) <$> (pageFontFamiliesMath p)
+    ]
+
+-- | Type 'Page.ScriptFontFamilies'.
+--   Font families collection for a script.
+data PageScriptFontFamilies = PageScriptFontFamilies
+  {
+    -- | Name of the script which these font families are defined for.
+    pageScriptFontFamiliesScript :: T.Text,
+    -- | Generic font families collection for the script.
+    pageScriptFontFamiliesFontFamilies :: PageFontFamilies
+  }
+  deriving (Eq, Show)
+instance FromJSON PageScriptFontFamilies where
+  parseJSON = A.withObject "PageScriptFontFamilies" $ \o -> PageScriptFontFamilies
+    <$> o A..: "script"
+    <*> o A..: "fontFamilies"
+instance ToJSON PageScriptFontFamilies where
+  toJSON p = A.object $ catMaybes [
+    ("script" A..=) <$> Just (pageScriptFontFamiliesScript p),
+    ("fontFamilies" A..=) <$> Just (pageScriptFontFamiliesFontFamilies p)
+    ]
+
+-- | Type 'Page.FontSizes'.
+--   Default font sizes.
+data PageFontSizes = PageFontSizes
+  {
+    -- | Default standard font size.
+    pageFontSizesStandard :: Maybe Int,
+    -- | Default fixed font size.
+    pageFontSizesFixed :: Maybe Int
+  }
+  deriving (Eq, Show)
+instance FromJSON PageFontSizes where
+  parseJSON = A.withObject "PageFontSizes" $ \o -> PageFontSizes
+    <$> o A..:? "standard"
+    <*> o A..:? "fixed"
+instance ToJSON PageFontSizes where
+  toJSON p = A.object $ catMaybes [
+    ("standard" A..=) <$> (pageFontSizesStandard p),
+    ("fixed" A..=) <$> (pageFontSizesFixed p)
+    ]
+
+-- | Type 'Page.ClientNavigationReason'.
+data PageClientNavigationReason = PageClientNavigationReasonFormSubmissionGet | PageClientNavigationReasonFormSubmissionPost | PageClientNavigationReasonHttpHeaderRefresh | PageClientNavigationReasonScriptInitiated | PageClientNavigationReasonMetaTagRefresh | PageClientNavigationReasonPageBlockInterstitial | PageClientNavigationReasonReload | PageClientNavigationReasonAnchorClick
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PageClientNavigationReason where
+  parseJSON = A.withText "PageClientNavigationReason" $ \v -> case v of
+    "formSubmissionGet" -> pure PageClientNavigationReasonFormSubmissionGet
+    "formSubmissionPost" -> pure PageClientNavigationReasonFormSubmissionPost
+    "httpHeaderRefresh" -> pure PageClientNavigationReasonHttpHeaderRefresh
+    "scriptInitiated" -> pure PageClientNavigationReasonScriptInitiated
+    "metaTagRefresh" -> pure PageClientNavigationReasonMetaTagRefresh
+    "pageBlockInterstitial" -> pure PageClientNavigationReasonPageBlockInterstitial
+    "reload" -> pure PageClientNavigationReasonReload
+    "anchorClick" -> pure PageClientNavigationReasonAnchorClick
+    "_" -> fail "failed to parse PageClientNavigationReason"
+instance ToJSON PageClientNavigationReason where
+  toJSON v = A.String $ case v of
+    PageClientNavigationReasonFormSubmissionGet -> "formSubmissionGet"
+    PageClientNavigationReasonFormSubmissionPost -> "formSubmissionPost"
+    PageClientNavigationReasonHttpHeaderRefresh -> "httpHeaderRefresh"
+    PageClientNavigationReasonScriptInitiated -> "scriptInitiated"
+    PageClientNavigationReasonMetaTagRefresh -> "metaTagRefresh"
+    PageClientNavigationReasonPageBlockInterstitial -> "pageBlockInterstitial"
+    PageClientNavigationReasonReload -> "reload"
+    PageClientNavigationReasonAnchorClick -> "anchorClick"
+
+-- | Type 'Page.ClientNavigationDisposition'.
+data PageClientNavigationDisposition = PageClientNavigationDispositionCurrentTab | PageClientNavigationDispositionNewTab | PageClientNavigationDispositionNewWindow | PageClientNavigationDispositionDownload
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PageClientNavigationDisposition where
+  parseJSON = A.withText "PageClientNavigationDisposition" $ \v -> case v of
+    "currentTab" -> pure PageClientNavigationDispositionCurrentTab
+    "newTab" -> pure PageClientNavigationDispositionNewTab
+    "newWindow" -> pure PageClientNavigationDispositionNewWindow
+    "download" -> pure PageClientNavigationDispositionDownload
+    "_" -> fail "failed to parse PageClientNavigationDisposition"
+instance ToJSON PageClientNavigationDisposition where
+  toJSON v = A.String $ case v of
+    PageClientNavigationDispositionCurrentTab -> "currentTab"
+    PageClientNavigationDispositionNewTab -> "newTab"
+    PageClientNavigationDispositionNewWindow -> "newWindow"
+    PageClientNavigationDispositionDownload -> "download"
+
+-- | Type 'Page.InstallabilityErrorArgument'.
+data PageInstallabilityErrorArgument = PageInstallabilityErrorArgument
+  {
+    -- | Argument name (e.g. name:'minimum-icon-size-in-pixels').
+    pageInstallabilityErrorArgumentName :: T.Text,
+    -- | Argument value (e.g. value:'64').
+    pageInstallabilityErrorArgumentValue :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON PageInstallabilityErrorArgument where
+  parseJSON = A.withObject "PageInstallabilityErrorArgument" $ \o -> PageInstallabilityErrorArgument
+    <$> o A..: "name"
+    <*> o A..: "value"
+instance ToJSON PageInstallabilityErrorArgument where
+  toJSON p = A.object $ catMaybes [
+    ("name" A..=) <$> Just (pageInstallabilityErrorArgumentName p),
+    ("value" A..=) <$> Just (pageInstallabilityErrorArgumentValue p)
+    ]
+
+-- | Type 'Page.InstallabilityError'.
+--   The installability error
+data PageInstallabilityError = PageInstallabilityError
+  {
+    -- | The error id (e.g. 'manifest-missing-suitable-icon').
+    pageInstallabilityErrorErrorId :: T.Text,
+    -- | The list of error arguments (e.g. {name:'minimum-icon-size-in-pixels', value:'64'}).
+    pageInstallabilityErrorErrorArguments :: [PageInstallabilityErrorArgument]
+  }
+  deriving (Eq, Show)
+instance FromJSON PageInstallabilityError where
+  parseJSON = A.withObject "PageInstallabilityError" $ \o -> PageInstallabilityError
+    <$> o A..: "errorId"
+    <*> o A..: "errorArguments"
+instance ToJSON PageInstallabilityError where
+  toJSON p = A.object $ catMaybes [
+    ("errorId" A..=) <$> Just (pageInstallabilityErrorErrorId p),
+    ("errorArguments" A..=) <$> Just (pageInstallabilityErrorErrorArguments p)
+    ]
+
+-- | Type 'Page.ReferrerPolicy'.
+--   The referring-policy used for the navigation.
+data PageReferrerPolicy = PageReferrerPolicyNoReferrer | PageReferrerPolicyNoReferrerWhenDowngrade | PageReferrerPolicyOrigin | PageReferrerPolicyOriginWhenCrossOrigin | PageReferrerPolicySameOrigin | PageReferrerPolicyStrictOrigin | PageReferrerPolicyStrictOriginWhenCrossOrigin | PageReferrerPolicyUnsafeUrl
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PageReferrerPolicy where
+  parseJSON = A.withText "PageReferrerPolicy" $ \v -> case v of
+    "noReferrer" -> pure PageReferrerPolicyNoReferrer
+    "noReferrerWhenDowngrade" -> pure PageReferrerPolicyNoReferrerWhenDowngrade
+    "origin" -> pure PageReferrerPolicyOrigin
+    "originWhenCrossOrigin" -> pure PageReferrerPolicyOriginWhenCrossOrigin
+    "sameOrigin" -> pure PageReferrerPolicySameOrigin
+    "strictOrigin" -> pure PageReferrerPolicyStrictOrigin
+    "strictOriginWhenCrossOrigin" -> pure PageReferrerPolicyStrictOriginWhenCrossOrigin
+    "unsafeUrl" -> pure PageReferrerPolicyUnsafeUrl
+    "_" -> fail "failed to parse PageReferrerPolicy"
+instance ToJSON PageReferrerPolicy where
+  toJSON v = A.String $ case v of
+    PageReferrerPolicyNoReferrer -> "noReferrer"
+    PageReferrerPolicyNoReferrerWhenDowngrade -> "noReferrerWhenDowngrade"
+    PageReferrerPolicyOrigin -> "origin"
+    PageReferrerPolicyOriginWhenCrossOrigin -> "originWhenCrossOrigin"
+    PageReferrerPolicySameOrigin -> "sameOrigin"
+    PageReferrerPolicyStrictOrigin -> "strictOrigin"
+    PageReferrerPolicyStrictOriginWhenCrossOrigin -> "strictOriginWhenCrossOrigin"
+    PageReferrerPolicyUnsafeUrl -> "unsafeUrl"
+
+-- | Type 'Page.CompilationCacheParams'.
+--   Per-script compilation cache parameters for `Page.produceCompilationCache`
+data PageCompilationCacheParams = PageCompilationCacheParams
+  {
+    -- | The URL of the script to produce a compilation cache entry for.
+    pageCompilationCacheParamsUrl :: T.Text,
+    -- | A hint to the backend whether eager compilation is recommended.
+    --   (the actual compilation mode used is upon backend discretion).
+    pageCompilationCacheParamsEager :: Maybe Bool
+  }
+  deriving (Eq, Show)
+instance FromJSON PageCompilationCacheParams where
+  parseJSON = A.withObject "PageCompilationCacheParams" $ \o -> PageCompilationCacheParams
+    <$> o A..: "url"
+    <*> o A..:? "eager"
+instance ToJSON PageCompilationCacheParams where
+  toJSON p = A.object $ catMaybes [
+    ("url" A..=) <$> Just (pageCompilationCacheParamsUrl p),
+    ("eager" A..=) <$> (pageCompilationCacheParamsEager p)
+    ]
+
+-- | Type 'Page.NavigationType'.
+--   The type of a frameNavigated event.
+data PageNavigationType = PageNavigationTypeNavigation | PageNavigationTypeBackForwardCacheRestore
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PageNavigationType where
+  parseJSON = A.withText "PageNavigationType" $ \v -> case v of
+    "Navigation" -> pure PageNavigationTypeNavigation
+    "BackForwardCacheRestore" -> pure PageNavigationTypeBackForwardCacheRestore
+    "_" -> fail "failed to parse PageNavigationType"
+instance ToJSON PageNavigationType where
+  toJSON v = A.String $ case v of
+    PageNavigationTypeNavigation -> "Navigation"
+    PageNavigationTypeBackForwardCacheRestore -> "BackForwardCacheRestore"
+
+-- | Type 'Page.BackForwardCacheNotRestoredReason'.
+--   List of not restored reasons for back-forward cache.
+data PageBackForwardCacheNotRestoredReason = PageBackForwardCacheNotRestoredReasonNotPrimaryMainFrame | PageBackForwardCacheNotRestoredReasonBackForwardCacheDisabled | PageBackForwardCacheNotRestoredReasonRelatedActiveContentsExist | PageBackForwardCacheNotRestoredReasonHTTPStatusNotOK | PageBackForwardCacheNotRestoredReasonSchemeNotHTTPOrHTTPS | PageBackForwardCacheNotRestoredReasonLoading | PageBackForwardCacheNotRestoredReasonWasGrantedMediaAccess | PageBackForwardCacheNotRestoredReasonDisableForRenderFrameHostCalled | PageBackForwardCacheNotRestoredReasonDomainNotAllowed | PageBackForwardCacheNotRestoredReasonHTTPMethodNotGET | PageBackForwardCacheNotRestoredReasonSubframeIsNavigating | PageBackForwardCacheNotRestoredReasonTimeout | PageBackForwardCacheNotRestoredReasonCacheLimit | PageBackForwardCacheNotRestoredReasonJavaScriptExecution | PageBackForwardCacheNotRestoredReasonRendererProcessKilled | PageBackForwardCacheNotRestoredReasonRendererProcessCrashed | PageBackForwardCacheNotRestoredReasonSchedulerTrackedFeatureUsed | PageBackForwardCacheNotRestoredReasonConflictingBrowsingInstance | PageBackForwardCacheNotRestoredReasonCacheFlushed | PageBackForwardCacheNotRestoredReasonServiceWorkerVersionActivation | PageBackForwardCacheNotRestoredReasonSessionRestored | PageBackForwardCacheNotRestoredReasonServiceWorkerPostMessage | PageBackForwardCacheNotRestoredReasonEnteredBackForwardCacheBeforeServiceWorkerHostAdded | PageBackForwardCacheNotRestoredReasonRenderFrameHostReused_SameSite | PageBackForwardCacheNotRestoredReasonRenderFrameHostReused_CrossSite | PageBackForwardCacheNotRestoredReasonServiceWorkerClaim | PageBackForwardCacheNotRestoredReasonIgnoreEventAndEvict | PageBackForwardCacheNotRestoredReasonHaveInnerContents | PageBackForwardCacheNotRestoredReasonTimeoutPuttingInCache | PageBackForwardCacheNotRestoredReasonBackForwardCacheDisabledByLowMemory | PageBackForwardCacheNotRestoredReasonBackForwardCacheDisabledByCommandLine | PageBackForwardCacheNotRestoredReasonNetworkRequestDatapipeDrainedAsBytesConsumer | PageBackForwardCacheNotRestoredReasonNetworkRequestRedirected | PageBackForwardCacheNotRestoredReasonNetworkRequestTimeout | PageBackForwardCacheNotRestoredReasonNetworkExceedsBufferLimit | PageBackForwardCacheNotRestoredReasonNavigationCancelledWhileRestoring | PageBackForwardCacheNotRestoredReasonNotMostRecentNavigationEntry | PageBackForwardCacheNotRestoredReasonBackForwardCacheDisabledForPrerender | PageBackForwardCacheNotRestoredReasonUserAgentOverrideDiffers | PageBackForwardCacheNotRestoredReasonForegroundCacheLimit | PageBackForwardCacheNotRestoredReasonBrowsingInstanceNotSwapped | PageBackForwardCacheNotRestoredReasonBackForwardCacheDisabledForDelegate | PageBackForwardCacheNotRestoredReasonUnloadHandlerExistsInMainFrame | PageBackForwardCacheNotRestoredReasonUnloadHandlerExistsInSubFrame | PageBackForwardCacheNotRestoredReasonServiceWorkerUnregistration | PageBackForwardCacheNotRestoredReasonCacheControlNoStore | PageBackForwardCacheNotRestoredReasonCacheControlNoStoreCookieModified | PageBackForwardCacheNotRestoredReasonCacheControlNoStoreHTTPOnlyCookieModified | PageBackForwardCacheNotRestoredReasonNoResponseHead | PageBackForwardCacheNotRestoredReasonUnknown | PageBackForwardCacheNotRestoredReasonActivationNavigationsDisallowedForBug1234857 | PageBackForwardCacheNotRestoredReasonErrorDocument | PageBackForwardCacheNotRestoredReasonFencedFramesEmbedder | PageBackForwardCacheNotRestoredReasonWebSocket | PageBackForwardCacheNotRestoredReasonWebTransport | PageBackForwardCacheNotRestoredReasonWebRTC | PageBackForwardCacheNotRestoredReasonMainResourceHasCacheControlNoStore | PageBackForwardCacheNotRestoredReasonMainResourceHasCacheControlNoCache | PageBackForwardCacheNotRestoredReasonSubresourceHasCacheControlNoStore | PageBackForwardCacheNotRestoredReasonSubresourceHasCacheControlNoCache | PageBackForwardCacheNotRestoredReasonContainsPlugins | PageBackForwardCacheNotRestoredReasonDocumentLoaded | PageBackForwardCacheNotRestoredReasonDedicatedWorkerOrWorklet | PageBackForwardCacheNotRestoredReasonOutstandingNetworkRequestOthers | PageBackForwardCacheNotRestoredReasonOutstandingIndexedDBTransaction | PageBackForwardCacheNotRestoredReasonRequestedNotificationsPermission | PageBackForwardCacheNotRestoredReasonRequestedMIDIPermission | PageBackForwardCacheNotRestoredReasonRequestedAudioCapturePermission | PageBackForwardCacheNotRestoredReasonRequestedVideoCapturePermission | PageBackForwardCacheNotRestoredReasonRequestedBackForwardCacheBlockedSensors | PageBackForwardCacheNotRestoredReasonRequestedBackgroundWorkPermission | PageBackForwardCacheNotRestoredReasonBroadcastChannel | PageBackForwardCacheNotRestoredReasonIndexedDBConnection | PageBackForwardCacheNotRestoredReasonWebXR | PageBackForwardCacheNotRestoredReasonSharedWorker | PageBackForwardCacheNotRestoredReasonWebLocks | PageBackForwardCacheNotRestoredReasonWebHID | PageBackForwardCacheNotRestoredReasonWebShare | PageBackForwardCacheNotRestoredReasonRequestedStorageAccessGrant | PageBackForwardCacheNotRestoredReasonWebNfc | PageBackForwardCacheNotRestoredReasonOutstandingNetworkRequestFetch | PageBackForwardCacheNotRestoredReasonOutstandingNetworkRequestXHR | PageBackForwardCacheNotRestoredReasonAppBanner | PageBackForwardCacheNotRestoredReasonPrinting | PageBackForwardCacheNotRestoredReasonWebDatabase | PageBackForwardCacheNotRestoredReasonPictureInPicture | PageBackForwardCacheNotRestoredReasonPortal | PageBackForwardCacheNotRestoredReasonSpeechRecognizer | PageBackForwardCacheNotRestoredReasonIdleManager | PageBackForwardCacheNotRestoredReasonPaymentManager | PageBackForwardCacheNotRestoredReasonSpeechSynthesis | PageBackForwardCacheNotRestoredReasonKeyboardLock | PageBackForwardCacheNotRestoredReasonWebOTPService | PageBackForwardCacheNotRestoredReasonOutstandingNetworkRequestDirectSocket | PageBackForwardCacheNotRestoredReasonInjectedJavascript | PageBackForwardCacheNotRestoredReasonInjectedStyleSheet | PageBackForwardCacheNotRestoredReasonDummy | PageBackForwardCacheNotRestoredReasonContentSecurityHandler | PageBackForwardCacheNotRestoredReasonContentWebAuthenticationAPI | PageBackForwardCacheNotRestoredReasonContentFileChooser | PageBackForwardCacheNotRestoredReasonContentSerial | PageBackForwardCacheNotRestoredReasonContentFileSystemAccess | PageBackForwardCacheNotRestoredReasonContentMediaDevicesDispatcherHost | PageBackForwardCacheNotRestoredReasonContentWebBluetooth | PageBackForwardCacheNotRestoredReasonContentWebUSB | PageBackForwardCacheNotRestoredReasonContentMediaSessionService | PageBackForwardCacheNotRestoredReasonContentScreenReader | PageBackForwardCacheNotRestoredReasonEmbedderPopupBlockerTabHelper | PageBackForwardCacheNotRestoredReasonEmbedderSafeBrowsingTriggeredPopupBlocker | PageBackForwardCacheNotRestoredReasonEmbedderSafeBrowsingThreatDetails | PageBackForwardCacheNotRestoredReasonEmbedderAppBannerManager | PageBackForwardCacheNotRestoredReasonEmbedderDomDistillerViewerSource | PageBackForwardCacheNotRestoredReasonEmbedderDomDistillerSelfDeletingRequestDelegate | PageBackForwardCacheNotRestoredReasonEmbedderOomInterventionTabHelper | PageBackForwardCacheNotRestoredReasonEmbedderOfflinePage | PageBackForwardCacheNotRestoredReasonEmbedderChromePasswordManagerClientBindCredentialManager | PageBackForwardCacheNotRestoredReasonEmbedderPermissionRequestManager | PageBackForwardCacheNotRestoredReasonEmbedderModalDialog | PageBackForwardCacheNotRestoredReasonEmbedderExtensions | PageBackForwardCacheNotRestoredReasonEmbedderExtensionMessaging | PageBackForwardCacheNotRestoredReasonEmbedderExtensionMessagingForOpenPort | PageBackForwardCacheNotRestoredReasonEmbedderExtensionSentMessageToCachedFrame
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PageBackForwardCacheNotRestoredReason where
+  parseJSON = A.withText "PageBackForwardCacheNotRestoredReason" $ \v -> case v of
+    "NotPrimaryMainFrame" -> pure PageBackForwardCacheNotRestoredReasonNotPrimaryMainFrame
+    "BackForwardCacheDisabled" -> pure PageBackForwardCacheNotRestoredReasonBackForwardCacheDisabled
+    "RelatedActiveContentsExist" -> pure PageBackForwardCacheNotRestoredReasonRelatedActiveContentsExist
+    "HTTPStatusNotOK" -> pure PageBackForwardCacheNotRestoredReasonHTTPStatusNotOK
+    "SchemeNotHTTPOrHTTPS" -> pure PageBackForwardCacheNotRestoredReasonSchemeNotHTTPOrHTTPS
+    "Loading" -> pure PageBackForwardCacheNotRestoredReasonLoading
+    "WasGrantedMediaAccess" -> pure PageBackForwardCacheNotRestoredReasonWasGrantedMediaAccess
+    "DisableForRenderFrameHostCalled" -> pure PageBackForwardCacheNotRestoredReasonDisableForRenderFrameHostCalled
+    "DomainNotAllowed" -> pure PageBackForwardCacheNotRestoredReasonDomainNotAllowed
+    "HTTPMethodNotGET" -> pure PageBackForwardCacheNotRestoredReasonHTTPMethodNotGET
+    "SubframeIsNavigating" -> pure PageBackForwardCacheNotRestoredReasonSubframeIsNavigating
+    "Timeout" -> pure PageBackForwardCacheNotRestoredReasonTimeout
+    "CacheLimit" -> pure PageBackForwardCacheNotRestoredReasonCacheLimit
+    "JavaScriptExecution" -> pure PageBackForwardCacheNotRestoredReasonJavaScriptExecution
+    "RendererProcessKilled" -> pure PageBackForwardCacheNotRestoredReasonRendererProcessKilled
+    "RendererProcessCrashed" -> pure PageBackForwardCacheNotRestoredReasonRendererProcessCrashed
+    "SchedulerTrackedFeatureUsed" -> pure PageBackForwardCacheNotRestoredReasonSchedulerTrackedFeatureUsed
+    "ConflictingBrowsingInstance" -> pure PageBackForwardCacheNotRestoredReasonConflictingBrowsingInstance
+    "CacheFlushed" -> pure PageBackForwardCacheNotRestoredReasonCacheFlushed
+    "ServiceWorkerVersionActivation" -> pure PageBackForwardCacheNotRestoredReasonServiceWorkerVersionActivation
+    "SessionRestored" -> pure PageBackForwardCacheNotRestoredReasonSessionRestored
+    "ServiceWorkerPostMessage" -> pure PageBackForwardCacheNotRestoredReasonServiceWorkerPostMessage
+    "EnteredBackForwardCacheBeforeServiceWorkerHostAdded" -> pure PageBackForwardCacheNotRestoredReasonEnteredBackForwardCacheBeforeServiceWorkerHostAdded
+    "RenderFrameHostReused_SameSite" -> pure PageBackForwardCacheNotRestoredReasonRenderFrameHostReused_SameSite
+    "RenderFrameHostReused_CrossSite" -> pure PageBackForwardCacheNotRestoredReasonRenderFrameHostReused_CrossSite
+    "ServiceWorkerClaim" -> pure PageBackForwardCacheNotRestoredReasonServiceWorkerClaim
+    "IgnoreEventAndEvict" -> pure PageBackForwardCacheNotRestoredReasonIgnoreEventAndEvict
+    "HaveInnerContents" -> pure PageBackForwardCacheNotRestoredReasonHaveInnerContents
+    "TimeoutPuttingInCache" -> pure PageBackForwardCacheNotRestoredReasonTimeoutPuttingInCache
+    "BackForwardCacheDisabledByLowMemory" -> pure PageBackForwardCacheNotRestoredReasonBackForwardCacheDisabledByLowMemory
+    "BackForwardCacheDisabledByCommandLine" -> pure PageBackForwardCacheNotRestoredReasonBackForwardCacheDisabledByCommandLine
+    "NetworkRequestDatapipeDrainedAsBytesConsumer" -> pure PageBackForwardCacheNotRestoredReasonNetworkRequestDatapipeDrainedAsBytesConsumer
+    "NetworkRequestRedirected" -> pure PageBackForwardCacheNotRestoredReasonNetworkRequestRedirected
+    "NetworkRequestTimeout" -> pure PageBackForwardCacheNotRestoredReasonNetworkRequestTimeout
+    "NetworkExceedsBufferLimit" -> pure PageBackForwardCacheNotRestoredReasonNetworkExceedsBufferLimit
+    "NavigationCancelledWhileRestoring" -> pure PageBackForwardCacheNotRestoredReasonNavigationCancelledWhileRestoring
+    "NotMostRecentNavigationEntry" -> pure PageBackForwardCacheNotRestoredReasonNotMostRecentNavigationEntry
+    "BackForwardCacheDisabledForPrerender" -> pure PageBackForwardCacheNotRestoredReasonBackForwardCacheDisabledForPrerender
+    "UserAgentOverrideDiffers" -> pure PageBackForwardCacheNotRestoredReasonUserAgentOverrideDiffers
+    "ForegroundCacheLimit" -> pure PageBackForwardCacheNotRestoredReasonForegroundCacheLimit
+    "BrowsingInstanceNotSwapped" -> pure PageBackForwardCacheNotRestoredReasonBrowsingInstanceNotSwapped
+    "BackForwardCacheDisabledForDelegate" -> pure PageBackForwardCacheNotRestoredReasonBackForwardCacheDisabledForDelegate
+    "UnloadHandlerExistsInMainFrame" -> pure PageBackForwardCacheNotRestoredReasonUnloadHandlerExistsInMainFrame
+    "UnloadHandlerExistsInSubFrame" -> pure PageBackForwardCacheNotRestoredReasonUnloadHandlerExistsInSubFrame
+    "ServiceWorkerUnregistration" -> pure PageBackForwardCacheNotRestoredReasonServiceWorkerUnregistration
+    "CacheControlNoStore" -> pure PageBackForwardCacheNotRestoredReasonCacheControlNoStore
+    "CacheControlNoStoreCookieModified" -> pure PageBackForwardCacheNotRestoredReasonCacheControlNoStoreCookieModified
+    "CacheControlNoStoreHTTPOnlyCookieModified" -> pure PageBackForwardCacheNotRestoredReasonCacheControlNoStoreHTTPOnlyCookieModified
+    "NoResponseHead" -> pure PageBackForwardCacheNotRestoredReasonNoResponseHead
+    "Unknown" -> pure PageBackForwardCacheNotRestoredReasonUnknown
+    "ActivationNavigationsDisallowedForBug1234857" -> pure PageBackForwardCacheNotRestoredReasonActivationNavigationsDisallowedForBug1234857
+    "ErrorDocument" -> pure PageBackForwardCacheNotRestoredReasonErrorDocument
+    "FencedFramesEmbedder" -> pure PageBackForwardCacheNotRestoredReasonFencedFramesEmbedder
+    "WebSocket" -> pure PageBackForwardCacheNotRestoredReasonWebSocket
+    "WebTransport" -> pure PageBackForwardCacheNotRestoredReasonWebTransport
+    "WebRTC" -> pure PageBackForwardCacheNotRestoredReasonWebRTC
+    "MainResourceHasCacheControlNoStore" -> pure PageBackForwardCacheNotRestoredReasonMainResourceHasCacheControlNoStore
+    "MainResourceHasCacheControlNoCache" -> pure PageBackForwardCacheNotRestoredReasonMainResourceHasCacheControlNoCache
+    "SubresourceHasCacheControlNoStore" -> pure PageBackForwardCacheNotRestoredReasonSubresourceHasCacheControlNoStore
+    "SubresourceHasCacheControlNoCache" -> pure PageBackForwardCacheNotRestoredReasonSubresourceHasCacheControlNoCache
+    "ContainsPlugins" -> pure PageBackForwardCacheNotRestoredReasonContainsPlugins
+    "DocumentLoaded" -> pure PageBackForwardCacheNotRestoredReasonDocumentLoaded
+    "DedicatedWorkerOrWorklet" -> pure PageBackForwardCacheNotRestoredReasonDedicatedWorkerOrWorklet
+    "OutstandingNetworkRequestOthers" -> pure PageBackForwardCacheNotRestoredReasonOutstandingNetworkRequestOthers
+    "OutstandingIndexedDBTransaction" -> pure PageBackForwardCacheNotRestoredReasonOutstandingIndexedDBTransaction
+    "RequestedNotificationsPermission" -> pure PageBackForwardCacheNotRestoredReasonRequestedNotificationsPermission
+    "RequestedMIDIPermission" -> pure PageBackForwardCacheNotRestoredReasonRequestedMIDIPermission
+    "RequestedAudioCapturePermission" -> pure PageBackForwardCacheNotRestoredReasonRequestedAudioCapturePermission
+    "RequestedVideoCapturePermission" -> pure PageBackForwardCacheNotRestoredReasonRequestedVideoCapturePermission
+    "RequestedBackForwardCacheBlockedSensors" -> pure PageBackForwardCacheNotRestoredReasonRequestedBackForwardCacheBlockedSensors
+    "RequestedBackgroundWorkPermission" -> pure PageBackForwardCacheNotRestoredReasonRequestedBackgroundWorkPermission
+    "BroadcastChannel" -> pure PageBackForwardCacheNotRestoredReasonBroadcastChannel
+    "IndexedDBConnection" -> pure PageBackForwardCacheNotRestoredReasonIndexedDBConnection
+    "WebXR" -> pure PageBackForwardCacheNotRestoredReasonWebXR
+    "SharedWorker" -> pure PageBackForwardCacheNotRestoredReasonSharedWorker
+    "WebLocks" -> pure PageBackForwardCacheNotRestoredReasonWebLocks
+    "WebHID" -> pure PageBackForwardCacheNotRestoredReasonWebHID
+    "WebShare" -> pure PageBackForwardCacheNotRestoredReasonWebShare
+    "RequestedStorageAccessGrant" -> pure PageBackForwardCacheNotRestoredReasonRequestedStorageAccessGrant
+    "WebNfc" -> pure PageBackForwardCacheNotRestoredReasonWebNfc
+    "OutstandingNetworkRequestFetch" -> pure PageBackForwardCacheNotRestoredReasonOutstandingNetworkRequestFetch
+    "OutstandingNetworkRequestXHR" -> pure PageBackForwardCacheNotRestoredReasonOutstandingNetworkRequestXHR
+    "AppBanner" -> pure PageBackForwardCacheNotRestoredReasonAppBanner
+    "Printing" -> pure PageBackForwardCacheNotRestoredReasonPrinting
+    "WebDatabase" -> pure PageBackForwardCacheNotRestoredReasonWebDatabase
+    "PictureInPicture" -> pure PageBackForwardCacheNotRestoredReasonPictureInPicture
+    "Portal" -> pure PageBackForwardCacheNotRestoredReasonPortal
+    "SpeechRecognizer" -> pure PageBackForwardCacheNotRestoredReasonSpeechRecognizer
+    "IdleManager" -> pure PageBackForwardCacheNotRestoredReasonIdleManager
+    "PaymentManager" -> pure PageBackForwardCacheNotRestoredReasonPaymentManager
+    "SpeechSynthesis" -> pure PageBackForwardCacheNotRestoredReasonSpeechSynthesis
+    "KeyboardLock" -> pure PageBackForwardCacheNotRestoredReasonKeyboardLock
+    "WebOTPService" -> pure PageBackForwardCacheNotRestoredReasonWebOTPService
+    "OutstandingNetworkRequestDirectSocket" -> pure PageBackForwardCacheNotRestoredReasonOutstandingNetworkRequestDirectSocket
+    "InjectedJavascript" -> pure PageBackForwardCacheNotRestoredReasonInjectedJavascript
+    "InjectedStyleSheet" -> pure PageBackForwardCacheNotRestoredReasonInjectedStyleSheet
+    "Dummy" -> pure PageBackForwardCacheNotRestoredReasonDummy
+    "ContentSecurityHandler" -> pure PageBackForwardCacheNotRestoredReasonContentSecurityHandler
+    "ContentWebAuthenticationAPI" -> pure PageBackForwardCacheNotRestoredReasonContentWebAuthenticationAPI
+    "ContentFileChooser" -> pure PageBackForwardCacheNotRestoredReasonContentFileChooser
+    "ContentSerial" -> pure PageBackForwardCacheNotRestoredReasonContentSerial
+    "ContentFileSystemAccess" -> pure PageBackForwardCacheNotRestoredReasonContentFileSystemAccess
+    "ContentMediaDevicesDispatcherHost" -> pure PageBackForwardCacheNotRestoredReasonContentMediaDevicesDispatcherHost
+    "ContentWebBluetooth" -> pure PageBackForwardCacheNotRestoredReasonContentWebBluetooth
+    "ContentWebUSB" -> pure PageBackForwardCacheNotRestoredReasonContentWebUSB
+    "ContentMediaSessionService" -> pure PageBackForwardCacheNotRestoredReasonContentMediaSessionService
+    "ContentScreenReader" -> pure PageBackForwardCacheNotRestoredReasonContentScreenReader
+    "EmbedderPopupBlockerTabHelper" -> pure PageBackForwardCacheNotRestoredReasonEmbedderPopupBlockerTabHelper
+    "EmbedderSafeBrowsingTriggeredPopupBlocker" -> pure PageBackForwardCacheNotRestoredReasonEmbedderSafeBrowsingTriggeredPopupBlocker
+    "EmbedderSafeBrowsingThreatDetails" -> pure PageBackForwardCacheNotRestoredReasonEmbedderSafeBrowsingThreatDetails
+    "EmbedderAppBannerManager" -> pure PageBackForwardCacheNotRestoredReasonEmbedderAppBannerManager
+    "EmbedderDomDistillerViewerSource" -> pure PageBackForwardCacheNotRestoredReasonEmbedderDomDistillerViewerSource
+    "EmbedderDomDistillerSelfDeletingRequestDelegate" -> pure PageBackForwardCacheNotRestoredReasonEmbedderDomDistillerSelfDeletingRequestDelegate
+    "EmbedderOomInterventionTabHelper" -> pure PageBackForwardCacheNotRestoredReasonEmbedderOomInterventionTabHelper
+    "EmbedderOfflinePage" -> pure PageBackForwardCacheNotRestoredReasonEmbedderOfflinePage
+    "EmbedderChromePasswordManagerClientBindCredentialManager" -> pure PageBackForwardCacheNotRestoredReasonEmbedderChromePasswordManagerClientBindCredentialManager
+    "EmbedderPermissionRequestManager" -> pure PageBackForwardCacheNotRestoredReasonEmbedderPermissionRequestManager
+    "EmbedderModalDialog" -> pure PageBackForwardCacheNotRestoredReasonEmbedderModalDialog
+    "EmbedderExtensions" -> pure PageBackForwardCacheNotRestoredReasonEmbedderExtensions
+    "EmbedderExtensionMessaging" -> pure PageBackForwardCacheNotRestoredReasonEmbedderExtensionMessaging
+    "EmbedderExtensionMessagingForOpenPort" -> pure PageBackForwardCacheNotRestoredReasonEmbedderExtensionMessagingForOpenPort
+    "EmbedderExtensionSentMessageToCachedFrame" -> pure PageBackForwardCacheNotRestoredReasonEmbedderExtensionSentMessageToCachedFrame
+    "_" -> fail "failed to parse PageBackForwardCacheNotRestoredReason"
+instance ToJSON PageBackForwardCacheNotRestoredReason where
+  toJSON v = A.String $ case v of
+    PageBackForwardCacheNotRestoredReasonNotPrimaryMainFrame -> "NotPrimaryMainFrame"
+    PageBackForwardCacheNotRestoredReasonBackForwardCacheDisabled -> "BackForwardCacheDisabled"
+    PageBackForwardCacheNotRestoredReasonRelatedActiveContentsExist -> "RelatedActiveContentsExist"
+    PageBackForwardCacheNotRestoredReasonHTTPStatusNotOK -> "HTTPStatusNotOK"
+    PageBackForwardCacheNotRestoredReasonSchemeNotHTTPOrHTTPS -> "SchemeNotHTTPOrHTTPS"
+    PageBackForwardCacheNotRestoredReasonLoading -> "Loading"
+    PageBackForwardCacheNotRestoredReasonWasGrantedMediaAccess -> "WasGrantedMediaAccess"
+    PageBackForwardCacheNotRestoredReasonDisableForRenderFrameHostCalled -> "DisableForRenderFrameHostCalled"
+    PageBackForwardCacheNotRestoredReasonDomainNotAllowed -> "DomainNotAllowed"
+    PageBackForwardCacheNotRestoredReasonHTTPMethodNotGET -> "HTTPMethodNotGET"
+    PageBackForwardCacheNotRestoredReasonSubframeIsNavigating -> "SubframeIsNavigating"
+    PageBackForwardCacheNotRestoredReasonTimeout -> "Timeout"
+    PageBackForwardCacheNotRestoredReasonCacheLimit -> "CacheLimit"
+    PageBackForwardCacheNotRestoredReasonJavaScriptExecution -> "JavaScriptExecution"
+    PageBackForwardCacheNotRestoredReasonRendererProcessKilled -> "RendererProcessKilled"
+    PageBackForwardCacheNotRestoredReasonRendererProcessCrashed -> "RendererProcessCrashed"
+    PageBackForwardCacheNotRestoredReasonSchedulerTrackedFeatureUsed -> "SchedulerTrackedFeatureUsed"
+    PageBackForwardCacheNotRestoredReasonConflictingBrowsingInstance -> "ConflictingBrowsingInstance"
+    PageBackForwardCacheNotRestoredReasonCacheFlushed -> "CacheFlushed"
+    PageBackForwardCacheNotRestoredReasonServiceWorkerVersionActivation -> "ServiceWorkerVersionActivation"
+    PageBackForwardCacheNotRestoredReasonSessionRestored -> "SessionRestored"
+    PageBackForwardCacheNotRestoredReasonServiceWorkerPostMessage -> "ServiceWorkerPostMessage"
+    PageBackForwardCacheNotRestoredReasonEnteredBackForwardCacheBeforeServiceWorkerHostAdded -> "EnteredBackForwardCacheBeforeServiceWorkerHostAdded"
+    PageBackForwardCacheNotRestoredReasonRenderFrameHostReused_SameSite -> "RenderFrameHostReused_SameSite"
+    PageBackForwardCacheNotRestoredReasonRenderFrameHostReused_CrossSite -> "RenderFrameHostReused_CrossSite"
+    PageBackForwardCacheNotRestoredReasonServiceWorkerClaim -> "ServiceWorkerClaim"
+    PageBackForwardCacheNotRestoredReasonIgnoreEventAndEvict -> "IgnoreEventAndEvict"
+    PageBackForwardCacheNotRestoredReasonHaveInnerContents -> "HaveInnerContents"
+    PageBackForwardCacheNotRestoredReasonTimeoutPuttingInCache -> "TimeoutPuttingInCache"
+    PageBackForwardCacheNotRestoredReasonBackForwardCacheDisabledByLowMemory -> "BackForwardCacheDisabledByLowMemory"
+    PageBackForwardCacheNotRestoredReasonBackForwardCacheDisabledByCommandLine -> "BackForwardCacheDisabledByCommandLine"
+    PageBackForwardCacheNotRestoredReasonNetworkRequestDatapipeDrainedAsBytesConsumer -> "NetworkRequestDatapipeDrainedAsBytesConsumer"
+    PageBackForwardCacheNotRestoredReasonNetworkRequestRedirected -> "NetworkRequestRedirected"
+    PageBackForwardCacheNotRestoredReasonNetworkRequestTimeout -> "NetworkRequestTimeout"
+    PageBackForwardCacheNotRestoredReasonNetworkExceedsBufferLimit -> "NetworkExceedsBufferLimit"
+    PageBackForwardCacheNotRestoredReasonNavigationCancelledWhileRestoring -> "NavigationCancelledWhileRestoring"
+    PageBackForwardCacheNotRestoredReasonNotMostRecentNavigationEntry -> "NotMostRecentNavigationEntry"
+    PageBackForwardCacheNotRestoredReasonBackForwardCacheDisabledForPrerender -> "BackForwardCacheDisabledForPrerender"
+    PageBackForwardCacheNotRestoredReasonUserAgentOverrideDiffers -> "UserAgentOverrideDiffers"
+    PageBackForwardCacheNotRestoredReasonForegroundCacheLimit -> "ForegroundCacheLimit"
+    PageBackForwardCacheNotRestoredReasonBrowsingInstanceNotSwapped -> "BrowsingInstanceNotSwapped"
+    PageBackForwardCacheNotRestoredReasonBackForwardCacheDisabledForDelegate -> "BackForwardCacheDisabledForDelegate"
+    PageBackForwardCacheNotRestoredReasonUnloadHandlerExistsInMainFrame -> "UnloadHandlerExistsInMainFrame"
+    PageBackForwardCacheNotRestoredReasonUnloadHandlerExistsInSubFrame -> "UnloadHandlerExistsInSubFrame"
+    PageBackForwardCacheNotRestoredReasonServiceWorkerUnregistration -> "ServiceWorkerUnregistration"
+    PageBackForwardCacheNotRestoredReasonCacheControlNoStore -> "CacheControlNoStore"
+    PageBackForwardCacheNotRestoredReasonCacheControlNoStoreCookieModified -> "CacheControlNoStoreCookieModified"
+    PageBackForwardCacheNotRestoredReasonCacheControlNoStoreHTTPOnlyCookieModified -> "CacheControlNoStoreHTTPOnlyCookieModified"
+    PageBackForwardCacheNotRestoredReasonNoResponseHead -> "NoResponseHead"
+    PageBackForwardCacheNotRestoredReasonUnknown -> "Unknown"
+    PageBackForwardCacheNotRestoredReasonActivationNavigationsDisallowedForBug1234857 -> "ActivationNavigationsDisallowedForBug1234857"
+    PageBackForwardCacheNotRestoredReasonErrorDocument -> "ErrorDocument"
+    PageBackForwardCacheNotRestoredReasonFencedFramesEmbedder -> "FencedFramesEmbedder"
+    PageBackForwardCacheNotRestoredReasonWebSocket -> "WebSocket"
+    PageBackForwardCacheNotRestoredReasonWebTransport -> "WebTransport"
+    PageBackForwardCacheNotRestoredReasonWebRTC -> "WebRTC"
+    PageBackForwardCacheNotRestoredReasonMainResourceHasCacheControlNoStore -> "MainResourceHasCacheControlNoStore"
+    PageBackForwardCacheNotRestoredReasonMainResourceHasCacheControlNoCache -> "MainResourceHasCacheControlNoCache"
+    PageBackForwardCacheNotRestoredReasonSubresourceHasCacheControlNoStore -> "SubresourceHasCacheControlNoStore"
+    PageBackForwardCacheNotRestoredReasonSubresourceHasCacheControlNoCache -> "SubresourceHasCacheControlNoCache"
+    PageBackForwardCacheNotRestoredReasonContainsPlugins -> "ContainsPlugins"
+    PageBackForwardCacheNotRestoredReasonDocumentLoaded -> "DocumentLoaded"
+    PageBackForwardCacheNotRestoredReasonDedicatedWorkerOrWorklet -> "DedicatedWorkerOrWorklet"
+    PageBackForwardCacheNotRestoredReasonOutstandingNetworkRequestOthers -> "OutstandingNetworkRequestOthers"
+    PageBackForwardCacheNotRestoredReasonOutstandingIndexedDBTransaction -> "OutstandingIndexedDBTransaction"
+    PageBackForwardCacheNotRestoredReasonRequestedNotificationsPermission -> "RequestedNotificationsPermission"
+    PageBackForwardCacheNotRestoredReasonRequestedMIDIPermission -> "RequestedMIDIPermission"
+    PageBackForwardCacheNotRestoredReasonRequestedAudioCapturePermission -> "RequestedAudioCapturePermission"
+    PageBackForwardCacheNotRestoredReasonRequestedVideoCapturePermission -> "RequestedVideoCapturePermission"
+    PageBackForwardCacheNotRestoredReasonRequestedBackForwardCacheBlockedSensors -> "RequestedBackForwardCacheBlockedSensors"
+    PageBackForwardCacheNotRestoredReasonRequestedBackgroundWorkPermission -> "RequestedBackgroundWorkPermission"
+    PageBackForwardCacheNotRestoredReasonBroadcastChannel -> "BroadcastChannel"
+    PageBackForwardCacheNotRestoredReasonIndexedDBConnection -> "IndexedDBConnection"
+    PageBackForwardCacheNotRestoredReasonWebXR -> "WebXR"
+    PageBackForwardCacheNotRestoredReasonSharedWorker -> "SharedWorker"
+    PageBackForwardCacheNotRestoredReasonWebLocks -> "WebLocks"
+    PageBackForwardCacheNotRestoredReasonWebHID -> "WebHID"
+    PageBackForwardCacheNotRestoredReasonWebShare -> "WebShare"
+    PageBackForwardCacheNotRestoredReasonRequestedStorageAccessGrant -> "RequestedStorageAccessGrant"
+    PageBackForwardCacheNotRestoredReasonWebNfc -> "WebNfc"
+    PageBackForwardCacheNotRestoredReasonOutstandingNetworkRequestFetch -> "OutstandingNetworkRequestFetch"
+    PageBackForwardCacheNotRestoredReasonOutstandingNetworkRequestXHR -> "OutstandingNetworkRequestXHR"
+    PageBackForwardCacheNotRestoredReasonAppBanner -> "AppBanner"
+    PageBackForwardCacheNotRestoredReasonPrinting -> "Printing"
+    PageBackForwardCacheNotRestoredReasonWebDatabase -> "WebDatabase"
+    PageBackForwardCacheNotRestoredReasonPictureInPicture -> "PictureInPicture"
+    PageBackForwardCacheNotRestoredReasonPortal -> "Portal"
+    PageBackForwardCacheNotRestoredReasonSpeechRecognizer -> "SpeechRecognizer"
+    PageBackForwardCacheNotRestoredReasonIdleManager -> "IdleManager"
+    PageBackForwardCacheNotRestoredReasonPaymentManager -> "PaymentManager"
+    PageBackForwardCacheNotRestoredReasonSpeechSynthesis -> "SpeechSynthesis"
+    PageBackForwardCacheNotRestoredReasonKeyboardLock -> "KeyboardLock"
+    PageBackForwardCacheNotRestoredReasonWebOTPService -> "WebOTPService"
+    PageBackForwardCacheNotRestoredReasonOutstandingNetworkRequestDirectSocket -> "OutstandingNetworkRequestDirectSocket"
+    PageBackForwardCacheNotRestoredReasonInjectedJavascript -> "InjectedJavascript"
+    PageBackForwardCacheNotRestoredReasonInjectedStyleSheet -> "InjectedStyleSheet"
+    PageBackForwardCacheNotRestoredReasonDummy -> "Dummy"
+    PageBackForwardCacheNotRestoredReasonContentSecurityHandler -> "ContentSecurityHandler"
+    PageBackForwardCacheNotRestoredReasonContentWebAuthenticationAPI -> "ContentWebAuthenticationAPI"
+    PageBackForwardCacheNotRestoredReasonContentFileChooser -> "ContentFileChooser"
+    PageBackForwardCacheNotRestoredReasonContentSerial -> "ContentSerial"
+    PageBackForwardCacheNotRestoredReasonContentFileSystemAccess -> "ContentFileSystemAccess"
+    PageBackForwardCacheNotRestoredReasonContentMediaDevicesDispatcherHost -> "ContentMediaDevicesDispatcherHost"
+    PageBackForwardCacheNotRestoredReasonContentWebBluetooth -> "ContentWebBluetooth"
+    PageBackForwardCacheNotRestoredReasonContentWebUSB -> "ContentWebUSB"
+    PageBackForwardCacheNotRestoredReasonContentMediaSessionService -> "ContentMediaSessionService"
+    PageBackForwardCacheNotRestoredReasonContentScreenReader -> "ContentScreenReader"
+    PageBackForwardCacheNotRestoredReasonEmbedderPopupBlockerTabHelper -> "EmbedderPopupBlockerTabHelper"
+    PageBackForwardCacheNotRestoredReasonEmbedderSafeBrowsingTriggeredPopupBlocker -> "EmbedderSafeBrowsingTriggeredPopupBlocker"
+    PageBackForwardCacheNotRestoredReasonEmbedderSafeBrowsingThreatDetails -> "EmbedderSafeBrowsingThreatDetails"
+    PageBackForwardCacheNotRestoredReasonEmbedderAppBannerManager -> "EmbedderAppBannerManager"
+    PageBackForwardCacheNotRestoredReasonEmbedderDomDistillerViewerSource -> "EmbedderDomDistillerViewerSource"
+    PageBackForwardCacheNotRestoredReasonEmbedderDomDistillerSelfDeletingRequestDelegate -> "EmbedderDomDistillerSelfDeletingRequestDelegate"
+    PageBackForwardCacheNotRestoredReasonEmbedderOomInterventionTabHelper -> "EmbedderOomInterventionTabHelper"
+    PageBackForwardCacheNotRestoredReasonEmbedderOfflinePage -> "EmbedderOfflinePage"
+    PageBackForwardCacheNotRestoredReasonEmbedderChromePasswordManagerClientBindCredentialManager -> "EmbedderChromePasswordManagerClientBindCredentialManager"
+    PageBackForwardCacheNotRestoredReasonEmbedderPermissionRequestManager -> "EmbedderPermissionRequestManager"
+    PageBackForwardCacheNotRestoredReasonEmbedderModalDialog -> "EmbedderModalDialog"
+    PageBackForwardCacheNotRestoredReasonEmbedderExtensions -> "EmbedderExtensions"
+    PageBackForwardCacheNotRestoredReasonEmbedderExtensionMessaging -> "EmbedderExtensionMessaging"
+    PageBackForwardCacheNotRestoredReasonEmbedderExtensionMessagingForOpenPort -> "EmbedderExtensionMessagingForOpenPort"
+    PageBackForwardCacheNotRestoredReasonEmbedderExtensionSentMessageToCachedFrame -> "EmbedderExtensionSentMessageToCachedFrame"
+
+-- | Type 'Page.BackForwardCacheNotRestoredReasonType'.
+--   Types of not restored reasons for back-forward cache.
+data PageBackForwardCacheNotRestoredReasonType = PageBackForwardCacheNotRestoredReasonTypeSupportPending | PageBackForwardCacheNotRestoredReasonTypePageSupportNeeded | PageBackForwardCacheNotRestoredReasonTypeCircumstantial
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PageBackForwardCacheNotRestoredReasonType where
+  parseJSON = A.withText "PageBackForwardCacheNotRestoredReasonType" $ \v -> case v of
+    "SupportPending" -> pure PageBackForwardCacheNotRestoredReasonTypeSupportPending
+    "PageSupportNeeded" -> pure PageBackForwardCacheNotRestoredReasonTypePageSupportNeeded
+    "Circumstantial" -> pure PageBackForwardCacheNotRestoredReasonTypeCircumstantial
+    "_" -> fail "failed to parse PageBackForwardCacheNotRestoredReasonType"
+instance ToJSON PageBackForwardCacheNotRestoredReasonType where
+  toJSON v = A.String $ case v of
+    PageBackForwardCacheNotRestoredReasonTypeSupportPending -> "SupportPending"
+    PageBackForwardCacheNotRestoredReasonTypePageSupportNeeded -> "PageSupportNeeded"
+    PageBackForwardCacheNotRestoredReasonTypeCircumstantial -> "Circumstantial"
+
+-- | Type 'Page.BackForwardCacheNotRestoredExplanation'.
+data PageBackForwardCacheNotRestoredExplanation = PageBackForwardCacheNotRestoredExplanation
+  {
+    -- | Type of the reason
+    pageBackForwardCacheNotRestoredExplanationType :: PageBackForwardCacheNotRestoredReasonType,
+    -- | Not restored reason
+    pageBackForwardCacheNotRestoredExplanationReason :: PageBackForwardCacheNotRestoredReason,
+    -- | Context associated with the reason. The meaning of this context is
+    --   dependent on the reason:
+    --   - EmbedderExtensionSentMessageToCachedFrame: the extension ID.
+    pageBackForwardCacheNotRestoredExplanationContext :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON PageBackForwardCacheNotRestoredExplanation where
+  parseJSON = A.withObject "PageBackForwardCacheNotRestoredExplanation" $ \o -> PageBackForwardCacheNotRestoredExplanation
+    <$> o A..: "type"
+    <*> o A..: "reason"
+    <*> o A..:? "context"
+instance ToJSON PageBackForwardCacheNotRestoredExplanation where
+  toJSON p = A.object $ catMaybes [
+    ("type" A..=) <$> Just (pageBackForwardCacheNotRestoredExplanationType p),
+    ("reason" A..=) <$> Just (pageBackForwardCacheNotRestoredExplanationReason p),
+    ("context" A..=) <$> (pageBackForwardCacheNotRestoredExplanationContext p)
+    ]
+
+-- | Type 'Page.BackForwardCacheNotRestoredExplanationTree'.
+data PageBackForwardCacheNotRestoredExplanationTree = PageBackForwardCacheNotRestoredExplanationTree
+  {
+    -- | URL of each frame
+    pageBackForwardCacheNotRestoredExplanationTreeUrl :: T.Text,
+    -- | Not restored reasons of each frame
+    pageBackForwardCacheNotRestoredExplanationTreeExplanations :: [PageBackForwardCacheNotRestoredExplanation],
+    -- | Array of children frame
+    pageBackForwardCacheNotRestoredExplanationTreeChildren :: [PageBackForwardCacheNotRestoredExplanationTree]
+  }
+  deriving (Eq, Show)
+instance FromJSON PageBackForwardCacheNotRestoredExplanationTree where
+  parseJSON = A.withObject "PageBackForwardCacheNotRestoredExplanationTree" $ \o -> PageBackForwardCacheNotRestoredExplanationTree
+    <$> o A..: "url"
+    <*> o A..: "explanations"
+    <*> o A..: "children"
+instance ToJSON PageBackForwardCacheNotRestoredExplanationTree where
+  toJSON p = A.object $ catMaybes [
+    ("url" A..=) <$> Just (pageBackForwardCacheNotRestoredExplanationTreeUrl p),
+    ("explanations" A..=) <$> Just (pageBackForwardCacheNotRestoredExplanationTreeExplanations p),
+    ("children" A..=) <$> Just (pageBackForwardCacheNotRestoredExplanationTreeChildren p)
+    ]
+
+-- | Type 'Page.PrerenderFinalStatus'.
+--   List of FinalStatus reasons for Prerender2.
+data PagePrerenderFinalStatus = PagePrerenderFinalStatusActivated | PagePrerenderFinalStatusDestroyed | PagePrerenderFinalStatusLowEndDevice | PagePrerenderFinalStatusCrossOriginRedirect | PagePrerenderFinalStatusCrossOriginNavigation | PagePrerenderFinalStatusInvalidSchemeRedirect | PagePrerenderFinalStatusInvalidSchemeNavigation | PagePrerenderFinalStatusInProgressNavigation | PagePrerenderFinalStatusNavigationRequestBlockedByCsp | PagePrerenderFinalStatusMainFrameNavigation | PagePrerenderFinalStatusMojoBinderPolicy | PagePrerenderFinalStatusRendererProcessCrashed | PagePrerenderFinalStatusRendererProcessKilled | PagePrerenderFinalStatusDownload | PagePrerenderFinalStatusTriggerDestroyed | PagePrerenderFinalStatusNavigationNotCommitted | PagePrerenderFinalStatusNavigationBadHttpStatus | PagePrerenderFinalStatusClientCertRequested | PagePrerenderFinalStatusNavigationRequestNetworkError | PagePrerenderFinalStatusMaxNumOfRunningPrerendersExceeded | PagePrerenderFinalStatusCancelAllHostsForTesting | PagePrerenderFinalStatusDidFailLoad | PagePrerenderFinalStatusStop | PagePrerenderFinalStatusSslCertificateError | PagePrerenderFinalStatusLoginAuthRequested | PagePrerenderFinalStatusUaChangeRequiresReload | PagePrerenderFinalStatusBlockedByClient | PagePrerenderFinalStatusAudioOutputDeviceRequested | PagePrerenderFinalStatusMixedContent | PagePrerenderFinalStatusTriggerBackgrounded | PagePrerenderFinalStatusEmbedderTriggeredAndCrossOriginRedirected | PagePrerenderFinalStatusMemoryLimitExceeded | PagePrerenderFinalStatusFailToGetMemoryUsage | PagePrerenderFinalStatusDataSaverEnabled | PagePrerenderFinalStatusHasEffectiveUrl | PagePrerenderFinalStatusActivatedBeforeStarted | PagePrerenderFinalStatusInactivePageRestriction | PagePrerenderFinalStatusStartFailed | PagePrerenderFinalStatusTimeoutBackgrounded
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PagePrerenderFinalStatus where
+  parseJSON = A.withText "PagePrerenderFinalStatus" $ \v -> case v of
+    "Activated" -> pure PagePrerenderFinalStatusActivated
+    "Destroyed" -> pure PagePrerenderFinalStatusDestroyed
+    "LowEndDevice" -> pure PagePrerenderFinalStatusLowEndDevice
+    "CrossOriginRedirect" -> pure PagePrerenderFinalStatusCrossOriginRedirect
+    "CrossOriginNavigation" -> pure PagePrerenderFinalStatusCrossOriginNavigation
+    "InvalidSchemeRedirect" -> pure PagePrerenderFinalStatusInvalidSchemeRedirect
+    "InvalidSchemeNavigation" -> pure PagePrerenderFinalStatusInvalidSchemeNavigation
+    "InProgressNavigation" -> pure PagePrerenderFinalStatusInProgressNavigation
+    "NavigationRequestBlockedByCsp" -> pure PagePrerenderFinalStatusNavigationRequestBlockedByCsp
+    "MainFrameNavigation" -> pure PagePrerenderFinalStatusMainFrameNavigation
+    "MojoBinderPolicy" -> pure PagePrerenderFinalStatusMojoBinderPolicy
+    "RendererProcessCrashed" -> pure PagePrerenderFinalStatusRendererProcessCrashed
+    "RendererProcessKilled" -> pure PagePrerenderFinalStatusRendererProcessKilled
+    "Download" -> pure PagePrerenderFinalStatusDownload
+    "TriggerDestroyed" -> pure PagePrerenderFinalStatusTriggerDestroyed
+    "NavigationNotCommitted" -> pure PagePrerenderFinalStatusNavigationNotCommitted
+    "NavigationBadHttpStatus" -> pure PagePrerenderFinalStatusNavigationBadHttpStatus
+    "ClientCertRequested" -> pure PagePrerenderFinalStatusClientCertRequested
+    "NavigationRequestNetworkError" -> pure PagePrerenderFinalStatusNavigationRequestNetworkError
+    "MaxNumOfRunningPrerendersExceeded" -> pure PagePrerenderFinalStatusMaxNumOfRunningPrerendersExceeded
+    "CancelAllHostsForTesting" -> pure PagePrerenderFinalStatusCancelAllHostsForTesting
+    "DidFailLoad" -> pure PagePrerenderFinalStatusDidFailLoad
+    "Stop" -> pure PagePrerenderFinalStatusStop
+    "SslCertificateError" -> pure PagePrerenderFinalStatusSslCertificateError
+    "LoginAuthRequested" -> pure PagePrerenderFinalStatusLoginAuthRequested
+    "UaChangeRequiresReload" -> pure PagePrerenderFinalStatusUaChangeRequiresReload
+    "BlockedByClient" -> pure PagePrerenderFinalStatusBlockedByClient
+    "AudioOutputDeviceRequested" -> pure PagePrerenderFinalStatusAudioOutputDeviceRequested
+    "MixedContent" -> pure PagePrerenderFinalStatusMixedContent
+    "TriggerBackgrounded" -> pure PagePrerenderFinalStatusTriggerBackgrounded
+    "EmbedderTriggeredAndCrossOriginRedirected" -> pure PagePrerenderFinalStatusEmbedderTriggeredAndCrossOriginRedirected
+    "MemoryLimitExceeded" -> pure PagePrerenderFinalStatusMemoryLimitExceeded
+    "FailToGetMemoryUsage" -> pure PagePrerenderFinalStatusFailToGetMemoryUsage
+    "DataSaverEnabled" -> pure PagePrerenderFinalStatusDataSaverEnabled
+    "HasEffectiveUrl" -> pure PagePrerenderFinalStatusHasEffectiveUrl
+    "ActivatedBeforeStarted" -> pure PagePrerenderFinalStatusActivatedBeforeStarted
+    "InactivePageRestriction" -> pure PagePrerenderFinalStatusInactivePageRestriction
+    "StartFailed" -> pure PagePrerenderFinalStatusStartFailed
+    "TimeoutBackgrounded" -> pure PagePrerenderFinalStatusTimeoutBackgrounded
+    "_" -> fail "failed to parse PagePrerenderFinalStatus"
+instance ToJSON PagePrerenderFinalStatus where
+  toJSON v = A.String $ case v of
+    PagePrerenderFinalStatusActivated -> "Activated"
+    PagePrerenderFinalStatusDestroyed -> "Destroyed"
+    PagePrerenderFinalStatusLowEndDevice -> "LowEndDevice"
+    PagePrerenderFinalStatusCrossOriginRedirect -> "CrossOriginRedirect"
+    PagePrerenderFinalStatusCrossOriginNavigation -> "CrossOriginNavigation"
+    PagePrerenderFinalStatusInvalidSchemeRedirect -> "InvalidSchemeRedirect"
+    PagePrerenderFinalStatusInvalidSchemeNavigation -> "InvalidSchemeNavigation"
+    PagePrerenderFinalStatusInProgressNavigation -> "InProgressNavigation"
+    PagePrerenderFinalStatusNavigationRequestBlockedByCsp -> "NavigationRequestBlockedByCsp"
+    PagePrerenderFinalStatusMainFrameNavigation -> "MainFrameNavigation"
+    PagePrerenderFinalStatusMojoBinderPolicy -> "MojoBinderPolicy"
+    PagePrerenderFinalStatusRendererProcessCrashed -> "RendererProcessCrashed"
+    PagePrerenderFinalStatusRendererProcessKilled -> "RendererProcessKilled"
+    PagePrerenderFinalStatusDownload -> "Download"
+    PagePrerenderFinalStatusTriggerDestroyed -> "TriggerDestroyed"
+    PagePrerenderFinalStatusNavigationNotCommitted -> "NavigationNotCommitted"
+    PagePrerenderFinalStatusNavigationBadHttpStatus -> "NavigationBadHttpStatus"
+    PagePrerenderFinalStatusClientCertRequested -> "ClientCertRequested"
+    PagePrerenderFinalStatusNavigationRequestNetworkError -> "NavigationRequestNetworkError"
+    PagePrerenderFinalStatusMaxNumOfRunningPrerendersExceeded -> "MaxNumOfRunningPrerendersExceeded"
+    PagePrerenderFinalStatusCancelAllHostsForTesting -> "CancelAllHostsForTesting"
+    PagePrerenderFinalStatusDidFailLoad -> "DidFailLoad"
+    PagePrerenderFinalStatusStop -> "Stop"
+    PagePrerenderFinalStatusSslCertificateError -> "SslCertificateError"
+    PagePrerenderFinalStatusLoginAuthRequested -> "LoginAuthRequested"
+    PagePrerenderFinalStatusUaChangeRequiresReload -> "UaChangeRequiresReload"
+    PagePrerenderFinalStatusBlockedByClient -> "BlockedByClient"
+    PagePrerenderFinalStatusAudioOutputDeviceRequested -> "AudioOutputDeviceRequested"
+    PagePrerenderFinalStatusMixedContent -> "MixedContent"
+    PagePrerenderFinalStatusTriggerBackgrounded -> "TriggerBackgrounded"
+    PagePrerenderFinalStatusEmbedderTriggeredAndCrossOriginRedirected -> "EmbedderTriggeredAndCrossOriginRedirected"
+    PagePrerenderFinalStatusMemoryLimitExceeded -> "MemoryLimitExceeded"
+    PagePrerenderFinalStatusFailToGetMemoryUsage -> "FailToGetMemoryUsage"
+    PagePrerenderFinalStatusDataSaverEnabled -> "DataSaverEnabled"
+    PagePrerenderFinalStatusHasEffectiveUrl -> "HasEffectiveUrl"
+    PagePrerenderFinalStatusActivatedBeforeStarted -> "ActivatedBeforeStarted"
+    PagePrerenderFinalStatusInactivePageRestriction -> "InactivePageRestriction"
+    PagePrerenderFinalStatusStartFailed -> "StartFailed"
+    PagePrerenderFinalStatusTimeoutBackgrounded -> "TimeoutBackgrounded"
+
+-- | Type of the 'Page.domContentEventFired' event.
+data PageDomContentEventFired = PageDomContentEventFired
+  {
+    pageDomContentEventFiredTimestamp :: NetworkMonotonicTime
+  }
+  deriving (Eq, Show)
+instance FromJSON PageDomContentEventFired where
+  parseJSON = A.withObject "PageDomContentEventFired" $ \o -> PageDomContentEventFired
+    <$> o A..: "timestamp"
+instance Event PageDomContentEventFired where
+  eventName _ = "Page.domContentEventFired"
+
+-- | Type of the 'Page.fileChooserOpened' event.
+data PageFileChooserOpenedMode = PageFileChooserOpenedModeSelectSingle | PageFileChooserOpenedModeSelectMultiple
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PageFileChooserOpenedMode where
+  parseJSON = A.withText "PageFileChooserOpenedMode" $ \v -> case v of
+    "selectSingle" -> pure PageFileChooserOpenedModeSelectSingle
+    "selectMultiple" -> pure PageFileChooserOpenedModeSelectMultiple
+    "_" -> fail "failed to parse PageFileChooserOpenedMode"
+instance ToJSON PageFileChooserOpenedMode where
+  toJSON v = A.String $ case v of
+    PageFileChooserOpenedModeSelectSingle -> "selectSingle"
+    PageFileChooserOpenedModeSelectMultiple -> "selectMultiple"
+data PageFileChooserOpened = PageFileChooserOpened
+  {
+    -- | Id of the frame containing input node.
+    pageFileChooserOpenedFrameId :: PageFrameId,
+    -- | Input mode.
+    pageFileChooserOpenedMode :: PageFileChooserOpenedMode,
+    -- | Input node id. Only present for file choosers opened via an <input type="file"> element.
+    pageFileChooserOpenedBackendNodeId :: Maybe DOMBackendNodeId
+  }
+  deriving (Eq, Show)
+instance FromJSON PageFileChooserOpened where
+  parseJSON = A.withObject "PageFileChooserOpened" $ \o -> PageFileChooserOpened
+    <$> o A..: "frameId"
+    <*> o A..: "mode"
+    <*> o A..:? "backendNodeId"
+instance Event PageFileChooserOpened where
+  eventName _ = "Page.fileChooserOpened"
+
+-- | Type of the 'Page.frameAttached' event.
+data PageFrameAttached = PageFrameAttached
+  {
+    -- | Id of the frame that has been attached.
+    pageFrameAttachedFrameId :: PageFrameId,
+    -- | Parent frame identifier.
+    pageFrameAttachedParentFrameId :: PageFrameId,
+    -- | JavaScript stack trace of when frame was attached, only set if frame initiated from script.
+    pageFrameAttachedStack :: Maybe Runtime.RuntimeStackTrace
+  }
+  deriving (Eq, Show)
+instance FromJSON PageFrameAttached where
+  parseJSON = A.withObject "PageFrameAttached" $ \o -> PageFrameAttached
+    <$> o A..: "frameId"
+    <*> o A..: "parentFrameId"
+    <*> o A..:? "stack"
+instance Event PageFrameAttached where
+  eventName _ = "Page.frameAttached"
+
+-- | Type of the 'Page.frameDetached' event.
+data PageFrameDetachedReason = PageFrameDetachedReasonRemove | PageFrameDetachedReasonSwap
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PageFrameDetachedReason where
+  parseJSON = A.withText "PageFrameDetachedReason" $ \v -> case v of
+    "remove" -> pure PageFrameDetachedReasonRemove
+    "swap" -> pure PageFrameDetachedReasonSwap
+    "_" -> fail "failed to parse PageFrameDetachedReason"
+instance ToJSON PageFrameDetachedReason where
+  toJSON v = A.String $ case v of
+    PageFrameDetachedReasonRemove -> "remove"
+    PageFrameDetachedReasonSwap -> "swap"
+data PageFrameDetached = PageFrameDetached
+  {
+    -- | Id of the frame that has been detached.
+    pageFrameDetachedFrameId :: PageFrameId,
+    pageFrameDetachedReason :: PageFrameDetachedReason
+  }
+  deriving (Eq, Show)
+instance FromJSON PageFrameDetached where
+  parseJSON = A.withObject "PageFrameDetached" $ \o -> PageFrameDetached
+    <$> o A..: "frameId"
+    <*> o A..: "reason"
+instance Event PageFrameDetached where
+  eventName _ = "Page.frameDetached"
+
+-- | Type of the 'Page.frameNavigated' event.
+data PageFrameNavigated = PageFrameNavigated
+  {
+    -- | Frame object.
+    pageFrameNavigatedFrame :: PageFrame,
+    pageFrameNavigatedType :: PageNavigationType
+  }
+  deriving (Eq, Show)
+instance FromJSON PageFrameNavigated where
+  parseJSON = A.withObject "PageFrameNavigated" $ \o -> PageFrameNavigated
+    <$> o A..: "frame"
+    <*> o A..: "type"
+instance Event PageFrameNavigated where
+  eventName _ = "Page.frameNavigated"
+
+-- | Type of the 'Page.documentOpened' event.
+data PageDocumentOpened = PageDocumentOpened
+  {
+    -- | Frame object.
+    pageDocumentOpenedFrame :: PageFrame
+  }
+  deriving (Eq, Show)
+instance FromJSON PageDocumentOpened where
+  parseJSON = A.withObject "PageDocumentOpened" $ \o -> PageDocumentOpened
+    <$> o A..: "frame"
+instance Event PageDocumentOpened where
+  eventName _ = "Page.documentOpened"
+
+-- | Type of the 'Page.frameResized' event.
+data PageFrameResized = PageFrameResized
+  deriving (Eq, Show, Read)
+instance FromJSON PageFrameResized where
+  parseJSON _ = pure PageFrameResized
+instance Event PageFrameResized where
+  eventName _ = "Page.frameResized"
+
+-- | Type of the 'Page.frameRequestedNavigation' event.
+data PageFrameRequestedNavigation = PageFrameRequestedNavigation
+  {
+    -- | Id of the frame that is being navigated.
+    pageFrameRequestedNavigationFrameId :: PageFrameId,
+    -- | The reason for the navigation.
+    pageFrameRequestedNavigationReason :: PageClientNavigationReason,
+    -- | The destination URL for the requested navigation.
+    pageFrameRequestedNavigationUrl :: T.Text,
+    -- | The disposition for the navigation.
+    pageFrameRequestedNavigationDisposition :: PageClientNavigationDisposition
+  }
+  deriving (Eq, Show)
+instance FromJSON PageFrameRequestedNavigation where
+  parseJSON = A.withObject "PageFrameRequestedNavigation" $ \o -> PageFrameRequestedNavigation
+    <$> o A..: "frameId"
+    <*> o A..: "reason"
+    <*> o A..: "url"
+    <*> o A..: "disposition"
+instance Event PageFrameRequestedNavigation where
+  eventName _ = "Page.frameRequestedNavigation"
+
+-- | Type of the 'Page.frameStartedLoading' event.
+data PageFrameStartedLoading = PageFrameStartedLoading
+  {
+    -- | Id of the frame that has started loading.
+    pageFrameStartedLoadingFrameId :: PageFrameId
+  }
+  deriving (Eq, Show)
+instance FromJSON PageFrameStartedLoading where
+  parseJSON = A.withObject "PageFrameStartedLoading" $ \o -> PageFrameStartedLoading
+    <$> o A..: "frameId"
+instance Event PageFrameStartedLoading where
+  eventName _ = "Page.frameStartedLoading"
+
+-- | Type of the 'Page.frameStoppedLoading' event.
+data PageFrameStoppedLoading = PageFrameStoppedLoading
+  {
+    -- | Id of the frame that has stopped loading.
+    pageFrameStoppedLoadingFrameId :: PageFrameId
+  }
+  deriving (Eq, Show)
+instance FromJSON PageFrameStoppedLoading where
+  parseJSON = A.withObject "PageFrameStoppedLoading" $ \o -> PageFrameStoppedLoading
+    <$> o A..: "frameId"
+instance Event PageFrameStoppedLoading where
+  eventName _ = "Page.frameStoppedLoading"
+
+-- | Type of the 'Page.interstitialHidden' event.
+data PageInterstitialHidden = PageInterstitialHidden
+  deriving (Eq, Show, Read)
+instance FromJSON PageInterstitialHidden where
+  parseJSON _ = pure PageInterstitialHidden
+instance Event PageInterstitialHidden where
+  eventName _ = "Page.interstitialHidden"
+
+-- | Type of the 'Page.interstitialShown' event.
+data PageInterstitialShown = PageInterstitialShown
+  deriving (Eq, Show, Read)
+instance FromJSON PageInterstitialShown where
+  parseJSON _ = pure PageInterstitialShown
+instance Event PageInterstitialShown where
+  eventName _ = "Page.interstitialShown"
+
+-- | Type of the 'Page.javascriptDialogClosed' event.
+data PageJavascriptDialogClosed = PageJavascriptDialogClosed
+  {
+    -- | Whether dialog was confirmed.
+    pageJavascriptDialogClosedResult :: Bool,
+    -- | User input in case of prompt.
+    pageJavascriptDialogClosedUserInput :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON PageJavascriptDialogClosed where
+  parseJSON = A.withObject "PageJavascriptDialogClosed" $ \o -> PageJavascriptDialogClosed
+    <$> o A..: "result"
+    <*> o A..: "userInput"
+instance Event PageJavascriptDialogClosed where
+  eventName _ = "Page.javascriptDialogClosed"
+
+-- | Type of the 'Page.javascriptDialogOpening' event.
+data PageJavascriptDialogOpening = PageJavascriptDialogOpening
+  {
+    -- | Frame url.
+    pageJavascriptDialogOpeningUrl :: T.Text,
+    -- | Message that will be displayed by the dialog.
+    pageJavascriptDialogOpeningMessage :: T.Text,
+    -- | Dialog type.
+    pageJavascriptDialogOpeningType :: PageDialogType,
+    -- | True iff browser is capable showing or acting on the given dialog. When browser has no
+    --   dialog handler for given target, calling alert while Page domain is engaged will stall
+    --   the page execution. Execution can be resumed via calling Page.handleJavaScriptDialog.
+    pageJavascriptDialogOpeningHasBrowserHandler :: Bool,
+    -- | Default dialog prompt.
+    pageJavascriptDialogOpeningDefaultPrompt :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON PageJavascriptDialogOpening where
+  parseJSON = A.withObject "PageJavascriptDialogOpening" $ \o -> PageJavascriptDialogOpening
+    <$> o A..: "url"
+    <*> o A..: "message"
+    <*> o A..: "type"
+    <*> o A..: "hasBrowserHandler"
+    <*> o A..:? "defaultPrompt"
+instance Event PageJavascriptDialogOpening where
+  eventName _ = "Page.javascriptDialogOpening"
+
+-- | Type of the 'Page.lifecycleEvent' event.
+data PageLifecycleEvent = PageLifecycleEvent
+  {
+    -- | Id of the frame.
+    pageLifecycleEventFrameId :: PageFrameId,
+    -- | Loader identifier. Empty string if the request is fetched from worker.
+    pageLifecycleEventLoaderId :: NetworkLoaderId,
+    pageLifecycleEventName :: T.Text,
+    pageLifecycleEventTimestamp :: NetworkMonotonicTime
+  }
+  deriving (Eq, Show)
+instance FromJSON PageLifecycleEvent where
+  parseJSON = A.withObject "PageLifecycleEvent" $ \o -> PageLifecycleEvent
+    <$> o A..: "frameId"
+    <*> o A..: "loaderId"
+    <*> o A..: "name"
+    <*> o A..: "timestamp"
+instance Event PageLifecycleEvent where
+  eventName _ = "Page.lifecycleEvent"
+
+-- | Type of the 'Page.backForwardCacheNotUsed' event.
+data PageBackForwardCacheNotUsed = PageBackForwardCacheNotUsed
+  {
+    -- | The loader id for the associated navgation.
+    pageBackForwardCacheNotUsedLoaderId :: NetworkLoaderId,
+    -- | The frame id of the associated frame.
+    pageBackForwardCacheNotUsedFrameId :: PageFrameId,
+    -- | Array of reasons why the page could not be cached. This must not be empty.
+    pageBackForwardCacheNotUsedNotRestoredExplanations :: [PageBackForwardCacheNotRestoredExplanation],
+    -- | Tree structure of reasons why the page could not be cached for each frame.
+    pageBackForwardCacheNotUsedNotRestoredExplanationsTree :: Maybe PageBackForwardCacheNotRestoredExplanationTree
+  }
+  deriving (Eq, Show)
+instance FromJSON PageBackForwardCacheNotUsed where
+  parseJSON = A.withObject "PageBackForwardCacheNotUsed" $ \o -> PageBackForwardCacheNotUsed
+    <$> o A..: "loaderId"
+    <*> o A..: "frameId"
+    <*> o A..: "notRestoredExplanations"
+    <*> o A..:? "notRestoredExplanationsTree"
+instance Event PageBackForwardCacheNotUsed where
+  eventName _ = "Page.backForwardCacheNotUsed"
+
+-- | Type of the 'Page.prerenderAttemptCompleted' event.
+data PagePrerenderAttemptCompleted = PagePrerenderAttemptCompleted
+  {
+    -- | The frame id of the frame initiating prerendering.
+    pagePrerenderAttemptCompletedInitiatingFrameId :: PageFrameId,
+    pagePrerenderAttemptCompletedPrerenderingUrl :: T.Text,
+    pagePrerenderAttemptCompletedFinalStatus :: PagePrerenderFinalStatus,
+    -- | This is used to give users more information about the name of the API call
+    --   that is incompatible with prerender and has caused the cancellation of the attempt
+    pagePrerenderAttemptCompletedDisallowedApiMethod :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON PagePrerenderAttemptCompleted where
+  parseJSON = A.withObject "PagePrerenderAttemptCompleted" $ \o -> PagePrerenderAttemptCompleted
+    <$> o A..: "initiatingFrameId"
+    <*> o A..: "prerenderingUrl"
+    <*> o A..: "finalStatus"
+    <*> o A..:? "disallowedApiMethod"
+instance Event PagePrerenderAttemptCompleted where
+  eventName _ = "Page.prerenderAttemptCompleted"
+
+-- | Type of the 'Page.loadEventFired' event.
+data PageLoadEventFired = PageLoadEventFired
+  {
+    pageLoadEventFiredTimestamp :: NetworkMonotonicTime
+  }
+  deriving (Eq, Show)
+instance FromJSON PageLoadEventFired where
+  parseJSON = A.withObject "PageLoadEventFired" $ \o -> PageLoadEventFired
+    <$> o A..: "timestamp"
+instance Event PageLoadEventFired where
+  eventName _ = "Page.loadEventFired"
+
+-- | Type of the 'Page.navigatedWithinDocument' event.
+data PageNavigatedWithinDocument = PageNavigatedWithinDocument
+  {
+    -- | Id of the frame.
+    pageNavigatedWithinDocumentFrameId :: PageFrameId,
+    -- | Frame's new url.
+    pageNavigatedWithinDocumentUrl :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON PageNavigatedWithinDocument where
+  parseJSON = A.withObject "PageNavigatedWithinDocument" $ \o -> PageNavigatedWithinDocument
+    <$> o A..: "frameId"
+    <*> o A..: "url"
+instance Event PageNavigatedWithinDocument where
+  eventName _ = "Page.navigatedWithinDocument"
+
+-- | Type of the 'Page.screencastFrame' event.
+data PageScreencastFrame = PageScreencastFrame
+  {
+    -- | Base64-encoded compressed image. (Encoded as a base64 string when passed over JSON)
+    pageScreencastFrameData :: T.Text,
+    -- | Screencast frame metadata.
+    pageScreencastFrameMetadata :: PageScreencastFrameMetadata,
+    -- | Frame number.
+    pageScreencastFrameSessionId :: Int
+  }
+  deriving (Eq, Show)
+instance FromJSON PageScreencastFrame where
+  parseJSON = A.withObject "PageScreencastFrame" $ \o -> PageScreencastFrame
+    <$> o A..: "data"
+    <*> o A..: "metadata"
+    <*> o A..: "sessionId"
+instance Event PageScreencastFrame where
+  eventName _ = "Page.screencastFrame"
+
+-- | Type of the 'Page.screencastVisibilityChanged' event.
+data PageScreencastVisibilityChanged = PageScreencastVisibilityChanged
+  {
+    -- | True if the page is visible.
+    pageScreencastVisibilityChangedVisible :: Bool
+  }
+  deriving (Eq, Show)
+instance FromJSON PageScreencastVisibilityChanged where
+  parseJSON = A.withObject "PageScreencastVisibilityChanged" $ \o -> PageScreencastVisibilityChanged
+    <$> o A..: "visible"
+instance Event PageScreencastVisibilityChanged where
+  eventName _ = "Page.screencastVisibilityChanged"
+
+-- | Type of the 'Page.windowOpen' event.
+data PageWindowOpen = PageWindowOpen
+  {
+    -- | The URL for the new window.
+    pageWindowOpenUrl :: T.Text,
+    -- | Window name.
+    pageWindowOpenWindowName :: T.Text,
+    -- | An array of enabled window features.
+    pageWindowOpenWindowFeatures :: [T.Text],
+    -- | Whether or not it was triggered by user gesture.
+    pageWindowOpenUserGesture :: Bool
+  }
+  deriving (Eq, Show)
+instance FromJSON PageWindowOpen where
+  parseJSON = A.withObject "PageWindowOpen" $ \o -> PageWindowOpen
+    <$> o A..: "url"
+    <*> o A..: "windowName"
+    <*> o A..: "windowFeatures"
+    <*> o A..: "userGesture"
+instance Event PageWindowOpen where
+  eventName _ = "Page.windowOpen"
+
+-- | Type of the 'Page.compilationCacheProduced' event.
+data PageCompilationCacheProduced = PageCompilationCacheProduced
+  {
+    pageCompilationCacheProducedUrl :: T.Text,
+    -- | Base64-encoded data (Encoded as a base64 string when passed over JSON)
+    pageCompilationCacheProducedData :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON PageCompilationCacheProduced where
+  parseJSON = A.withObject "PageCompilationCacheProduced" $ \o -> PageCompilationCacheProduced
+    <$> o A..: "url"
+    <*> o A..: "data"
+instance Event PageCompilationCacheProduced where
+  eventName _ = "Page.compilationCacheProduced"
+
+-- | Evaluates given script in every frame upon creation (before loading frame's scripts).
+
+-- | Parameters of the 'Page.addScriptToEvaluateOnNewDocument' command.
+data PPageAddScriptToEvaluateOnNewDocument = PPageAddScriptToEvaluateOnNewDocument
+  {
+    pPageAddScriptToEvaluateOnNewDocumentSource :: T.Text,
+    -- | If specified, creates an isolated world with the given name and evaluates given script in it.
+    --   This world name will be used as the ExecutionContextDescription::name when the corresponding
+    --   event is emitted.
+    pPageAddScriptToEvaluateOnNewDocumentWorldName :: Maybe T.Text,
+    -- | Specifies whether command line API should be available to the script, defaults
+    --   to false.
+    pPageAddScriptToEvaluateOnNewDocumentIncludeCommandLineAPI :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pPageAddScriptToEvaluateOnNewDocument
+  :: T.Text
+  -> PPageAddScriptToEvaluateOnNewDocument
+pPageAddScriptToEvaluateOnNewDocument
+  arg_pPageAddScriptToEvaluateOnNewDocumentSource
+  = PPageAddScriptToEvaluateOnNewDocument
+    arg_pPageAddScriptToEvaluateOnNewDocumentSource
+    Nothing
+    Nothing
+instance ToJSON PPageAddScriptToEvaluateOnNewDocument where
+  toJSON p = A.object $ catMaybes [
+    ("source" A..=) <$> Just (pPageAddScriptToEvaluateOnNewDocumentSource p),
+    ("worldName" A..=) <$> (pPageAddScriptToEvaluateOnNewDocumentWorldName p),
+    ("includeCommandLineAPI" A..=) <$> (pPageAddScriptToEvaluateOnNewDocumentIncludeCommandLineAPI p)
+    ]
+data PageAddScriptToEvaluateOnNewDocument = PageAddScriptToEvaluateOnNewDocument
+  {
+    -- | Identifier of the added script.
+    pageAddScriptToEvaluateOnNewDocumentIdentifier :: PageScriptIdentifier
+  }
+  deriving (Eq, Show)
+instance FromJSON PageAddScriptToEvaluateOnNewDocument where
+  parseJSON = A.withObject "PageAddScriptToEvaluateOnNewDocument" $ \o -> PageAddScriptToEvaluateOnNewDocument
+    <$> o A..: "identifier"
+instance Command PPageAddScriptToEvaluateOnNewDocument where
+  type CommandResponse PPageAddScriptToEvaluateOnNewDocument = PageAddScriptToEvaluateOnNewDocument
+  commandName _ = "Page.addScriptToEvaluateOnNewDocument"
+
+-- | Brings page to front (activates tab).
+
+-- | Parameters of the 'Page.bringToFront' command.
+data PPageBringToFront = PPageBringToFront
+  deriving (Eq, Show)
+pPageBringToFront
+  :: PPageBringToFront
+pPageBringToFront
+  = PPageBringToFront
+instance ToJSON PPageBringToFront where
+  toJSON _ = A.Null
+instance Command PPageBringToFront where
+  type CommandResponse PPageBringToFront = ()
+  commandName _ = "Page.bringToFront"
+  fromJSON = const . A.Success . const ()
+
+-- | Capture page screenshot.
+
+-- | Parameters of the 'Page.captureScreenshot' command.
+data PPageCaptureScreenshotFormat = PPageCaptureScreenshotFormatJpeg | PPageCaptureScreenshotFormatPng | PPageCaptureScreenshotFormatWebp
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PPageCaptureScreenshotFormat where
+  parseJSON = A.withText "PPageCaptureScreenshotFormat" $ \v -> case v of
+    "jpeg" -> pure PPageCaptureScreenshotFormatJpeg
+    "png" -> pure PPageCaptureScreenshotFormatPng
+    "webp" -> pure PPageCaptureScreenshotFormatWebp
+    "_" -> fail "failed to parse PPageCaptureScreenshotFormat"
+instance ToJSON PPageCaptureScreenshotFormat where
+  toJSON v = A.String $ case v of
+    PPageCaptureScreenshotFormatJpeg -> "jpeg"
+    PPageCaptureScreenshotFormatPng -> "png"
+    PPageCaptureScreenshotFormatWebp -> "webp"
+data PPageCaptureScreenshot = PPageCaptureScreenshot
+  {
+    -- | Image compression format (defaults to png).
+    pPageCaptureScreenshotFormat :: Maybe PPageCaptureScreenshotFormat,
+    -- | Compression quality from range [0..100] (jpeg only).
+    pPageCaptureScreenshotQuality :: Maybe Int,
+    -- | Capture the screenshot of a given region only.
+    pPageCaptureScreenshotClip :: Maybe PageViewport,
+    -- | Capture the screenshot from the surface, rather than the view. Defaults to true.
+    pPageCaptureScreenshotFromSurface :: Maybe Bool,
+    -- | Capture the screenshot beyond the viewport. Defaults to false.
+    pPageCaptureScreenshotCaptureBeyondViewport :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pPageCaptureScreenshot
+  :: PPageCaptureScreenshot
+pPageCaptureScreenshot
+  = PPageCaptureScreenshot
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PPageCaptureScreenshot where
+  toJSON p = A.object $ catMaybes [
+    ("format" A..=) <$> (pPageCaptureScreenshotFormat p),
+    ("quality" A..=) <$> (pPageCaptureScreenshotQuality p),
+    ("clip" A..=) <$> (pPageCaptureScreenshotClip p),
+    ("fromSurface" A..=) <$> (pPageCaptureScreenshotFromSurface p),
+    ("captureBeyondViewport" A..=) <$> (pPageCaptureScreenshotCaptureBeyondViewport p)
+    ]
+data PageCaptureScreenshot = PageCaptureScreenshot
+  {
+    -- | Base64-encoded image data. (Encoded as a base64 string when passed over JSON)
+    pageCaptureScreenshotData :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON PageCaptureScreenshot where
+  parseJSON = A.withObject "PageCaptureScreenshot" $ \o -> PageCaptureScreenshot
+    <$> o A..: "data"
+instance Command PPageCaptureScreenshot where
+  type CommandResponse PPageCaptureScreenshot = PageCaptureScreenshot
+  commandName _ = "Page.captureScreenshot"
+
+-- | Returns a snapshot of the page as a string. For MHTML format, the serialization includes
+--   iframes, shadow DOM, external resources, and element-inline styles.
+
+-- | Parameters of the 'Page.captureSnapshot' command.
+data PPageCaptureSnapshotFormat = PPageCaptureSnapshotFormatMhtml
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PPageCaptureSnapshotFormat where
+  parseJSON = A.withText "PPageCaptureSnapshotFormat" $ \v -> case v of
+    "mhtml" -> pure PPageCaptureSnapshotFormatMhtml
+    "_" -> fail "failed to parse PPageCaptureSnapshotFormat"
+instance ToJSON PPageCaptureSnapshotFormat where
+  toJSON v = A.String $ case v of
+    PPageCaptureSnapshotFormatMhtml -> "mhtml"
+data PPageCaptureSnapshot = PPageCaptureSnapshot
+  {
+    -- | Format (defaults to mhtml).
+    pPageCaptureSnapshotFormat :: Maybe PPageCaptureSnapshotFormat
+  }
+  deriving (Eq, Show)
+pPageCaptureSnapshot
+  :: PPageCaptureSnapshot
+pPageCaptureSnapshot
+  = PPageCaptureSnapshot
+    Nothing
+instance ToJSON PPageCaptureSnapshot where
+  toJSON p = A.object $ catMaybes [
+    ("format" A..=) <$> (pPageCaptureSnapshotFormat p)
+    ]
+data PageCaptureSnapshot = PageCaptureSnapshot
+  {
+    -- | Serialized page data.
+    pageCaptureSnapshotData :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON PageCaptureSnapshot where
+  parseJSON = A.withObject "PageCaptureSnapshot" $ \o -> PageCaptureSnapshot
+    <$> o A..: "data"
+instance Command PPageCaptureSnapshot where
+  type CommandResponse PPageCaptureSnapshot = PageCaptureSnapshot
+  commandName _ = "Page.captureSnapshot"
+
+-- | Creates an isolated world for the given frame.
+
+-- | Parameters of the 'Page.createIsolatedWorld' command.
+data PPageCreateIsolatedWorld = PPageCreateIsolatedWorld
+  {
+    -- | Id of the frame in which the isolated world should be created.
+    pPageCreateIsolatedWorldFrameId :: PageFrameId,
+    -- | An optional name which is reported in the Execution Context.
+    pPageCreateIsolatedWorldWorldName :: Maybe T.Text,
+    -- | Whether or not universal access should be granted to the isolated world. This is a powerful
+    --   option, use with caution.
+    pPageCreateIsolatedWorldGrantUniveralAccess :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pPageCreateIsolatedWorld
+  {-
+  -- | Id of the frame in which the isolated world should be created.
+  -}
+  :: PageFrameId
+  -> PPageCreateIsolatedWorld
+pPageCreateIsolatedWorld
+  arg_pPageCreateIsolatedWorldFrameId
+  = PPageCreateIsolatedWorld
+    arg_pPageCreateIsolatedWorldFrameId
+    Nothing
+    Nothing
+instance ToJSON PPageCreateIsolatedWorld where
+  toJSON p = A.object $ catMaybes [
+    ("frameId" A..=) <$> Just (pPageCreateIsolatedWorldFrameId p),
+    ("worldName" A..=) <$> (pPageCreateIsolatedWorldWorldName p),
+    ("grantUniveralAccess" A..=) <$> (pPageCreateIsolatedWorldGrantUniveralAccess p)
+    ]
+data PageCreateIsolatedWorld = PageCreateIsolatedWorld
+  {
+    -- | Execution context of the isolated world.
+    pageCreateIsolatedWorldExecutionContextId :: Runtime.RuntimeExecutionContextId
+  }
+  deriving (Eq, Show)
+instance FromJSON PageCreateIsolatedWorld where
+  parseJSON = A.withObject "PageCreateIsolatedWorld" $ \o -> PageCreateIsolatedWorld
+    <$> o A..: "executionContextId"
+instance Command PPageCreateIsolatedWorld where
+  type CommandResponse PPageCreateIsolatedWorld = PageCreateIsolatedWorld
+  commandName _ = "Page.createIsolatedWorld"
+
+-- | Disables page domain notifications.
+
+-- | Parameters of the 'Page.disable' command.
+data PPageDisable = PPageDisable
+  deriving (Eq, Show)
+pPageDisable
+  :: PPageDisable
+pPageDisable
+  = PPageDisable
+instance ToJSON PPageDisable where
+  toJSON _ = A.Null
+instance Command PPageDisable where
+  type CommandResponse PPageDisable = ()
+  commandName _ = "Page.disable"
+  fromJSON = const . A.Success . const ()
+
+-- | Enables page domain notifications.
+
+-- | Parameters of the 'Page.enable' command.
+data PPageEnable = PPageEnable
+  deriving (Eq, Show)
+pPageEnable
+  :: PPageEnable
+pPageEnable
+  = PPageEnable
+instance ToJSON PPageEnable where
+  toJSON _ = A.Null
+instance Command PPageEnable where
+  type CommandResponse PPageEnable = ()
+  commandName _ = "Page.enable"
+  fromJSON = const . A.Success . const ()
+
+
+-- | Parameters of the 'Page.getAppManifest' command.
+data PPageGetAppManifest = PPageGetAppManifest
+  deriving (Eq, Show)
+pPageGetAppManifest
+  :: PPageGetAppManifest
+pPageGetAppManifest
+  = PPageGetAppManifest
+instance ToJSON PPageGetAppManifest where
+  toJSON _ = A.Null
+data PageGetAppManifest = PageGetAppManifest
+  {
+    -- | Manifest location.
+    pageGetAppManifestUrl :: T.Text,
+    pageGetAppManifestErrors :: [PageAppManifestError],
+    -- | Manifest content.
+    pageGetAppManifestData :: Maybe T.Text,
+    -- | Parsed manifest properties
+    pageGetAppManifestParsed :: Maybe PageAppManifestParsedProperties
+  }
+  deriving (Eq, Show)
+instance FromJSON PageGetAppManifest where
+  parseJSON = A.withObject "PageGetAppManifest" $ \o -> PageGetAppManifest
+    <$> o A..: "url"
+    <*> o A..: "errors"
+    <*> o A..:? "data"
+    <*> o A..:? "parsed"
+instance Command PPageGetAppManifest where
+  type CommandResponse PPageGetAppManifest = PageGetAppManifest
+  commandName _ = "Page.getAppManifest"
+
+
+-- | Parameters of the 'Page.getInstallabilityErrors' command.
+data PPageGetInstallabilityErrors = PPageGetInstallabilityErrors
+  deriving (Eq, Show)
+pPageGetInstallabilityErrors
+  :: PPageGetInstallabilityErrors
+pPageGetInstallabilityErrors
+  = PPageGetInstallabilityErrors
+instance ToJSON PPageGetInstallabilityErrors where
+  toJSON _ = A.Null
+data PageGetInstallabilityErrors = PageGetInstallabilityErrors
+  {
+    pageGetInstallabilityErrorsInstallabilityErrors :: [PageInstallabilityError]
+  }
+  deriving (Eq, Show)
+instance FromJSON PageGetInstallabilityErrors where
+  parseJSON = A.withObject "PageGetInstallabilityErrors" $ \o -> PageGetInstallabilityErrors
+    <$> o A..: "installabilityErrors"
+instance Command PPageGetInstallabilityErrors where
+  type CommandResponse PPageGetInstallabilityErrors = PageGetInstallabilityErrors
+  commandName _ = "Page.getInstallabilityErrors"
+
+
+-- | Parameters of the 'Page.getManifestIcons' command.
+data PPageGetManifestIcons = PPageGetManifestIcons
+  deriving (Eq, Show)
+pPageGetManifestIcons
+  :: PPageGetManifestIcons
+pPageGetManifestIcons
+  = PPageGetManifestIcons
+instance ToJSON PPageGetManifestIcons where
+  toJSON _ = A.Null
+data PageGetManifestIcons = PageGetManifestIcons
+  {
+    pageGetManifestIconsPrimaryIcon :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON PageGetManifestIcons where
+  parseJSON = A.withObject "PageGetManifestIcons" $ \o -> PageGetManifestIcons
+    <$> o A..:? "primaryIcon"
+instance Command PPageGetManifestIcons where
+  type CommandResponse PPageGetManifestIcons = PageGetManifestIcons
+  commandName _ = "Page.getManifestIcons"
+
+-- | Returns the unique (PWA) app id.
+--   Only returns values if the feature flag 'WebAppEnableManifestId' is enabled
+
+-- | Parameters of the 'Page.getAppId' command.
+data PPageGetAppId = PPageGetAppId
+  deriving (Eq, Show)
+pPageGetAppId
+  :: PPageGetAppId
+pPageGetAppId
+  = PPageGetAppId
+instance ToJSON PPageGetAppId where
+  toJSON _ = A.Null
+data PageGetAppId = PageGetAppId
+  {
+    -- | App id, either from manifest's id attribute or computed from start_url
+    pageGetAppIdAppId :: Maybe T.Text,
+    -- | Recommendation for manifest's id attribute to match current id computed from start_url
+    pageGetAppIdRecommendedId :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON PageGetAppId where
+  parseJSON = A.withObject "PageGetAppId" $ \o -> PageGetAppId
+    <$> o A..:? "appId"
+    <*> o A..:? "recommendedId"
+instance Command PPageGetAppId where
+  type CommandResponse PPageGetAppId = PageGetAppId
+  commandName _ = "Page.getAppId"
+
+
+-- | Parameters of the 'Page.getAdScriptId' command.
+data PPageGetAdScriptId = PPageGetAdScriptId
+  {
+    pPageGetAdScriptIdFrameId :: PageFrameId
+  }
+  deriving (Eq, Show)
+pPageGetAdScriptId
+  :: PageFrameId
+  -> PPageGetAdScriptId
+pPageGetAdScriptId
+  arg_pPageGetAdScriptIdFrameId
+  = PPageGetAdScriptId
+    arg_pPageGetAdScriptIdFrameId
+instance ToJSON PPageGetAdScriptId where
+  toJSON p = A.object $ catMaybes [
+    ("frameId" A..=) <$> Just (pPageGetAdScriptIdFrameId p)
+    ]
+data PageGetAdScriptId = PageGetAdScriptId
+  {
+    -- | Identifies the bottom-most script which caused the frame to be labelled
+    --   as an ad. Only sent if frame is labelled as an ad and id is available.
+    pageGetAdScriptIdAdScriptId :: Maybe PageAdScriptId
+  }
+  deriving (Eq, Show)
+instance FromJSON PageGetAdScriptId where
+  parseJSON = A.withObject "PageGetAdScriptId" $ \o -> PageGetAdScriptId
+    <$> o A..:? "adScriptId"
+instance Command PPageGetAdScriptId where
+  type CommandResponse PPageGetAdScriptId = PageGetAdScriptId
+  commandName _ = "Page.getAdScriptId"
+
+-- | Returns present frame tree structure.
+
+-- | Parameters of the 'Page.getFrameTree' command.
+data PPageGetFrameTree = PPageGetFrameTree
+  deriving (Eq, Show)
+pPageGetFrameTree
+  :: PPageGetFrameTree
+pPageGetFrameTree
+  = PPageGetFrameTree
+instance ToJSON PPageGetFrameTree where
+  toJSON _ = A.Null
+data PageGetFrameTree = PageGetFrameTree
+  {
+    -- | Present frame tree structure.
+    pageGetFrameTreeFrameTree :: PageFrameTree
+  }
+  deriving (Eq, Show)
+instance FromJSON PageGetFrameTree where
+  parseJSON = A.withObject "PageGetFrameTree" $ \o -> PageGetFrameTree
+    <$> o A..: "frameTree"
+instance Command PPageGetFrameTree where
+  type CommandResponse PPageGetFrameTree = PageGetFrameTree
+  commandName _ = "Page.getFrameTree"
+
+-- | Returns metrics relating to the layouting of the page, such as viewport bounds/scale.
+
+-- | Parameters of the 'Page.getLayoutMetrics' command.
+data PPageGetLayoutMetrics = PPageGetLayoutMetrics
+  deriving (Eq, Show)
+pPageGetLayoutMetrics
+  :: PPageGetLayoutMetrics
+pPageGetLayoutMetrics
+  = PPageGetLayoutMetrics
+instance ToJSON PPageGetLayoutMetrics where
+  toJSON _ = A.Null
+data PageGetLayoutMetrics = PageGetLayoutMetrics
+  {
+    -- | Metrics relating to the layout viewport in CSS pixels.
+    pageGetLayoutMetricsCssLayoutViewport :: PageLayoutViewport,
+    -- | Metrics relating to the visual viewport in CSS pixels.
+    pageGetLayoutMetricsCssVisualViewport :: PageVisualViewport,
+    -- | Size of scrollable area in CSS pixels.
+    pageGetLayoutMetricsCssContentSize :: DOMRect
+  }
+  deriving (Eq, Show)
+instance FromJSON PageGetLayoutMetrics where
+  parseJSON = A.withObject "PageGetLayoutMetrics" $ \o -> PageGetLayoutMetrics
+    <$> o A..: "cssLayoutViewport"
+    <*> o A..: "cssVisualViewport"
+    <*> o A..: "cssContentSize"
+instance Command PPageGetLayoutMetrics where
+  type CommandResponse PPageGetLayoutMetrics = PageGetLayoutMetrics
+  commandName _ = "Page.getLayoutMetrics"
+
+-- | Returns navigation history for the current page.
+
+-- | Parameters of the 'Page.getNavigationHistory' command.
+data PPageGetNavigationHistory = PPageGetNavigationHistory
+  deriving (Eq, Show)
+pPageGetNavigationHistory
+  :: PPageGetNavigationHistory
+pPageGetNavigationHistory
+  = PPageGetNavigationHistory
+instance ToJSON PPageGetNavigationHistory where
+  toJSON _ = A.Null
+data PageGetNavigationHistory = PageGetNavigationHistory
+  {
+    -- | Index of the current navigation history entry.
+    pageGetNavigationHistoryCurrentIndex :: Int,
+    -- | Array of navigation history entries.
+    pageGetNavigationHistoryEntries :: [PageNavigationEntry]
+  }
+  deriving (Eq, Show)
+instance FromJSON PageGetNavigationHistory where
+  parseJSON = A.withObject "PageGetNavigationHistory" $ \o -> PageGetNavigationHistory
+    <$> o A..: "currentIndex"
+    <*> o A..: "entries"
+instance Command PPageGetNavigationHistory where
+  type CommandResponse PPageGetNavigationHistory = PageGetNavigationHistory
+  commandName _ = "Page.getNavigationHistory"
+
+-- | Resets navigation history for the current page.
+
+-- | Parameters of the 'Page.resetNavigationHistory' command.
+data PPageResetNavigationHistory = PPageResetNavigationHistory
+  deriving (Eq, Show)
+pPageResetNavigationHistory
+  :: PPageResetNavigationHistory
+pPageResetNavigationHistory
+  = PPageResetNavigationHistory
+instance ToJSON PPageResetNavigationHistory where
+  toJSON _ = A.Null
+instance Command PPageResetNavigationHistory where
+  type CommandResponse PPageResetNavigationHistory = ()
+  commandName _ = "Page.resetNavigationHistory"
+  fromJSON = const . A.Success . const ()
+
+-- | Returns content of the given resource.
+
+-- | Parameters of the 'Page.getResourceContent' command.
+data PPageGetResourceContent = PPageGetResourceContent
+  {
+    -- | Frame id to get resource for.
+    pPageGetResourceContentFrameId :: PageFrameId,
+    -- | URL of the resource to get content for.
+    pPageGetResourceContentUrl :: T.Text
+  }
+  deriving (Eq, Show)
+pPageGetResourceContent
+  {-
+  -- | Frame id to get resource for.
+  -}
+  :: PageFrameId
+  {-
+  -- | URL of the resource to get content for.
+  -}
+  -> T.Text
+  -> PPageGetResourceContent
+pPageGetResourceContent
+  arg_pPageGetResourceContentFrameId
+  arg_pPageGetResourceContentUrl
+  = PPageGetResourceContent
+    arg_pPageGetResourceContentFrameId
+    arg_pPageGetResourceContentUrl
+instance ToJSON PPageGetResourceContent where
+  toJSON p = A.object $ catMaybes [
+    ("frameId" A..=) <$> Just (pPageGetResourceContentFrameId p),
+    ("url" A..=) <$> Just (pPageGetResourceContentUrl p)
+    ]
+data PageGetResourceContent = PageGetResourceContent
+  {
+    -- | Resource content.
+    pageGetResourceContentContent :: T.Text,
+    -- | True, if content was served as base64.
+    pageGetResourceContentBase64Encoded :: Bool
+  }
+  deriving (Eq, Show)
+instance FromJSON PageGetResourceContent where
+  parseJSON = A.withObject "PageGetResourceContent" $ \o -> PageGetResourceContent
+    <$> o A..: "content"
+    <*> o A..: "base64Encoded"
+instance Command PPageGetResourceContent where
+  type CommandResponse PPageGetResourceContent = PageGetResourceContent
+  commandName _ = "Page.getResourceContent"
+
+-- | Returns present frame / resource tree structure.
+
+-- | Parameters of the 'Page.getResourceTree' command.
+data PPageGetResourceTree = PPageGetResourceTree
+  deriving (Eq, Show)
+pPageGetResourceTree
+  :: PPageGetResourceTree
+pPageGetResourceTree
+  = PPageGetResourceTree
+instance ToJSON PPageGetResourceTree where
+  toJSON _ = A.Null
+data PageGetResourceTree = PageGetResourceTree
+  {
+    -- | Present frame / resource tree structure.
+    pageGetResourceTreeFrameTree :: PageFrameResourceTree
+  }
+  deriving (Eq, Show)
+instance FromJSON PageGetResourceTree where
+  parseJSON = A.withObject "PageGetResourceTree" $ \o -> PageGetResourceTree
+    <$> o A..: "frameTree"
+instance Command PPageGetResourceTree where
+  type CommandResponse PPageGetResourceTree = PageGetResourceTree
+  commandName _ = "Page.getResourceTree"
+
+-- | Accepts or dismisses a JavaScript initiated dialog (alert, confirm, prompt, or onbeforeunload).
+
+-- | Parameters of the 'Page.handleJavaScriptDialog' command.
+data PPageHandleJavaScriptDialog = PPageHandleJavaScriptDialog
+  {
+    -- | Whether to accept or dismiss the dialog.
+    pPageHandleJavaScriptDialogAccept :: Bool,
+    -- | The text to enter into the dialog prompt before accepting. Used only if this is a prompt
+    --   dialog.
+    pPageHandleJavaScriptDialogPromptText :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+pPageHandleJavaScriptDialog
+  {-
+  -- | Whether to accept or dismiss the dialog.
+  -}
+  :: Bool
+  -> PPageHandleJavaScriptDialog
+pPageHandleJavaScriptDialog
+  arg_pPageHandleJavaScriptDialogAccept
+  = PPageHandleJavaScriptDialog
+    arg_pPageHandleJavaScriptDialogAccept
+    Nothing
+instance ToJSON PPageHandleJavaScriptDialog where
+  toJSON p = A.object $ catMaybes [
+    ("accept" A..=) <$> Just (pPageHandleJavaScriptDialogAccept p),
+    ("promptText" A..=) <$> (pPageHandleJavaScriptDialogPromptText p)
+    ]
+instance Command PPageHandleJavaScriptDialog where
+  type CommandResponse PPageHandleJavaScriptDialog = ()
+  commandName _ = "Page.handleJavaScriptDialog"
+  fromJSON = const . A.Success . const ()
+
+-- | Navigates current page to the given URL.
+
+-- | Parameters of the 'Page.navigate' command.
+data PPageNavigate = PPageNavigate
+  {
+    -- | URL to navigate the page to.
+    pPageNavigateUrl :: T.Text,
+    -- | Referrer URL.
+    pPageNavigateReferrer :: Maybe T.Text,
+    -- | Intended transition type.
+    pPageNavigateTransitionType :: Maybe PageTransitionType,
+    -- | Frame id to navigate, if not specified navigates the top frame.
+    pPageNavigateFrameId :: Maybe PageFrameId,
+    -- | Referrer-policy used for the navigation.
+    pPageNavigateReferrerPolicy :: Maybe PageReferrerPolicy
+  }
+  deriving (Eq, Show)
+pPageNavigate
+  {-
+  -- | URL to navigate the page to.
+  -}
+  :: T.Text
+  -> PPageNavigate
+pPageNavigate
+  arg_pPageNavigateUrl
+  = PPageNavigate
+    arg_pPageNavigateUrl
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PPageNavigate where
+  toJSON p = A.object $ catMaybes [
+    ("url" A..=) <$> Just (pPageNavigateUrl p),
+    ("referrer" A..=) <$> (pPageNavigateReferrer p),
+    ("transitionType" A..=) <$> (pPageNavigateTransitionType p),
+    ("frameId" A..=) <$> (pPageNavigateFrameId p),
+    ("referrerPolicy" A..=) <$> (pPageNavigateReferrerPolicy p)
+    ]
+data PageNavigate = PageNavigate
+  {
+    -- | Frame id that has navigated (or failed to navigate)
+    pageNavigateFrameId :: PageFrameId,
+    -- | Loader identifier. This is omitted in case of same-document navigation,
+    --   as the previously committed loaderId would not change.
+    pageNavigateLoaderId :: Maybe NetworkLoaderId,
+    -- | User friendly error message, present if and only if navigation has failed.
+    pageNavigateErrorText :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON PageNavigate where
+  parseJSON = A.withObject "PageNavigate" $ \o -> PageNavigate
+    <$> o A..: "frameId"
+    <*> o A..:? "loaderId"
+    <*> o A..:? "errorText"
+instance Command PPageNavigate where
+  type CommandResponse PPageNavigate = PageNavigate
+  commandName _ = "Page.navigate"
+
+-- | Navigates current page to the given history entry.
+
+-- | Parameters of the 'Page.navigateToHistoryEntry' command.
+data PPageNavigateToHistoryEntry = PPageNavigateToHistoryEntry
+  {
+    -- | Unique id of the entry to navigate to.
+    pPageNavigateToHistoryEntryEntryId :: Int
+  }
+  deriving (Eq, Show)
+pPageNavigateToHistoryEntry
+  {-
+  -- | Unique id of the entry to navigate to.
+  -}
+  :: Int
+  -> PPageNavigateToHistoryEntry
+pPageNavigateToHistoryEntry
+  arg_pPageNavigateToHistoryEntryEntryId
+  = PPageNavigateToHistoryEntry
+    arg_pPageNavigateToHistoryEntryEntryId
+instance ToJSON PPageNavigateToHistoryEntry where
+  toJSON p = A.object $ catMaybes [
+    ("entryId" A..=) <$> Just (pPageNavigateToHistoryEntryEntryId p)
+    ]
+instance Command PPageNavigateToHistoryEntry where
+  type CommandResponse PPageNavigateToHistoryEntry = ()
+  commandName _ = "Page.navigateToHistoryEntry"
+  fromJSON = const . A.Success . const ()
+
+-- | Print page as PDF.
+
+-- | Parameters of the 'Page.printToPDF' command.
+data PPagePrintToPDFTransferMode = PPagePrintToPDFTransferModeReturnAsBase64 | PPagePrintToPDFTransferModeReturnAsStream
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PPagePrintToPDFTransferMode where
+  parseJSON = A.withText "PPagePrintToPDFTransferMode" $ \v -> case v of
+    "ReturnAsBase64" -> pure PPagePrintToPDFTransferModeReturnAsBase64
+    "ReturnAsStream" -> pure PPagePrintToPDFTransferModeReturnAsStream
+    "_" -> fail "failed to parse PPagePrintToPDFTransferMode"
+instance ToJSON PPagePrintToPDFTransferMode where
+  toJSON v = A.String $ case v of
+    PPagePrintToPDFTransferModeReturnAsBase64 -> "ReturnAsBase64"
+    PPagePrintToPDFTransferModeReturnAsStream -> "ReturnAsStream"
+data PPagePrintToPDF = PPagePrintToPDF
+  {
+    -- | Paper orientation. Defaults to false.
+    pPagePrintToPDFLandscape :: Maybe Bool,
+    -- | Display header and footer. Defaults to false.
+    pPagePrintToPDFDisplayHeaderFooter :: Maybe Bool,
+    -- | Print background graphics. Defaults to false.
+    pPagePrintToPDFPrintBackground :: Maybe Bool,
+    -- | Scale of the webpage rendering. Defaults to 1.
+    pPagePrintToPDFScale :: Maybe Double,
+    -- | Paper width in inches. Defaults to 8.5 inches.
+    pPagePrintToPDFPaperWidth :: Maybe Double,
+    -- | Paper height in inches. Defaults to 11 inches.
+    pPagePrintToPDFPaperHeight :: Maybe Double,
+    -- | Top margin in inches. Defaults to 1cm (~0.4 inches).
+    pPagePrintToPDFMarginTop :: Maybe Double,
+    -- | Bottom margin in inches. Defaults to 1cm (~0.4 inches).
+    pPagePrintToPDFMarginBottom :: Maybe Double,
+    -- | Left margin in inches. Defaults to 1cm (~0.4 inches).
+    pPagePrintToPDFMarginLeft :: Maybe Double,
+    -- | Right margin in inches. Defaults to 1cm (~0.4 inches).
+    pPagePrintToPDFMarginRight :: Maybe Double,
+    -- | Paper ranges to print, one based, e.g., '1-5, 8, 11-13'. Pages are
+    --   printed in the document order, not in the order specified, and no
+    --   more than once.
+    --   Defaults to empty string, which implies the entire document is printed.
+    --   The page numbers are quietly capped to actual page count of the
+    --   document, and ranges beyond the end of the document are ignored.
+    --   If this results in no pages to print, an error is reported.
+    --   It is an error to specify a range with start greater than end.
+    pPagePrintToPDFPageRanges :: Maybe T.Text,
+    -- | HTML template for the print header. Should be valid HTML markup with following
+    --   classes used to inject printing values into them:
+    --   - `date`: formatted print date
+    --   - `title`: document title
+    --   - `url`: document location
+    --   - `pageNumber`: current page number
+    --   - `totalPages`: total pages in the document
+    --   
+    --   For example, `<span class=title></span>` would generate span containing the title.
+    pPagePrintToPDFHeaderTemplate :: Maybe T.Text,
+    -- | HTML template for the print footer. Should use the same format as the `headerTemplate`.
+    pPagePrintToPDFFooterTemplate :: Maybe T.Text,
+    -- | Whether or not to prefer page size as defined by css. Defaults to false,
+    --   in which case the content will be scaled to fit the paper size.
+    pPagePrintToPDFPreferCSSPageSize :: Maybe Bool,
+    -- | return as stream
+    pPagePrintToPDFTransferMode :: Maybe PPagePrintToPDFTransferMode
+  }
+  deriving (Eq, Show)
+pPagePrintToPDF
+  :: PPagePrintToPDF
+pPagePrintToPDF
+  = PPagePrintToPDF
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PPagePrintToPDF where
+  toJSON p = A.object $ catMaybes [
+    ("landscape" A..=) <$> (pPagePrintToPDFLandscape p),
+    ("displayHeaderFooter" A..=) <$> (pPagePrintToPDFDisplayHeaderFooter p),
+    ("printBackground" A..=) <$> (pPagePrintToPDFPrintBackground p),
+    ("scale" A..=) <$> (pPagePrintToPDFScale p),
+    ("paperWidth" A..=) <$> (pPagePrintToPDFPaperWidth p),
+    ("paperHeight" A..=) <$> (pPagePrintToPDFPaperHeight p),
+    ("marginTop" A..=) <$> (pPagePrintToPDFMarginTop p),
+    ("marginBottom" A..=) <$> (pPagePrintToPDFMarginBottom p),
+    ("marginLeft" A..=) <$> (pPagePrintToPDFMarginLeft p),
+    ("marginRight" A..=) <$> (pPagePrintToPDFMarginRight p),
+    ("pageRanges" A..=) <$> (pPagePrintToPDFPageRanges p),
+    ("headerTemplate" A..=) <$> (pPagePrintToPDFHeaderTemplate p),
+    ("footerTemplate" A..=) <$> (pPagePrintToPDFFooterTemplate p),
+    ("preferCSSPageSize" A..=) <$> (pPagePrintToPDFPreferCSSPageSize p),
+    ("transferMode" A..=) <$> (pPagePrintToPDFTransferMode p)
+    ]
+data PagePrintToPDF = PagePrintToPDF
+  {
+    -- | Base64-encoded pdf data. Empty if |returnAsStream| is specified. (Encoded as a base64 string when passed over JSON)
+    pagePrintToPDFData :: T.Text,
+    -- | A handle of the stream that holds resulting PDF data.
+    pagePrintToPDFStream :: Maybe IO.IOStreamHandle
+  }
+  deriving (Eq, Show)
+instance FromJSON PagePrintToPDF where
+  parseJSON = A.withObject "PagePrintToPDF" $ \o -> PagePrintToPDF
+    <$> o A..: "data"
+    <*> o A..:? "stream"
+instance Command PPagePrintToPDF where
+  type CommandResponse PPagePrintToPDF = PagePrintToPDF
+  commandName _ = "Page.printToPDF"
+
+-- | Reloads given page optionally ignoring the cache.
+
+-- | Parameters of the 'Page.reload' command.
+data PPageReload = PPageReload
+  {
+    -- | If true, browser cache is ignored (as if the user pressed Shift+refresh).
+    pPageReloadIgnoreCache :: Maybe Bool,
+    -- | If set, the script will be injected into all frames of the inspected page after reload.
+    --   Argument will be ignored if reloading dataURL origin.
+    pPageReloadScriptToEvaluateOnLoad :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+pPageReload
+  :: PPageReload
+pPageReload
+  = PPageReload
+    Nothing
+    Nothing
+instance ToJSON PPageReload where
+  toJSON p = A.object $ catMaybes [
+    ("ignoreCache" A..=) <$> (pPageReloadIgnoreCache p),
+    ("scriptToEvaluateOnLoad" A..=) <$> (pPageReloadScriptToEvaluateOnLoad p)
+    ]
+instance Command PPageReload where
+  type CommandResponse PPageReload = ()
+  commandName _ = "Page.reload"
+  fromJSON = const . A.Success . const ()
+
+-- | Removes given script from the list.
+
+-- | Parameters of the 'Page.removeScriptToEvaluateOnNewDocument' command.
+data PPageRemoveScriptToEvaluateOnNewDocument = PPageRemoveScriptToEvaluateOnNewDocument
+  {
+    pPageRemoveScriptToEvaluateOnNewDocumentIdentifier :: PageScriptIdentifier
+  }
+  deriving (Eq, Show)
+pPageRemoveScriptToEvaluateOnNewDocument
+  :: PageScriptIdentifier
+  -> PPageRemoveScriptToEvaluateOnNewDocument
+pPageRemoveScriptToEvaluateOnNewDocument
+  arg_pPageRemoveScriptToEvaluateOnNewDocumentIdentifier
+  = PPageRemoveScriptToEvaluateOnNewDocument
+    arg_pPageRemoveScriptToEvaluateOnNewDocumentIdentifier
+instance ToJSON PPageRemoveScriptToEvaluateOnNewDocument where
+  toJSON p = A.object $ catMaybes [
+    ("identifier" A..=) <$> Just (pPageRemoveScriptToEvaluateOnNewDocumentIdentifier p)
+    ]
+instance Command PPageRemoveScriptToEvaluateOnNewDocument where
+  type CommandResponse PPageRemoveScriptToEvaluateOnNewDocument = ()
+  commandName _ = "Page.removeScriptToEvaluateOnNewDocument"
+  fromJSON = const . A.Success . const ()
+
+-- | Acknowledges that a screencast frame has been received by the frontend.
+
+-- | Parameters of the 'Page.screencastFrameAck' command.
+data PPageScreencastFrameAck = PPageScreencastFrameAck
+  {
+    -- | Frame number.
+    pPageScreencastFrameAckSessionId :: Int
+  }
+  deriving (Eq, Show)
+pPageScreencastFrameAck
+  {-
+  -- | Frame number.
+  -}
+  :: Int
+  -> PPageScreencastFrameAck
+pPageScreencastFrameAck
+  arg_pPageScreencastFrameAckSessionId
+  = PPageScreencastFrameAck
+    arg_pPageScreencastFrameAckSessionId
+instance ToJSON PPageScreencastFrameAck where
+  toJSON p = A.object $ catMaybes [
+    ("sessionId" A..=) <$> Just (pPageScreencastFrameAckSessionId p)
+    ]
+instance Command PPageScreencastFrameAck where
+  type CommandResponse PPageScreencastFrameAck = ()
+  commandName _ = "Page.screencastFrameAck"
+  fromJSON = const . A.Success . const ()
+
+-- | Searches for given string in resource content.
+
+-- | Parameters of the 'Page.searchInResource' command.
+data PPageSearchInResource = PPageSearchInResource
+  {
+    -- | Frame id for resource to search in.
+    pPageSearchInResourceFrameId :: PageFrameId,
+    -- | URL of the resource to search in.
+    pPageSearchInResourceUrl :: T.Text,
+    -- | String to search for.
+    pPageSearchInResourceQuery :: T.Text,
+    -- | If true, search is case sensitive.
+    pPageSearchInResourceCaseSensitive :: Maybe Bool,
+    -- | If true, treats string parameter as regex.
+    pPageSearchInResourceIsRegex :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pPageSearchInResource
+  {-
+  -- | Frame id for resource to search in.
+  -}
+  :: PageFrameId
+  {-
+  -- | URL of the resource to search in.
+  -}
+  -> T.Text
+  {-
+  -- | String to search for.
+  -}
+  -> T.Text
+  -> PPageSearchInResource
+pPageSearchInResource
+  arg_pPageSearchInResourceFrameId
+  arg_pPageSearchInResourceUrl
+  arg_pPageSearchInResourceQuery
+  = PPageSearchInResource
+    arg_pPageSearchInResourceFrameId
+    arg_pPageSearchInResourceUrl
+    arg_pPageSearchInResourceQuery
+    Nothing
+    Nothing
+instance ToJSON PPageSearchInResource where
+  toJSON p = A.object $ catMaybes [
+    ("frameId" A..=) <$> Just (pPageSearchInResourceFrameId p),
+    ("url" A..=) <$> Just (pPageSearchInResourceUrl p),
+    ("query" A..=) <$> Just (pPageSearchInResourceQuery p),
+    ("caseSensitive" A..=) <$> (pPageSearchInResourceCaseSensitive p),
+    ("isRegex" A..=) <$> (pPageSearchInResourceIsRegex p)
+    ]
+data PageSearchInResource = PageSearchInResource
+  {
+    -- | List of search matches.
+    pageSearchInResourceResult :: [Debugger.DebuggerSearchMatch]
+  }
+  deriving (Eq, Show)
+instance FromJSON PageSearchInResource where
+  parseJSON = A.withObject "PageSearchInResource" $ \o -> PageSearchInResource
+    <$> o A..: "result"
+instance Command PPageSearchInResource where
+  type CommandResponse PPageSearchInResource = PageSearchInResource
+  commandName _ = "Page.searchInResource"
+
+-- | Enable Chrome's experimental ad filter on all sites.
+
+-- | Parameters of the 'Page.setAdBlockingEnabled' command.
+data PPageSetAdBlockingEnabled = PPageSetAdBlockingEnabled
+  {
+    -- | Whether to block ads.
+    pPageSetAdBlockingEnabledEnabled :: Bool
+  }
+  deriving (Eq, Show)
+pPageSetAdBlockingEnabled
+  {-
+  -- | Whether to block ads.
+  -}
+  :: Bool
+  -> PPageSetAdBlockingEnabled
+pPageSetAdBlockingEnabled
+  arg_pPageSetAdBlockingEnabledEnabled
+  = PPageSetAdBlockingEnabled
+    arg_pPageSetAdBlockingEnabledEnabled
+instance ToJSON PPageSetAdBlockingEnabled where
+  toJSON p = A.object $ catMaybes [
+    ("enabled" A..=) <$> Just (pPageSetAdBlockingEnabledEnabled p)
+    ]
+instance Command PPageSetAdBlockingEnabled where
+  type CommandResponse PPageSetAdBlockingEnabled = ()
+  commandName _ = "Page.setAdBlockingEnabled"
+  fromJSON = const . A.Success . const ()
+
+-- | Enable page Content Security Policy by-passing.
+
+-- | Parameters of the 'Page.setBypassCSP' command.
+data PPageSetBypassCSP = PPageSetBypassCSP
+  {
+    -- | Whether to bypass page CSP.
+    pPageSetBypassCSPEnabled :: Bool
+  }
+  deriving (Eq, Show)
+pPageSetBypassCSP
+  {-
+  -- | Whether to bypass page CSP.
+  -}
+  :: Bool
+  -> PPageSetBypassCSP
+pPageSetBypassCSP
+  arg_pPageSetBypassCSPEnabled
+  = PPageSetBypassCSP
+    arg_pPageSetBypassCSPEnabled
+instance ToJSON PPageSetBypassCSP where
+  toJSON p = A.object $ catMaybes [
+    ("enabled" A..=) <$> Just (pPageSetBypassCSPEnabled p)
+    ]
+instance Command PPageSetBypassCSP where
+  type CommandResponse PPageSetBypassCSP = ()
+  commandName _ = "Page.setBypassCSP"
+  fromJSON = const . A.Success . const ()
+
+-- | Get Permissions Policy state on given frame.
+
+-- | Parameters of the 'Page.getPermissionsPolicyState' command.
+data PPageGetPermissionsPolicyState = PPageGetPermissionsPolicyState
+  {
+    pPageGetPermissionsPolicyStateFrameId :: PageFrameId
+  }
+  deriving (Eq, Show)
+pPageGetPermissionsPolicyState
+  :: PageFrameId
+  -> PPageGetPermissionsPolicyState
+pPageGetPermissionsPolicyState
+  arg_pPageGetPermissionsPolicyStateFrameId
+  = PPageGetPermissionsPolicyState
+    arg_pPageGetPermissionsPolicyStateFrameId
+instance ToJSON PPageGetPermissionsPolicyState where
+  toJSON p = A.object $ catMaybes [
+    ("frameId" A..=) <$> Just (pPageGetPermissionsPolicyStateFrameId p)
+    ]
+data PageGetPermissionsPolicyState = PageGetPermissionsPolicyState
+  {
+    pageGetPermissionsPolicyStateStates :: [PagePermissionsPolicyFeatureState]
+  }
+  deriving (Eq, Show)
+instance FromJSON PageGetPermissionsPolicyState where
+  parseJSON = A.withObject "PageGetPermissionsPolicyState" $ \o -> PageGetPermissionsPolicyState
+    <$> o A..: "states"
+instance Command PPageGetPermissionsPolicyState where
+  type CommandResponse PPageGetPermissionsPolicyState = PageGetPermissionsPolicyState
+  commandName _ = "Page.getPermissionsPolicyState"
+
+-- | Get Origin Trials on given frame.
+
+-- | Parameters of the 'Page.getOriginTrials' command.
+data PPageGetOriginTrials = PPageGetOriginTrials
+  {
+    pPageGetOriginTrialsFrameId :: PageFrameId
+  }
+  deriving (Eq, Show)
+pPageGetOriginTrials
+  :: PageFrameId
+  -> PPageGetOriginTrials
+pPageGetOriginTrials
+  arg_pPageGetOriginTrialsFrameId
+  = PPageGetOriginTrials
+    arg_pPageGetOriginTrialsFrameId
+instance ToJSON PPageGetOriginTrials where
+  toJSON p = A.object $ catMaybes [
+    ("frameId" A..=) <$> Just (pPageGetOriginTrialsFrameId p)
+    ]
+data PageGetOriginTrials = PageGetOriginTrials
+  {
+    pageGetOriginTrialsOriginTrials :: [PageOriginTrial]
+  }
+  deriving (Eq, Show)
+instance FromJSON PageGetOriginTrials where
+  parseJSON = A.withObject "PageGetOriginTrials" $ \o -> PageGetOriginTrials
+    <$> o A..: "originTrials"
+instance Command PPageGetOriginTrials where
+  type CommandResponse PPageGetOriginTrials = PageGetOriginTrials
+  commandName _ = "Page.getOriginTrials"
+
+-- | Set generic font families.
+
+-- | Parameters of the 'Page.setFontFamilies' command.
+data PPageSetFontFamilies = PPageSetFontFamilies
+  {
+    -- | Specifies font families to set. If a font family is not specified, it won't be changed.
+    pPageSetFontFamiliesFontFamilies :: PageFontFamilies,
+    -- | Specifies font families to set for individual scripts.
+    pPageSetFontFamiliesForScripts :: Maybe [PageScriptFontFamilies]
+  }
+  deriving (Eq, Show)
+pPageSetFontFamilies
+  {-
+  -- | Specifies font families to set. If a font family is not specified, it won't be changed.
+  -}
+  :: PageFontFamilies
+  -> PPageSetFontFamilies
+pPageSetFontFamilies
+  arg_pPageSetFontFamiliesFontFamilies
+  = PPageSetFontFamilies
+    arg_pPageSetFontFamiliesFontFamilies
+    Nothing
+instance ToJSON PPageSetFontFamilies where
+  toJSON p = A.object $ catMaybes [
+    ("fontFamilies" A..=) <$> Just (pPageSetFontFamiliesFontFamilies p),
+    ("forScripts" A..=) <$> (pPageSetFontFamiliesForScripts p)
+    ]
+instance Command PPageSetFontFamilies where
+  type CommandResponse PPageSetFontFamilies = ()
+  commandName _ = "Page.setFontFamilies"
+  fromJSON = const . A.Success . const ()
+
+-- | Set default font sizes.
+
+-- | Parameters of the 'Page.setFontSizes' command.
+data PPageSetFontSizes = PPageSetFontSizes
+  {
+    -- | Specifies font sizes to set. If a font size is not specified, it won't be changed.
+    pPageSetFontSizesFontSizes :: PageFontSizes
+  }
+  deriving (Eq, Show)
+pPageSetFontSizes
+  {-
+  -- | Specifies font sizes to set. If a font size is not specified, it won't be changed.
+  -}
+  :: PageFontSizes
+  -> PPageSetFontSizes
+pPageSetFontSizes
+  arg_pPageSetFontSizesFontSizes
+  = PPageSetFontSizes
+    arg_pPageSetFontSizesFontSizes
+instance ToJSON PPageSetFontSizes where
+  toJSON p = A.object $ catMaybes [
+    ("fontSizes" A..=) <$> Just (pPageSetFontSizesFontSizes p)
+    ]
+instance Command PPageSetFontSizes where
+  type CommandResponse PPageSetFontSizes = ()
+  commandName _ = "Page.setFontSizes"
+  fromJSON = const . A.Success . const ()
+
+-- | Sets given markup as the document's HTML.
+
+-- | Parameters of the 'Page.setDocumentContent' command.
+data PPageSetDocumentContent = PPageSetDocumentContent
+  {
+    -- | Frame id to set HTML for.
+    pPageSetDocumentContentFrameId :: PageFrameId,
+    -- | HTML content to set.
+    pPageSetDocumentContentHtml :: T.Text
+  }
+  deriving (Eq, Show)
+pPageSetDocumentContent
+  {-
+  -- | Frame id to set HTML for.
+  -}
+  :: PageFrameId
+  {-
+  -- | HTML content to set.
+  -}
+  -> T.Text
+  -> PPageSetDocumentContent
+pPageSetDocumentContent
+  arg_pPageSetDocumentContentFrameId
+  arg_pPageSetDocumentContentHtml
+  = PPageSetDocumentContent
+    arg_pPageSetDocumentContentFrameId
+    arg_pPageSetDocumentContentHtml
+instance ToJSON PPageSetDocumentContent where
+  toJSON p = A.object $ catMaybes [
+    ("frameId" A..=) <$> Just (pPageSetDocumentContentFrameId p),
+    ("html" A..=) <$> Just (pPageSetDocumentContentHtml p)
+    ]
+instance Command PPageSetDocumentContent where
+  type CommandResponse PPageSetDocumentContent = ()
+  commandName _ = "Page.setDocumentContent"
+  fromJSON = const . A.Success . const ()
+
+-- | Controls whether page will emit lifecycle events.
+
+-- | Parameters of the 'Page.setLifecycleEventsEnabled' command.
+data PPageSetLifecycleEventsEnabled = PPageSetLifecycleEventsEnabled
+  {
+    -- | If true, starts emitting lifecycle events.
+    pPageSetLifecycleEventsEnabledEnabled :: Bool
+  }
+  deriving (Eq, Show)
+pPageSetLifecycleEventsEnabled
+  {-
+  -- | If true, starts emitting lifecycle events.
+  -}
+  :: Bool
+  -> PPageSetLifecycleEventsEnabled
+pPageSetLifecycleEventsEnabled
+  arg_pPageSetLifecycleEventsEnabledEnabled
+  = PPageSetLifecycleEventsEnabled
+    arg_pPageSetLifecycleEventsEnabledEnabled
+instance ToJSON PPageSetLifecycleEventsEnabled where
+  toJSON p = A.object $ catMaybes [
+    ("enabled" A..=) <$> Just (pPageSetLifecycleEventsEnabledEnabled p)
+    ]
+instance Command PPageSetLifecycleEventsEnabled where
+  type CommandResponse PPageSetLifecycleEventsEnabled = ()
+  commandName _ = "Page.setLifecycleEventsEnabled"
+  fromJSON = const . A.Success . const ()
+
+-- | Starts sending each frame using the `screencastFrame` event.
+
+-- | Parameters of the 'Page.startScreencast' command.
+data PPageStartScreencastFormat = PPageStartScreencastFormatJpeg | PPageStartScreencastFormatPng
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PPageStartScreencastFormat where
+  parseJSON = A.withText "PPageStartScreencastFormat" $ \v -> case v of
+    "jpeg" -> pure PPageStartScreencastFormatJpeg
+    "png" -> pure PPageStartScreencastFormatPng
+    "_" -> fail "failed to parse PPageStartScreencastFormat"
+instance ToJSON PPageStartScreencastFormat where
+  toJSON v = A.String $ case v of
+    PPageStartScreencastFormatJpeg -> "jpeg"
+    PPageStartScreencastFormatPng -> "png"
+data PPageStartScreencast = PPageStartScreencast
+  {
+    -- | Image compression format.
+    pPageStartScreencastFormat :: Maybe PPageStartScreencastFormat,
+    -- | Compression quality from range [0..100].
+    pPageStartScreencastQuality :: Maybe Int,
+    -- | Maximum screenshot width.
+    pPageStartScreencastMaxWidth :: Maybe Int,
+    -- | Maximum screenshot height.
+    pPageStartScreencastMaxHeight :: Maybe Int,
+    -- | Send every n-th frame.
+    pPageStartScreencastEveryNthFrame :: Maybe Int
+  }
+  deriving (Eq, Show)
+pPageStartScreencast
+  :: PPageStartScreencast
+pPageStartScreencast
+  = PPageStartScreencast
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PPageStartScreencast where
+  toJSON p = A.object $ catMaybes [
+    ("format" A..=) <$> (pPageStartScreencastFormat p),
+    ("quality" A..=) <$> (pPageStartScreencastQuality p),
+    ("maxWidth" A..=) <$> (pPageStartScreencastMaxWidth p),
+    ("maxHeight" A..=) <$> (pPageStartScreencastMaxHeight p),
+    ("everyNthFrame" A..=) <$> (pPageStartScreencastEveryNthFrame p)
+    ]
+instance Command PPageStartScreencast where
+  type CommandResponse PPageStartScreencast = ()
+  commandName _ = "Page.startScreencast"
+  fromJSON = const . A.Success . const ()
+
+-- | Force the page stop all navigations and pending resource fetches.
+
+-- | Parameters of the 'Page.stopLoading' command.
+data PPageStopLoading = PPageStopLoading
+  deriving (Eq, Show)
+pPageStopLoading
+  :: PPageStopLoading
+pPageStopLoading
+  = PPageStopLoading
+instance ToJSON PPageStopLoading where
+  toJSON _ = A.Null
+instance Command PPageStopLoading where
+  type CommandResponse PPageStopLoading = ()
+  commandName _ = "Page.stopLoading"
+  fromJSON = const . A.Success . const ()
+
+-- | Crashes renderer on the IO thread, generates minidumps.
+
+-- | Parameters of the 'Page.crash' command.
+data PPageCrash = PPageCrash
+  deriving (Eq, Show)
+pPageCrash
+  :: PPageCrash
+pPageCrash
+  = PPageCrash
+instance ToJSON PPageCrash where
+  toJSON _ = A.Null
+instance Command PPageCrash where
+  type CommandResponse PPageCrash = ()
+  commandName _ = "Page.crash"
+  fromJSON = const . A.Success . const ()
+
+-- | Tries to close page, running its beforeunload hooks, if any.
+
+-- | Parameters of the 'Page.close' command.
+data PPageClose = PPageClose
+  deriving (Eq, Show)
+pPageClose
+  :: PPageClose
+pPageClose
+  = PPageClose
+instance ToJSON PPageClose where
+  toJSON _ = A.Null
+instance Command PPageClose where
+  type CommandResponse PPageClose = ()
+  commandName _ = "Page.close"
+  fromJSON = const . A.Success . const ()
+
+-- | Tries to update the web lifecycle state of the page.
+--   It will transition the page to the given state according to:
+--   https://github.com/WICG/web-lifecycle/
+
+-- | Parameters of the 'Page.setWebLifecycleState' command.
+data PPageSetWebLifecycleStateState = PPageSetWebLifecycleStateStateFrozen | PPageSetWebLifecycleStateStateActive
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PPageSetWebLifecycleStateState where
+  parseJSON = A.withText "PPageSetWebLifecycleStateState" $ \v -> case v of
+    "frozen" -> pure PPageSetWebLifecycleStateStateFrozen
+    "active" -> pure PPageSetWebLifecycleStateStateActive
+    "_" -> fail "failed to parse PPageSetWebLifecycleStateState"
+instance ToJSON PPageSetWebLifecycleStateState where
+  toJSON v = A.String $ case v of
+    PPageSetWebLifecycleStateStateFrozen -> "frozen"
+    PPageSetWebLifecycleStateStateActive -> "active"
+data PPageSetWebLifecycleState = PPageSetWebLifecycleState
+  {
+    -- | Target lifecycle state
+    pPageSetWebLifecycleStateState :: PPageSetWebLifecycleStateState
+  }
+  deriving (Eq, Show)
+pPageSetWebLifecycleState
+  {-
+  -- | Target lifecycle state
+  -}
+  :: PPageSetWebLifecycleStateState
+  -> PPageSetWebLifecycleState
+pPageSetWebLifecycleState
+  arg_pPageSetWebLifecycleStateState
+  = PPageSetWebLifecycleState
+    arg_pPageSetWebLifecycleStateState
+instance ToJSON PPageSetWebLifecycleState where
+  toJSON p = A.object $ catMaybes [
+    ("state" A..=) <$> Just (pPageSetWebLifecycleStateState p)
+    ]
+instance Command PPageSetWebLifecycleState where
+  type CommandResponse PPageSetWebLifecycleState = ()
+  commandName _ = "Page.setWebLifecycleState"
+  fromJSON = const . A.Success . const ()
+
+-- | Stops sending each frame in the `screencastFrame`.
+
+-- | Parameters of the 'Page.stopScreencast' command.
+data PPageStopScreencast = PPageStopScreencast
+  deriving (Eq, Show)
+pPageStopScreencast
+  :: PPageStopScreencast
+pPageStopScreencast
+  = PPageStopScreencast
+instance ToJSON PPageStopScreencast where
+  toJSON _ = A.Null
+instance Command PPageStopScreencast where
+  type CommandResponse PPageStopScreencast = ()
+  commandName _ = "Page.stopScreencast"
+  fromJSON = const . A.Success . const ()
+
+-- | Requests backend to produce compilation cache for the specified scripts.
+--   `scripts` are appeneded to the list of scripts for which the cache
+--   would be produced. The list may be reset during page navigation.
+--   When script with a matching URL is encountered, the cache is optionally
+--   produced upon backend discretion, based on internal heuristics.
+--   See also: `Page.compilationCacheProduced`.
+
+-- | Parameters of the 'Page.produceCompilationCache' command.
+data PPageProduceCompilationCache = PPageProduceCompilationCache
+  {
+    pPageProduceCompilationCacheScripts :: [PageCompilationCacheParams]
+  }
+  deriving (Eq, Show)
+pPageProduceCompilationCache
+  :: [PageCompilationCacheParams]
+  -> PPageProduceCompilationCache
+pPageProduceCompilationCache
+  arg_pPageProduceCompilationCacheScripts
+  = PPageProduceCompilationCache
+    arg_pPageProduceCompilationCacheScripts
+instance ToJSON PPageProduceCompilationCache where
+  toJSON p = A.object $ catMaybes [
+    ("scripts" A..=) <$> Just (pPageProduceCompilationCacheScripts p)
+    ]
+instance Command PPageProduceCompilationCache where
+  type CommandResponse PPageProduceCompilationCache = ()
+  commandName _ = "Page.produceCompilationCache"
+  fromJSON = const . A.Success . const ()
+
+-- | Seeds compilation cache for given url. Compilation cache does not survive
+--   cross-process navigation.
+
+-- | Parameters of the 'Page.addCompilationCache' command.
+data PPageAddCompilationCache = PPageAddCompilationCache
+  {
+    pPageAddCompilationCacheUrl :: T.Text,
+    -- | Base64-encoded data (Encoded as a base64 string when passed over JSON)
+    pPageAddCompilationCacheData :: T.Text
+  }
+  deriving (Eq, Show)
+pPageAddCompilationCache
+  :: T.Text
+  {-
+  -- | Base64-encoded data (Encoded as a base64 string when passed over JSON)
+  -}
+  -> T.Text
+  -> PPageAddCompilationCache
+pPageAddCompilationCache
+  arg_pPageAddCompilationCacheUrl
+  arg_pPageAddCompilationCacheData
+  = PPageAddCompilationCache
+    arg_pPageAddCompilationCacheUrl
+    arg_pPageAddCompilationCacheData
+instance ToJSON PPageAddCompilationCache where
+  toJSON p = A.object $ catMaybes [
+    ("url" A..=) <$> Just (pPageAddCompilationCacheUrl p),
+    ("data" A..=) <$> Just (pPageAddCompilationCacheData p)
+    ]
+instance Command PPageAddCompilationCache where
+  type CommandResponse PPageAddCompilationCache = ()
+  commandName _ = "Page.addCompilationCache"
+  fromJSON = const . A.Success . const ()
+
+-- | Clears seeded compilation cache.
+
+-- | Parameters of the 'Page.clearCompilationCache' command.
+data PPageClearCompilationCache = PPageClearCompilationCache
+  deriving (Eq, Show)
+pPageClearCompilationCache
+  :: PPageClearCompilationCache
+pPageClearCompilationCache
+  = PPageClearCompilationCache
+instance ToJSON PPageClearCompilationCache where
+  toJSON _ = A.Null
+instance Command PPageClearCompilationCache where
+  type CommandResponse PPageClearCompilationCache = ()
+  commandName _ = "Page.clearCompilationCache"
+  fromJSON = const . A.Success . const ()
+
+-- | Sets the Secure Payment Confirmation transaction mode.
+--   https://w3c.github.io/secure-payment-confirmation/#sctn-automation-set-spc-transaction-mode
+
+-- | Parameters of the 'Page.setSPCTransactionMode' command.
+data PPageSetSPCTransactionModeMode = PPageSetSPCTransactionModeModeNone | PPageSetSPCTransactionModeModeAutoaccept | PPageSetSPCTransactionModeModeAutoreject
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PPageSetSPCTransactionModeMode where
+  parseJSON = A.withText "PPageSetSPCTransactionModeMode" $ \v -> case v of
+    "none" -> pure PPageSetSPCTransactionModeModeNone
+    "autoaccept" -> pure PPageSetSPCTransactionModeModeAutoaccept
+    "autoreject" -> pure PPageSetSPCTransactionModeModeAutoreject
+    "_" -> fail "failed to parse PPageSetSPCTransactionModeMode"
+instance ToJSON PPageSetSPCTransactionModeMode where
+  toJSON v = A.String $ case v of
+    PPageSetSPCTransactionModeModeNone -> "none"
+    PPageSetSPCTransactionModeModeAutoaccept -> "autoaccept"
+    PPageSetSPCTransactionModeModeAutoreject -> "autoreject"
+data PPageSetSPCTransactionMode = PPageSetSPCTransactionMode
+  {
+    pPageSetSPCTransactionModeMode :: PPageSetSPCTransactionModeMode
+  }
+  deriving (Eq, Show)
+pPageSetSPCTransactionMode
+  :: PPageSetSPCTransactionModeMode
+  -> PPageSetSPCTransactionMode
+pPageSetSPCTransactionMode
+  arg_pPageSetSPCTransactionModeMode
+  = PPageSetSPCTransactionMode
+    arg_pPageSetSPCTransactionModeMode
+instance ToJSON PPageSetSPCTransactionMode where
+  toJSON p = A.object $ catMaybes [
+    ("mode" A..=) <$> Just (pPageSetSPCTransactionModeMode p)
+    ]
+instance Command PPageSetSPCTransactionMode where
+  type CommandResponse PPageSetSPCTransactionMode = ()
+  commandName _ = "Page.setSPCTransactionMode"
+  fromJSON = const . A.Success . const ()
+
+-- | Generates a report for testing.
+
+-- | Parameters of the 'Page.generateTestReport' command.
+data PPageGenerateTestReport = PPageGenerateTestReport
+  {
+    -- | Message to be displayed in the report.
+    pPageGenerateTestReportMessage :: T.Text,
+    -- | Specifies the endpoint group to deliver the report to.
+    pPageGenerateTestReportGroup :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+pPageGenerateTestReport
+  {-
+  -- | Message to be displayed in the report.
+  -}
+  :: T.Text
+  -> PPageGenerateTestReport
+pPageGenerateTestReport
+  arg_pPageGenerateTestReportMessage
+  = PPageGenerateTestReport
+    arg_pPageGenerateTestReportMessage
+    Nothing
+instance ToJSON PPageGenerateTestReport where
+  toJSON p = A.object $ catMaybes [
+    ("message" A..=) <$> Just (pPageGenerateTestReportMessage p),
+    ("group" A..=) <$> (pPageGenerateTestReportGroup p)
+    ]
+instance Command PPageGenerateTestReport where
+  type CommandResponse PPageGenerateTestReport = ()
+  commandName _ = "Page.generateTestReport"
+  fromJSON = const . A.Success . const ()
+
+-- | Pauses page execution. Can be resumed using generic Runtime.runIfWaitingForDebugger.
+
+-- | Parameters of the 'Page.waitForDebugger' command.
+data PPageWaitForDebugger = PPageWaitForDebugger
+  deriving (Eq, Show)
+pPageWaitForDebugger
+  :: PPageWaitForDebugger
+pPageWaitForDebugger
+  = PPageWaitForDebugger
+instance ToJSON PPageWaitForDebugger where
+  toJSON _ = A.Null
+instance Command PPageWaitForDebugger where
+  type CommandResponse PPageWaitForDebugger = ()
+  commandName _ = "Page.waitForDebugger"
+  fromJSON = const . A.Success . const ()
+
+-- | Intercept file chooser requests and transfer control to protocol clients.
+--   When file chooser interception is enabled, native file chooser dialog is not shown.
+--   Instead, a protocol event `Page.fileChooserOpened` is emitted.
+
+-- | Parameters of the 'Page.setInterceptFileChooserDialog' command.
+data PPageSetInterceptFileChooserDialog = PPageSetInterceptFileChooserDialog
+  {
+    pPageSetInterceptFileChooserDialogEnabled :: Bool
+  }
+  deriving (Eq, Show)
+pPageSetInterceptFileChooserDialog
+  :: Bool
+  -> PPageSetInterceptFileChooserDialog
+pPageSetInterceptFileChooserDialog
+  arg_pPageSetInterceptFileChooserDialogEnabled
+  = PPageSetInterceptFileChooserDialog
+    arg_pPageSetInterceptFileChooserDialogEnabled
+instance ToJSON PPageSetInterceptFileChooserDialog where
+  toJSON p = A.object $ catMaybes [
+    ("enabled" A..=) <$> Just (pPageSetInterceptFileChooserDialogEnabled p)
+    ]
+instance Command PPageSetInterceptFileChooserDialog where
+  type CommandResponse PPageSetInterceptFileChooserDialog = ()
+  commandName _ = "Page.setInterceptFileChooserDialog"
+  fromJSON = const . A.Success . const ()
+
+-- | Type 'Security.CertificateId'.
+--   An internal certificate ID value.
+type SecurityCertificateId = Int
+
+-- | Type 'Security.MixedContentType'.
+--   A description of mixed content (HTTP resources on HTTPS pages), as defined by
+--   https://www.w3.org/TR/mixed-content/#categories
+data SecurityMixedContentType = SecurityMixedContentTypeBlockable | SecurityMixedContentTypeOptionallyBlockable | SecurityMixedContentTypeNone
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON SecurityMixedContentType where
+  parseJSON = A.withText "SecurityMixedContentType" $ \v -> case v of
+    "blockable" -> pure SecurityMixedContentTypeBlockable
+    "optionally-blockable" -> pure SecurityMixedContentTypeOptionallyBlockable
+    "none" -> pure SecurityMixedContentTypeNone
+    "_" -> fail "failed to parse SecurityMixedContentType"
+instance ToJSON SecurityMixedContentType where
+  toJSON v = A.String $ case v of
+    SecurityMixedContentTypeBlockable -> "blockable"
+    SecurityMixedContentTypeOptionallyBlockable -> "optionally-blockable"
+    SecurityMixedContentTypeNone -> "none"
+
+-- | Type 'Security.SecurityState'.
+--   The security level of a page or resource.
+data SecuritySecurityState = SecuritySecurityStateUnknown | SecuritySecurityStateNeutral | SecuritySecurityStateInsecure | SecuritySecurityStateSecure | SecuritySecurityStateInfo | SecuritySecurityStateInsecureBroken
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON SecuritySecurityState where
+  parseJSON = A.withText "SecuritySecurityState" $ \v -> case v of
+    "unknown" -> pure SecuritySecurityStateUnknown
+    "neutral" -> pure SecuritySecurityStateNeutral
+    "insecure" -> pure SecuritySecurityStateInsecure
+    "secure" -> pure SecuritySecurityStateSecure
+    "info" -> pure SecuritySecurityStateInfo
+    "insecure-broken" -> pure SecuritySecurityStateInsecureBroken
+    "_" -> fail "failed to parse SecuritySecurityState"
+instance ToJSON SecuritySecurityState where
+  toJSON v = A.String $ case v of
+    SecuritySecurityStateUnknown -> "unknown"
+    SecuritySecurityStateNeutral -> "neutral"
+    SecuritySecurityStateInsecure -> "insecure"
+    SecuritySecurityStateSecure -> "secure"
+    SecuritySecurityStateInfo -> "info"
+    SecuritySecurityStateInsecureBroken -> "insecure-broken"
+
+-- | Type 'Security.CertificateSecurityState'.
+--   Details about the security state of the page certificate.
+data SecurityCertificateSecurityState = SecurityCertificateSecurityState
+  {
+    -- | Protocol name (e.g. "TLS 1.2" or "QUIC").
+    securityCertificateSecurityStateProtocol :: T.Text,
+    -- | Key Exchange used by the connection, or the empty string if not applicable.
+    securityCertificateSecurityStateKeyExchange :: T.Text,
+    -- | (EC)DH group used by the connection, if applicable.
+    securityCertificateSecurityStateKeyExchangeGroup :: Maybe T.Text,
+    -- | Cipher name.
+    securityCertificateSecurityStateCipher :: T.Text,
+    -- | TLS MAC. Note that AEAD ciphers do not have separate MACs.
+    securityCertificateSecurityStateMac :: Maybe T.Text,
+    -- | Page certificate.
+    securityCertificateSecurityStateCertificate :: [T.Text],
+    -- | Certificate subject name.
+    securityCertificateSecurityStateSubjectName :: T.Text,
+    -- | Name of the issuing CA.
+    securityCertificateSecurityStateIssuer :: T.Text,
+    -- | Certificate valid from date.
+    securityCertificateSecurityStateValidFrom :: NetworkTimeSinceEpoch,
+    -- | Certificate valid to (expiration) date
+    securityCertificateSecurityStateValidTo :: NetworkTimeSinceEpoch,
+    -- | The highest priority network error code, if the certificate has an error.
+    securityCertificateSecurityStateCertificateNetworkError :: Maybe T.Text,
+    -- | True if the certificate uses a weak signature aglorithm.
+    securityCertificateSecurityStateCertificateHasWeakSignature :: Bool,
+    -- | True if the certificate has a SHA1 signature in the chain.
+    securityCertificateSecurityStateCertificateHasSha1Signature :: Bool,
+    -- | True if modern SSL
+    securityCertificateSecurityStateModernSSL :: Bool,
+    -- | True if the connection is using an obsolete SSL protocol.
+    securityCertificateSecurityStateObsoleteSslProtocol :: Bool,
+    -- | True if the connection is using an obsolete SSL key exchange.
+    securityCertificateSecurityStateObsoleteSslKeyExchange :: Bool,
+    -- | True if the connection is using an obsolete SSL cipher.
+    securityCertificateSecurityStateObsoleteSslCipher :: Bool,
+    -- | True if the connection is using an obsolete SSL signature.
+    securityCertificateSecurityStateObsoleteSslSignature :: Bool
+  }
+  deriving (Eq, Show)
+instance FromJSON SecurityCertificateSecurityState where
+  parseJSON = A.withObject "SecurityCertificateSecurityState" $ \o -> SecurityCertificateSecurityState
+    <$> o A..: "protocol"
+    <*> o A..: "keyExchange"
+    <*> o A..:? "keyExchangeGroup"
+    <*> o A..: "cipher"
+    <*> o A..:? "mac"
+    <*> o A..: "certificate"
+    <*> o A..: "subjectName"
+    <*> o A..: "issuer"
+    <*> o A..: "validFrom"
+    <*> o A..: "validTo"
+    <*> o A..:? "certificateNetworkError"
+    <*> o A..: "certificateHasWeakSignature"
+    <*> o A..: "certificateHasSha1Signature"
+    <*> o A..: "modernSSL"
+    <*> o A..: "obsoleteSslProtocol"
+    <*> o A..: "obsoleteSslKeyExchange"
+    <*> o A..: "obsoleteSslCipher"
+    <*> o A..: "obsoleteSslSignature"
+instance ToJSON SecurityCertificateSecurityState where
+  toJSON p = A.object $ catMaybes [
+    ("protocol" A..=) <$> Just (securityCertificateSecurityStateProtocol p),
+    ("keyExchange" A..=) <$> Just (securityCertificateSecurityStateKeyExchange p),
+    ("keyExchangeGroup" A..=) <$> (securityCertificateSecurityStateKeyExchangeGroup p),
+    ("cipher" A..=) <$> Just (securityCertificateSecurityStateCipher p),
+    ("mac" A..=) <$> (securityCertificateSecurityStateMac p),
+    ("certificate" A..=) <$> Just (securityCertificateSecurityStateCertificate p),
+    ("subjectName" A..=) <$> Just (securityCertificateSecurityStateSubjectName p),
+    ("issuer" A..=) <$> Just (securityCertificateSecurityStateIssuer p),
+    ("validFrom" A..=) <$> Just (securityCertificateSecurityStateValidFrom p),
+    ("validTo" A..=) <$> Just (securityCertificateSecurityStateValidTo p),
+    ("certificateNetworkError" A..=) <$> (securityCertificateSecurityStateCertificateNetworkError p),
+    ("certificateHasWeakSignature" A..=) <$> Just (securityCertificateSecurityStateCertificateHasWeakSignature p),
+    ("certificateHasSha1Signature" A..=) <$> Just (securityCertificateSecurityStateCertificateHasSha1Signature p),
+    ("modernSSL" A..=) <$> Just (securityCertificateSecurityStateModernSSL p),
+    ("obsoleteSslProtocol" A..=) <$> Just (securityCertificateSecurityStateObsoleteSslProtocol p),
+    ("obsoleteSslKeyExchange" A..=) <$> Just (securityCertificateSecurityStateObsoleteSslKeyExchange p),
+    ("obsoleteSslCipher" A..=) <$> Just (securityCertificateSecurityStateObsoleteSslCipher p),
+    ("obsoleteSslSignature" A..=) <$> Just (securityCertificateSecurityStateObsoleteSslSignature p)
+    ]
+
+-- | Type 'Security.SafetyTipStatus'.
+data SecuritySafetyTipStatus = SecuritySafetyTipStatusBadReputation | SecuritySafetyTipStatusLookalike
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON SecuritySafetyTipStatus where
+  parseJSON = A.withText "SecuritySafetyTipStatus" $ \v -> case v of
+    "badReputation" -> pure SecuritySafetyTipStatusBadReputation
+    "lookalike" -> pure SecuritySafetyTipStatusLookalike
+    "_" -> fail "failed to parse SecuritySafetyTipStatus"
+instance ToJSON SecuritySafetyTipStatus where
+  toJSON v = A.String $ case v of
+    SecuritySafetyTipStatusBadReputation -> "badReputation"
+    SecuritySafetyTipStatusLookalike -> "lookalike"
+
+-- | Type 'Security.SafetyTipInfo'.
+data SecuritySafetyTipInfo = SecuritySafetyTipInfo
+  {
+    -- | Describes whether the page triggers any safety tips or reputation warnings. Default is unknown.
+    securitySafetyTipInfoSafetyTipStatus :: SecuritySafetyTipStatus,
+    -- | The URL the safety tip suggested ("Did you mean?"). Only filled in for lookalike matches.
+    securitySafetyTipInfoSafeUrl :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON SecuritySafetyTipInfo where
+  parseJSON = A.withObject "SecuritySafetyTipInfo" $ \o -> SecuritySafetyTipInfo
+    <$> o A..: "safetyTipStatus"
+    <*> o A..:? "safeUrl"
+instance ToJSON SecuritySafetyTipInfo where
+  toJSON p = A.object $ catMaybes [
+    ("safetyTipStatus" A..=) <$> Just (securitySafetyTipInfoSafetyTipStatus p),
+    ("safeUrl" A..=) <$> (securitySafetyTipInfoSafeUrl p)
+    ]
+
+-- | Type 'Security.VisibleSecurityState'.
+--   Security state information about the page.
+data SecurityVisibleSecurityState = SecurityVisibleSecurityState
+  {
+    -- | The security level of the page.
+    securityVisibleSecurityStateSecurityState :: SecuritySecurityState,
+    -- | Security state details about the page certificate.
+    securityVisibleSecurityStateCertificateSecurityState :: Maybe SecurityCertificateSecurityState,
+    -- | The type of Safety Tip triggered on the page. Note that this field will be set even if the Safety Tip UI was not actually shown.
+    securityVisibleSecurityStateSafetyTipInfo :: Maybe SecuritySafetyTipInfo,
+    -- | Array of security state issues ids.
+    securityVisibleSecurityStateSecurityStateIssueIds :: [T.Text]
+  }
+  deriving (Eq, Show)
+instance FromJSON SecurityVisibleSecurityState where
+  parseJSON = A.withObject "SecurityVisibleSecurityState" $ \o -> SecurityVisibleSecurityState
+    <$> o A..: "securityState"
+    <*> o A..:? "certificateSecurityState"
+    <*> o A..:? "safetyTipInfo"
+    <*> o A..: "securityStateIssueIds"
+instance ToJSON SecurityVisibleSecurityState where
+  toJSON p = A.object $ catMaybes [
+    ("securityState" A..=) <$> Just (securityVisibleSecurityStateSecurityState p),
+    ("certificateSecurityState" A..=) <$> (securityVisibleSecurityStateCertificateSecurityState p),
+    ("safetyTipInfo" A..=) <$> (securityVisibleSecurityStateSafetyTipInfo p),
+    ("securityStateIssueIds" A..=) <$> Just (securityVisibleSecurityStateSecurityStateIssueIds p)
+    ]
+
+-- | Type 'Security.SecurityStateExplanation'.
+--   An explanation of an factor contributing to the security state.
+data SecuritySecurityStateExplanation = SecuritySecurityStateExplanation
+  {
+    -- | Security state representing the severity of the factor being explained.
+    securitySecurityStateExplanationSecurityState :: SecuritySecurityState,
+    -- | Title describing the type of factor.
+    securitySecurityStateExplanationTitle :: T.Text,
+    -- | Short phrase describing the type of factor.
+    securitySecurityStateExplanationSummary :: T.Text,
+    -- | Full text explanation of the factor.
+    securitySecurityStateExplanationDescription :: T.Text,
+    -- | The type of mixed content described by the explanation.
+    securitySecurityStateExplanationMixedContentType :: SecurityMixedContentType,
+    -- | Page certificate.
+    securitySecurityStateExplanationCertificate :: [T.Text],
+    -- | Recommendations to fix any issues.
+    securitySecurityStateExplanationRecommendations :: Maybe [T.Text]
+  }
+  deriving (Eq, Show)
+instance FromJSON SecuritySecurityStateExplanation where
+  parseJSON = A.withObject "SecuritySecurityStateExplanation" $ \o -> SecuritySecurityStateExplanation
+    <$> o A..: "securityState"
+    <*> o A..: "title"
+    <*> o A..: "summary"
+    <*> o A..: "description"
+    <*> o A..: "mixedContentType"
+    <*> o A..: "certificate"
+    <*> o A..:? "recommendations"
+instance ToJSON SecuritySecurityStateExplanation where
+  toJSON p = A.object $ catMaybes [
+    ("securityState" A..=) <$> Just (securitySecurityStateExplanationSecurityState p),
+    ("title" A..=) <$> Just (securitySecurityStateExplanationTitle p),
+    ("summary" A..=) <$> Just (securitySecurityStateExplanationSummary p),
+    ("description" A..=) <$> Just (securitySecurityStateExplanationDescription p),
+    ("mixedContentType" A..=) <$> Just (securitySecurityStateExplanationMixedContentType p),
+    ("certificate" A..=) <$> Just (securitySecurityStateExplanationCertificate p),
+    ("recommendations" A..=) <$> (securitySecurityStateExplanationRecommendations p)
+    ]
+
+-- | Type 'Security.CertificateErrorAction'.
+--   The action to take when a certificate error occurs. continue will continue processing the
+--   request and cancel will cancel the request.
+data SecurityCertificateErrorAction = SecurityCertificateErrorActionContinue | SecurityCertificateErrorActionCancel
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON SecurityCertificateErrorAction where
+  parseJSON = A.withText "SecurityCertificateErrorAction" $ \v -> case v of
+    "continue" -> pure SecurityCertificateErrorActionContinue
+    "cancel" -> pure SecurityCertificateErrorActionCancel
+    "_" -> fail "failed to parse SecurityCertificateErrorAction"
+instance ToJSON SecurityCertificateErrorAction where
+  toJSON v = A.String $ case v of
+    SecurityCertificateErrorActionContinue -> "continue"
+    SecurityCertificateErrorActionCancel -> "cancel"
+
+-- | Type of the 'Security.visibleSecurityStateChanged' event.
+data SecurityVisibleSecurityStateChanged = SecurityVisibleSecurityStateChanged
+  {
+    -- | Security state information about the page.
+    securityVisibleSecurityStateChangedVisibleSecurityState :: SecurityVisibleSecurityState
+  }
+  deriving (Eq, Show)
+instance FromJSON SecurityVisibleSecurityStateChanged where
+  parseJSON = A.withObject "SecurityVisibleSecurityStateChanged" $ \o -> SecurityVisibleSecurityStateChanged
+    <$> o A..: "visibleSecurityState"
+instance Event SecurityVisibleSecurityStateChanged where
+  eventName _ = "Security.visibleSecurityStateChanged"
+
+-- | Disables tracking security state changes.
+
+-- | Parameters of the 'Security.disable' command.
+data PSecurityDisable = PSecurityDisable
+  deriving (Eq, Show)
+pSecurityDisable
+  :: PSecurityDisable
+pSecurityDisable
+  = PSecurityDisable
+instance ToJSON PSecurityDisable where
+  toJSON _ = A.Null
+instance Command PSecurityDisable where
+  type CommandResponse PSecurityDisable = ()
+  commandName _ = "Security.disable"
+  fromJSON = const . A.Success . const ()
+
+-- | Enables tracking security state changes.
+
+-- | Parameters of the 'Security.enable' command.
+data PSecurityEnable = PSecurityEnable
+  deriving (Eq, Show)
+pSecurityEnable
+  :: PSecurityEnable
+pSecurityEnable
+  = PSecurityEnable
+instance ToJSON PSecurityEnable where
+  toJSON _ = A.Null
+instance Command PSecurityEnable where
+  type CommandResponse PSecurityEnable = ()
+  commandName _ = "Security.enable"
+  fromJSON = const . A.Success . const ()
+
+-- | Enable/disable whether all certificate errors should be ignored.
+
+-- | Parameters of the 'Security.setIgnoreCertificateErrors' command.
+data PSecuritySetIgnoreCertificateErrors = PSecuritySetIgnoreCertificateErrors
+  {
+    -- | If true, all certificate errors will be ignored.
+    pSecuritySetIgnoreCertificateErrorsIgnore :: Bool
+  }
+  deriving (Eq, Show)
+pSecuritySetIgnoreCertificateErrors
+  {-
+  -- | If true, all certificate errors will be ignored.
+  -}
+  :: Bool
+  -> PSecuritySetIgnoreCertificateErrors
+pSecuritySetIgnoreCertificateErrors
+  arg_pSecuritySetIgnoreCertificateErrorsIgnore
+  = PSecuritySetIgnoreCertificateErrors
+    arg_pSecuritySetIgnoreCertificateErrorsIgnore
+instance ToJSON PSecuritySetIgnoreCertificateErrors where
+  toJSON p = A.object $ catMaybes [
+    ("ignore" A..=) <$> Just (pSecuritySetIgnoreCertificateErrorsIgnore p)
+    ]
+instance Command PSecuritySetIgnoreCertificateErrors where
+  type CommandResponse PSecuritySetIgnoreCertificateErrors = ()
+  commandName _ = "Security.setIgnoreCertificateErrors"
+  fromJSON = const . A.Success . const ()
+
diff --git a/src/CDP/Domains/DOMSnapshot.hs b/src/CDP/Domains/DOMSnapshot.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains/DOMSnapshot.hs
@@ -0,0 +1,684 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+
+
+{- |
+= DOMSnapshot
+
+This domain facilitates obtaining document snapshots with DOM, layout, and style information.
+-}
+
+
+module CDP.Domains.DOMSnapshot (module CDP.Domains.DOMSnapshot) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+
+import CDP.Domains.DOMDebugger as DOMDebugger
+import CDP.Domains.DOMPageNetworkEmulationSecurity as DOMPageNetworkEmulationSecurity
+
+
+-- | Type 'DOMSnapshot.DOMNode'.
+--   A Node in the DOM tree.
+data DOMSnapshotDOMNode = DOMSnapshotDOMNode
+  {
+    -- | `Node`'s nodeType.
+    dOMSnapshotDOMNodeNodeType :: Int,
+    -- | `Node`'s nodeName.
+    dOMSnapshotDOMNodeNodeName :: T.Text,
+    -- | `Node`'s nodeValue.
+    dOMSnapshotDOMNodeNodeValue :: T.Text,
+    -- | Only set for textarea elements, contains the text value.
+    dOMSnapshotDOMNodeTextValue :: Maybe T.Text,
+    -- | Only set for input elements, contains the input's associated text value.
+    dOMSnapshotDOMNodeInputValue :: Maybe T.Text,
+    -- | Only set for radio and checkbox input elements, indicates if the element has been checked
+    dOMSnapshotDOMNodeInputChecked :: Maybe Bool,
+    -- | Only set for option elements, indicates if the element has been selected
+    dOMSnapshotDOMNodeOptionSelected :: Maybe Bool,
+    -- | `Node`'s id, corresponds to DOM.Node.backendNodeId.
+    dOMSnapshotDOMNodeBackendNodeId :: DOMPageNetworkEmulationSecurity.DOMBackendNodeId,
+    -- | The indexes of the node's child nodes in the `domNodes` array returned by `getSnapshot`, if
+    --   any.
+    dOMSnapshotDOMNodeChildNodeIndexes :: Maybe [Int],
+    -- | Attributes of an `Element` node.
+    dOMSnapshotDOMNodeAttributes :: Maybe [DOMSnapshotNameValue],
+    -- | Indexes of pseudo elements associated with this node in the `domNodes` array returned by
+    --   `getSnapshot`, if any.
+    dOMSnapshotDOMNodePseudoElementIndexes :: Maybe [Int],
+    -- | The index of the node's related layout tree node in the `layoutTreeNodes` array returned by
+    --   `getSnapshot`, if any.
+    dOMSnapshotDOMNodeLayoutNodeIndex :: Maybe Int,
+    -- | Document URL that `Document` or `FrameOwner` node points to.
+    dOMSnapshotDOMNodeDocumentURL :: Maybe T.Text,
+    -- | Base URL that `Document` or `FrameOwner` node uses for URL completion.
+    dOMSnapshotDOMNodeBaseURL :: Maybe T.Text,
+    -- | Only set for documents, contains the document's content language.
+    dOMSnapshotDOMNodeContentLanguage :: Maybe T.Text,
+    -- | Only set for documents, contains the document's character set encoding.
+    dOMSnapshotDOMNodeDocumentEncoding :: Maybe T.Text,
+    -- | `DocumentType` node's publicId.
+    dOMSnapshotDOMNodePublicId :: Maybe T.Text,
+    -- | `DocumentType` node's systemId.
+    dOMSnapshotDOMNodeSystemId :: Maybe T.Text,
+    -- | Frame ID for frame owner elements and also for the document node.
+    dOMSnapshotDOMNodeFrameId :: Maybe DOMPageNetworkEmulationSecurity.PageFrameId,
+    -- | The index of a frame owner element's content document in the `domNodes` array returned by
+    --   `getSnapshot`, if any.
+    dOMSnapshotDOMNodeContentDocumentIndex :: Maybe Int,
+    -- | Type of a pseudo element node.
+    dOMSnapshotDOMNodePseudoType :: Maybe DOMPageNetworkEmulationSecurity.DOMPseudoType,
+    -- | Shadow root type.
+    dOMSnapshotDOMNodeShadowRootType :: Maybe DOMPageNetworkEmulationSecurity.DOMShadowRootType,
+    -- | Whether this DOM node responds to mouse clicks. This includes nodes that have had click
+    --   event listeners attached via JavaScript as well as anchor tags that naturally navigate when
+    --   clicked.
+    dOMSnapshotDOMNodeIsClickable :: Maybe Bool,
+    -- | Details of the node's event listeners, if any.
+    dOMSnapshotDOMNodeEventListeners :: Maybe [DOMDebugger.DOMDebuggerEventListener],
+    -- | The selected url for nodes with a srcset attribute.
+    dOMSnapshotDOMNodeCurrentSourceURL :: Maybe T.Text,
+    -- | The url of the script (if any) that generates this node.
+    dOMSnapshotDOMNodeOriginURL :: Maybe T.Text,
+    -- | Scroll offsets, set when this node is a Document.
+    dOMSnapshotDOMNodeScrollOffsetX :: Maybe Double,
+    dOMSnapshotDOMNodeScrollOffsetY :: Maybe Double
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMSnapshotDOMNode where
+  parseJSON = A.withObject "DOMSnapshotDOMNode" $ \o -> DOMSnapshotDOMNode
+    <$> o A..: "nodeType"
+    <*> o A..: "nodeName"
+    <*> o A..: "nodeValue"
+    <*> o A..:? "textValue"
+    <*> o A..:? "inputValue"
+    <*> o A..:? "inputChecked"
+    <*> o A..:? "optionSelected"
+    <*> o A..: "backendNodeId"
+    <*> o A..:? "childNodeIndexes"
+    <*> o A..:? "attributes"
+    <*> o A..:? "pseudoElementIndexes"
+    <*> o A..:? "layoutNodeIndex"
+    <*> o A..:? "documentURL"
+    <*> o A..:? "baseURL"
+    <*> o A..:? "contentLanguage"
+    <*> o A..:? "documentEncoding"
+    <*> o A..:? "publicId"
+    <*> o A..:? "systemId"
+    <*> o A..:? "frameId"
+    <*> o A..:? "contentDocumentIndex"
+    <*> o A..:? "pseudoType"
+    <*> o A..:? "shadowRootType"
+    <*> o A..:? "isClickable"
+    <*> o A..:? "eventListeners"
+    <*> o A..:? "currentSourceURL"
+    <*> o A..:? "originURL"
+    <*> o A..:? "scrollOffsetX"
+    <*> o A..:? "scrollOffsetY"
+instance ToJSON DOMSnapshotDOMNode where
+  toJSON p = A.object $ catMaybes [
+    ("nodeType" A..=) <$> Just (dOMSnapshotDOMNodeNodeType p),
+    ("nodeName" A..=) <$> Just (dOMSnapshotDOMNodeNodeName p),
+    ("nodeValue" A..=) <$> Just (dOMSnapshotDOMNodeNodeValue p),
+    ("textValue" A..=) <$> (dOMSnapshotDOMNodeTextValue p),
+    ("inputValue" A..=) <$> (dOMSnapshotDOMNodeInputValue p),
+    ("inputChecked" A..=) <$> (dOMSnapshotDOMNodeInputChecked p),
+    ("optionSelected" A..=) <$> (dOMSnapshotDOMNodeOptionSelected p),
+    ("backendNodeId" A..=) <$> Just (dOMSnapshotDOMNodeBackendNodeId p),
+    ("childNodeIndexes" A..=) <$> (dOMSnapshotDOMNodeChildNodeIndexes p),
+    ("attributes" A..=) <$> (dOMSnapshotDOMNodeAttributes p),
+    ("pseudoElementIndexes" A..=) <$> (dOMSnapshotDOMNodePseudoElementIndexes p),
+    ("layoutNodeIndex" A..=) <$> (dOMSnapshotDOMNodeLayoutNodeIndex p),
+    ("documentURL" A..=) <$> (dOMSnapshotDOMNodeDocumentURL p),
+    ("baseURL" A..=) <$> (dOMSnapshotDOMNodeBaseURL p),
+    ("contentLanguage" A..=) <$> (dOMSnapshotDOMNodeContentLanguage p),
+    ("documentEncoding" A..=) <$> (dOMSnapshotDOMNodeDocumentEncoding p),
+    ("publicId" A..=) <$> (dOMSnapshotDOMNodePublicId p),
+    ("systemId" A..=) <$> (dOMSnapshotDOMNodeSystemId p),
+    ("frameId" A..=) <$> (dOMSnapshotDOMNodeFrameId p),
+    ("contentDocumentIndex" A..=) <$> (dOMSnapshotDOMNodeContentDocumentIndex p),
+    ("pseudoType" A..=) <$> (dOMSnapshotDOMNodePseudoType p),
+    ("shadowRootType" A..=) <$> (dOMSnapshotDOMNodeShadowRootType p),
+    ("isClickable" A..=) <$> (dOMSnapshotDOMNodeIsClickable p),
+    ("eventListeners" A..=) <$> (dOMSnapshotDOMNodeEventListeners p),
+    ("currentSourceURL" A..=) <$> (dOMSnapshotDOMNodeCurrentSourceURL p),
+    ("originURL" A..=) <$> (dOMSnapshotDOMNodeOriginURL p),
+    ("scrollOffsetX" A..=) <$> (dOMSnapshotDOMNodeScrollOffsetX p),
+    ("scrollOffsetY" A..=) <$> (dOMSnapshotDOMNodeScrollOffsetY p)
+    ]
+
+-- | Type 'DOMSnapshot.InlineTextBox'.
+--   Details of post layout rendered text positions. The exact layout should not be regarded as
+--   stable and may change between versions.
+data DOMSnapshotInlineTextBox = DOMSnapshotInlineTextBox
+  {
+    -- | The bounding box in document coordinates. Note that scroll offset of the document is ignored.
+    dOMSnapshotInlineTextBoxBoundingBox :: DOMPageNetworkEmulationSecurity.DOMRect,
+    -- | The starting index in characters, for this post layout textbox substring. Characters that
+    --   would be represented as a surrogate pair in UTF-16 have length 2.
+    dOMSnapshotInlineTextBoxStartCharacterIndex :: Int,
+    -- | The number of characters in this post layout textbox substring. Characters that would be
+    --   represented as a surrogate pair in UTF-16 have length 2.
+    dOMSnapshotInlineTextBoxNumCharacters :: Int
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMSnapshotInlineTextBox where
+  parseJSON = A.withObject "DOMSnapshotInlineTextBox" $ \o -> DOMSnapshotInlineTextBox
+    <$> o A..: "boundingBox"
+    <*> o A..: "startCharacterIndex"
+    <*> o A..: "numCharacters"
+instance ToJSON DOMSnapshotInlineTextBox where
+  toJSON p = A.object $ catMaybes [
+    ("boundingBox" A..=) <$> Just (dOMSnapshotInlineTextBoxBoundingBox p),
+    ("startCharacterIndex" A..=) <$> Just (dOMSnapshotInlineTextBoxStartCharacterIndex p),
+    ("numCharacters" A..=) <$> Just (dOMSnapshotInlineTextBoxNumCharacters p)
+    ]
+
+-- | Type 'DOMSnapshot.LayoutTreeNode'.
+--   Details of an element in the DOM tree with a LayoutObject.
+data DOMSnapshotLayoutTreeNode = DOMSnapshotLayoutTreeNode
+  {
+    -- | The index of the related DOM node in the `domNodes` array returned by `getSnapshot`.
+    dOMSnapshotLayoutTreeNodeDomNodeIndex :: Int,
+    -- | The bounding box in document coordinates. Note that scroll offset of the document is ignored.
+    dOMSnapshotLayoutTreeNodeBoundingBox :: DOMPageNetworkEmulationSecurity.DOMRect,
+    -- | Contents of the LayoutText, if any.
+    dOMSnapshotLayoutTreeNodeLayoutText :: Maybe T.Text,
+    -- | The post-layout inline text nodes, if any.
+    dOMSnapshotLayoutTreeNodeInlineTextNodes :: Maybe [DOMSnapshotInlineTextBox],
+    -- | Index into the `computedStyles` array returned by `getSnapshot`.
+    dOMSnapshotLayoutTreeNodeStyleIndex :: Maybe Int,
+    -- | Global paint order index, which is determined by the stacking order of the nodes. Nodes
+    --   that are painted together will have the same index. Only provided if includePaintOrder in
+    --   getSnapshot was true.
+    dOMSnapshotLayoutTreeNodePaintOrder :: Maybe Int,
+    -- | Set to true to indicate the element begins a new stacking context.
+    dOMSnapshotLayoutTreeNodeIsStackingContext :: Maybe Bool
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMSnapshotLayoutTreeNode where
+  parseJSON = A.withObject "DOMSnapshotLayoutTreeNode" $ \o -> DOMSnapshotLayoutTreeNode
+    <$> o A..: "domNodeIndex"
+    <*> o A..: "boundingBox"
+    <*> o A..:? "layoutText"
+    <*> o A..:? "inlineTextNodes"
+    <*> o A..:? "styleIndex"
+    <*> o A..:? "paintOrder"
+    <*> o A..:? "isStackingContext"
+instance ToJSON DOMSnapshotLayoutTreeNode where
+  toJSON p = A.object $ catMaybes [
+    ("domNodeIndex" A..=) <$> Just (dOMSnapshotLayoutTreeNodeDomNodeIndex p),
+    ("boundingBox" A..=) <$> Just (dOMSnapshotLayoutTreeNodeBoundingBox p),
+    ("layoutText" A..=) <$> (dOMSnapshotLayoutTreeNodeLayoutText p),
+    ("inlineTextNodes" A..=) <$> (dOMSnapshotLayoutTreeNodeInlineTextNodes p),
+    ("styleIndex" A..=) <$> (dOMSnapshotLayoutTreeNodeStyleIndex p),
+    ("paintOrder" A..=) <$> (dOMSnapshotLayoutTreeNodePaintOrder p),
+    ("isStackingContext" A..=) <$> (dOMSnapshotLayoutTreeNodeIsStackingContext p)
+    ]
+
+-- | Type 'DOMSnapshot.ComputedStyle'.
+--   A subset of the full ComputedStyle as defined by the request whitelist.
+data DOMSnapshotComputedStyle = DOMSnapshotComputedStyle
+  {
+    -- | Name/value pairs of computed style properties.
+    dOMSnapshotComputedStyleProperties :: [DOMSnapshotNameValue]
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMSnapshotComputedStyle where
+  parseJSON = A.withObject "DOMSnapshotComputedStyle" $ \o -> DOMSnapshotComputedStyle
+    <$> o A..: "properties"
+instance ToJSON DOMSnapshotComputedStyle where
+  toJSON p = A.object $ catMaybes [
+    ("properties" A..=) <$> Just (dOMSnapshotComputedStyleProperties p)
+    ]
+
+-- | Type 'DOMSnapshot.NameValue'.
+--   A name/value pair.
+data DOMSnapshotNameValue = DOMSnapshotNameValue
+  {
+    -- | Attribute/property name.
+    dOMSnapshotNameValueName :: T.Text,
+    -- | Attribute/property value.
+    dOMSnapshotNameValueValue :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMSnapshotNameValue where
+  parseJSON = A.withObject "DOMSnapshotNameValue" $ \o -> DOMSnapshotNameValue
+    <$> o A..: "name"
+    <*> o A..: "value"
+instance ToJSON DOMSnapshotNameValue where
+  toJSON p = A.object $ catMaybes [
+    ("name" A..=) <$> Just (dOMSnapshotNameValueName p),
+    ("value" A..=) <$> Just (dOMSnapshotNameValueValue p)
+    ]
+
+-- | Type 'DOMSnapshot.StringIndex'.
+--   Index of the string in the strings table.
+type DOMSnapshotStringIndex = Int
+
+-- | Type 'DOMSnapshot.ArrayOfStrings'.
+--   Index of the string in the strings table.
+type DOMSnapshotArrayOfStrings = [DOMSnapshotStringIndex]
+
+-- | Type 'DOMSnapshot.RareStringData'.
+--   Data that is only present on rare nodes.
+data DOMSnapshotRareStringData = DOMSnapshotRareStringData
+  {
+    dOMSnapshotRareStringDataIndex :: [Int],
+    dOMSnapshotRareStringDataValue :: [DOMSnapshotStringIndex]
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMSnapshotRareStringData where
+  parseJSON = A.withObject "DOMSnapshotRareStringData" $ \o -> DOMSnapshotRareStringData
+    <$> o A..: "index"
+    <*> o A..: "value"
+instance ToJSON DOMSnapshotRareStringData where
+  toJSON p = A.object $ catMaybes [
+    ("index" A..=) <$> Just (dOMSnapshotRareStringDataIndex p),
+    ("value" A..=) <$> Just (dOMSnapshotRareStringDataValue p)
+    ]
+
+-- | Type 'DOMSnapshot.RareBooleanData'.
+data DOMSnapshotRareBooleanData = DOMSnapshotRareBooleanData
+  {
+    dOMSnapshotRareBooleanDataIndex :: [Int]
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMSnapshotRareBooleanData where
+  parseJSON = A.withObject "DOMSnapshotRareBooleanData" $ \o -> DOMSnapshotRareBooleanData
+    <$> o A..: "index"
+instance ToJSON DOMSnapshotRareBooleanData where
+  toJSON p = A.object $ catMaybes [
+    ("index" A..=) <$> Just (dOMSnapshotRareBooleanDataIndex p)
+    ]
+
+-- | Type 'DOMSnapshot.RareIntegerData'.
+data DOMSnapshotRareIntegerData = DOMSnapshotRareIntegerData
+  {
+    dOMSnapshotRareIntegerDataIndex :: [Int],
+    dOMSnapshotRareIntegerDataValue :: [Int]
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMSnapshotRareIntegerData where
+  parseJSON = A.withObject "DOMSnapshotRareIntegerData" $ \o -> DOMSnapshotRareIntegerData
+    <$> o A..: "index"
+    <*> o A..: "value"
+instance ToJSON DOMSnapshotRareIntegerData where
+  toJSON p = A.object $ catMaybes [
+    ("index" A..=) <$> Just (dOMSnapshotRareIntegerDataIndex p),
+    ("value" A..=) <$> Just (dOMSnapshotRareIntegerDataValue p)
+    ]
+
+-- | Type 'DOMSnapshot.Rectangle'.
+type DOMSnapshotRectangle = [Double]
+
+-- | Type 'DOMSnapshot.DocumentSnapshot'.
+--   Document snapshot.
+data DOMSnapshotDocumentSnapshot = DOMSnapshotDocumentSnapshot
+  {
+    -- | Document URL that `Document` or `FrameOwner` node points to.
+    dOMSnapshotDocumentSnapshotDocumentURL :: DOMSnapshotStringIndex,
+    -- | Document title.
+    dOMSnapshotDocumentSnapshotTitle :: DOMSnapshotStringIndex,
+    -- | Base URL that `Document` or `FrameOwner` node uses for URL completion.
+    dOMSnapshotDocumentSnapshotBaseURL :: DOMSnapshotStringIndex,
+    -- | Contains the document's content language.
+    dOMSnapshotDocumentSnapshotContentLanguage :: DOMSnapshotStringIndex,
+    -- | Contains the document's character set encoding.
+    dOMSnapshotDocumentSnapshotEncodingName :: DOMSnapshotStringIndex,
+    -- | `DocumentType` node's publicId.
+    dOMSnapshotDocumentSnapshotPublicId :: DOMSnapshotStringIndex,
+    -- | `DocumentType` node's systemId.
+    dOMSnapshotDocumentSnapshotSystemId :: DOMSnapshotStringIndex,
+    -- | Frame ID for frame owner elements and also for the document node.
+    dOMSnapshotDocumentSnapshotFrameId :: DOMSnapshotStringIndex,
+    -- | A table with dom nodes.
+    dOMSnapshotDocumentSnapshotNodes :: DOMSnapshotNodeTreeSnapshot,
+    -- | The nodes in the layout tree.
+    dOMSnapshotDocumentSnapshotLayout :: DOMSnapshotLayoutTreeSnapshot,
+    -- | The post-layout inline text nodes.
+    dOMSnapshotDocumentSnapshotTextBoxes :: DOMSnapshotTextBoxSnapshot,
+    -- | Horizontal scroll offset.
+    dOMSnapshotDocumentSnapshotScrollOffsetX :: Maybe Double,
+    -- | Vertical scroll offset.
+    dOMSnapshotDocumentSnapshotScrollOffsetY :: Maybe Double,
+    -- | Document content width.
+    dOMSnapshotDocumentSnapshotContentWidth :: Maybe Double,
+    -- | Document content height.
+    dOMSnapshotDocumentSnapshotContentHeight :: Maybe Double
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMSnapshotDocumentSnapshot where
+  parseJSON = A.withObject "DOMSnapshotDocumentSnapshot" $ \o -> DOMSnapshotDocumentSnapshot
+    <$> o A..: "documentURL"
+    <*> o A..: "title"
+    <*> o A..: "baseURL"
+    <*> o A..: "contentLanguage"
+    <*> o A..: "encodingName"
+    <*> o A..: "publicId"
+    <*> o A..: "systemId"
+    <*> o A..: "frameId"
+    <*> o A..: "nodes"
+    <*> o A..: "layout"
+    <*> o A..: "textBoxes"
+    <*> o A..:? "scrollOffsetX"
+    <*> o A..:? "scrollOffsetY"
+    <*> o A..:? "contentWidth"
+    <*> o A..:? "contentHeight"
+instance ToJSON DOMSnapshotDocumentSnapshot where
+  toJSON p = A.object $ catMaybes [
+    ("documentURL" A..=) <$> Just (dOMSnapshotDocumentSnapshotDocumentURL p),
+    ("title" A..=) <$> Just (dOMSnapshotDocumentSnapshotTitle p),
+    ("baseURL" A..=) <$> Just (dOMSnapshotDocumentSnapshotBaseURL p),
+    ("contentLanguage" A..=) <$> Just (dOMSnapshotDocumentSnapshotContentLanguage p),
+    ("encodingName" A..=) <$> Just (dOMSnapshotDocumentSnapshotEncodingName p),
+    ("publicId" A..=) <$> Just (dOMSnapshotDocumentSnapshotPublicId p),
+    ("systemId" A..=) <$> Just (dOMSnapshotDocumentSnapshotSystemId p),
+    ("frameId" A..=) <$> Just (dOMSnapshotDocumentSnapshotFrameId p),
+    ("nodes" A..=) <$> Just (dOMSnapshotDocumentSnapshotNodes p),
+    ("layout" A..=) <$> Just (dOMSnapshotDocumentSnapshotLayout p),
+    ("textBoxes" A..=) <$> Just (dOMSnapshotDocumentSnapshotTextBoxes p),
+    ("scrollOffsetX" A..=) <$> (dOMSnapshotDocumentSnapshotScrollOffsetX p),
+    ("scrollOffsetY" A..=) <$> (dOMSnapshotDocumentSnapshotScrollOffsetY p),
+    ("contentWidth" A..=) <$> (dOMSnapshotDocumentSnapshotContentWidth p),
+    ("contentHeight" A..=) <$> (dOMSnapshotDocumentSnapshotContentHeight p)
+    ]
+
+-- | Type 'DOMSnapshot.NodeTreeSnapshot'.
+--   Table containing nodes.
+data DOMSnapshotNodeTreeSnapshot = DOMSnapshotNodeTreeSnapshot
+  {
+    -- | Parent node index.
+    dOMSnapshotNodeTreeSnapshotParentIndex :: Maybe [Int],
+    -- | `Node`'s nodeType.
+    dOMSnapshotNodeTreeSnapshotNodeType :: Maybe [Int],
+    -- | Type of the shadow root the `Node` is in. String values are equal to the `ShadowRootType` enum.
+    dOMSnapshotNodeTreeSnapshotShadowRootType :: Maybe DOMSnapshotRareStringData,
+    -- | `Node`'s nodeName.
+    dOMSnapshotNodeTreeSnapshotNodeName :: Maybe [DOMSnapshotStringIndex],
+    -- | `Node`'s nodeValue.
+    dOMSnapshotNodeTreeSnapshotNodeValue :: Maybe [DOMSnapshotStringIndex],
+    -- | `Node`'s id, corresponds to DOM.Node.backendNodeId.
+    dOMSnapshotNodeTreeSnapshotBackendNodeId :: Maybe [DOMPageNetworkEmulationSecurity.DOMBackendNodeId],
+    -- | Attributes of an `Element` node. Flatten name, value pairs.
+    dOMSnapshotNodeTreeSnapshotAttributes :: Maybe [DOMSnapshotArrayOfStrings],
+    -- | Only set for textarea elements, contains the text value.
+    dOMSnapshotNodeTreeSnapshotTextValue :: Maybe DOMSnapshotRareStringData,
+    -- | Only set for input elements, contains the input's associated text value.
+    dOMSnapshotNodeTreeSnapshotInputValue :: Maybe DOMSnapshotRareStringData,
+    -- | Only set for radio and checkbox input elements, indicates if the element has been checked
+    dOMSnapshotNodeTreeSnapshotInputChecked :: Maybe DOMSnapshotRareBooleanData,
+    -- | Only set for option elements, indicates if the element has been selected
+    dOMSnapshotNodeTreeSnapshotOptionSelected :: Maybe DOMSnapshotRareBooleanData,
+    -- | The index of the document in the list of the snapshot documents.
+    dOMSnapshotNodeTreeSnapshotContentDocumentIndex :: Maybe DOMSnapshotRareIntegerData,
+    -- | Type of a pseudo element node.
+    dOMSnapshotNodeTreeSnapshotPseudoType :: Maybe DOMSnapshotRareStringData,
+    -- | Pseudo element identifier for this node. Only present if there is a
+    --   valid pseudoType.
+    dOMSnapshotNodeTreeSnapshotPseudoIdentifier :: Maybe DOMSnapshotRareStringData,
+    -- | Whether this DOM node responds to mouse clicks. This includes nodes that have had click
+    --   event listeners attached via JavaScript as well as anchor tags that naturally navigate when
+    --   clicked.
+    dOMSnapshotNodeTreeSnapshotIsClickable :: Maybe DOMSnapshotRareBooleanData,
+    -- | The selected url for nodes with a srcset attribute.
+    dOMSnapshotNodeTreeSnapshotCurrentSourceURL :: Maybe DOMSnapshotRareStringData,
+    -- | The url of the script (if any) that generates this node.
+    dOMSnapshotNodeTreeSnapshotOriginURL :: Maybe DOMSnapshotRareStringData
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMSnapshotNodeTreeSnapshot where
+  parseJSON = A.withObject "DOMSnapshotNodeTreeSnapshot" $ \o -> DOMSnapshotNodeTreeSnapshot
+    <$> o A..:? "parentIndex"
+    <*> o A..:? "nodeType"
+    <*> o A..:? "shadowRootType"
+    <*> o A..:? "nodeName"
+    <*> o A..:? "nodeValue"
+    <*> o A..:? "backendNodeId"
+    <*> o A..:? "attributes"
+    <*> o A..:? "textValue"
+    <*> o A..:? "inputValue"
+    <*> o A..:? "inputChecked"
+    <*> o A..:? "optionSelected"
+    <*> o A..:? "contentDocumentIndex"
+    <*> o A..:? "pseudoType"
+    <*> o A..:? "pseudoIdentifier"
+    <*> o A..:? "isClickable"
+    <*> o A..:? "currentSourceURL"
+    <*> o A..:? "originURL"
+instance ToJSON DOMSnapshotNodeTreeSnapshot where
+  toJSON p = A.object $ catMaybes [
+    ("parentIndex" A..=) <$> (dOMSnapshotNodeTreeSnapshotParentIndex p),
+    ("nodeType" A..=) <$> (dOMSnapshotNodeTreeSnapshotNodeType p),
+    ("shadowRootType" A..=) <$> (dOMSnapshotNodeTreeSnapshotShadowRootType p),
+    ("nodeName" A..=) <$> (dOMSnapshotNodeTreeSnapshotNodeName p),
+    ("nodeValue" A..=) <$> (dOMSnapshotNodeTreeSnapshotNodeValue p),
+    ("backendNodeId" A..=) <$> (dOMSnapshotNodeTreeSnapshotBackendNodeId p),
+    ("attributes" A..=) <$> (dOMSnapshotNodeTreeSnapshotAttributes p),
+    ("textValue" A..=) <$> (dOMSnapshotNodeTreeSnapshotTextValue p),
+    ("inputValue" A..=) <$> (dOMSnapshotNodeTreeSnapshotInputValue p),
+    ("inputChecked" A..=) <$> (dOMSnapshotNodeTreeSnapshotInputChecked p),
+    ("optionSelected" A..=) <$> (dOMSnapshotNodeTreeSnapshotOptionSelected p),
+    ("contentDocumentIndex" A..=) <$> (dOMSnapshotNodeTreeSnapshotContentDocumentIndex p),
+    ("pseudoType" A..=) <$> (dOMSnapshotNodeTreeSnapshotPseudoType p),
+    ("pseudoIdentifier" A..=) <$> (dOMSnapshotNodeTreeSnapshotPseudoIdentifier p),
+    ("isClickable" A..=) <$> (dOMSnapshotNodeTreeSnapshotIsClickable p),
+    ("currentSourceURL" A..=) <$> (dOMSnapshotNodeTreeSnapshotCurrentSourceURL p),
+    ("originURL" A..=) <$> (dOMSnapshotNodeTreeSnapshotOriginURL p)
+    ]
+
+-- | Type 'DOMSnapshot.LayoutTreeSnapshot'.
+--   Table of details of an element in the DOM tree with a LayoutObject.
+data DOMSnapshotLayoutTreeSnapshot = DOMSnapshotLayoutTreeSnapshot
+  {
+    -- | Index of the corresponding node in the `NodeTreeSnapshot` array returned by `captureSnapshot`.
+    dOMSnapshotLayoutTreeSnapshotNodeIndex :: [Int],
+    -- | Array of indexes specifying computed style strings, filtered according to the `computedStyles` parameter passed to `captureSnapshot`.
+    dOMSnapshotLayoutTreeSnapshotStyles :: [DOMSnapshotArrayOfStrings],
+    -- | The absolute position bounding box.
+    dOMSnapshotLayoutTreeSnapshotBounds :: [DOMSnapshotRectangle],
+    -- | Contents of the LayoutText, if any.
+    dOMSnapshotLayoutTreeSnapshotText :: [DOMSnapshotStringIndex],
+    -- | Stacking context information.
+    dOMSnapshotLayoutTreeSnapshotStackingContexts :: DOMSnapshotRareBooleanData,
+    -- | Global paint order index, which is determined by the stacking order of the nodes. Nodes
+    --   that are painted together will have the same index. Only provided if includePaintOrder in
+    --   captureSnapshot was true.
+    dOMSnapshotLayoutTreeSnapshotPaintOrders :: Maybe [Int],
+    -- | The offset rect of nodes. Only available when includeDOMRects is set to true
+    dOMSnapshotLayoutTreeSnapshotOffsetRects :: Maybe [DOMSnapshotRectangle],
+    -- | The scroll rect of nodes. Only available when includeDOMRects is set to true
+    dOMSnapshotLayoutTreeSnapshotScrollRects :: Maybe [DOMSnapshotRectangle],
+    -- | The client rect of nodes. Only available when includeDOMRects is set to true
+    dOMSnapshotLayoutTreeSnapshotClientRects :: Maybe [DOMSnapshotRectangle],
+    -- | The list of background colors that are blended with colors of overlapping elements.
+    dOMSnapshotLayoutTreeSnapshotBlendedBackgroundColors :: Maybe [DOMSnapshotStringIndex],
+    -- | The list of computed text opacities.
+    dOMSnapshotLayoutTreeSnapshotTextColorOpacities :: Maybe [Double]
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMSnapshotLayoutTreeSnapshot where
+  parseJSON = A.withObject "DOMSnapshotLayoutTreeSnapshot" $ \o -> DOMSnapshotLayoutTreeSnapshot
+    <$> o A..: "nodeIndex"
+    <*> o A..: "styles"
+    <*> o A..: "bounds"
+    <*> o A..: "text"
+    <*> o A..: "stackingContexts"
+    <*> o A..:? "paintOrders"
+    <*> o A..:? "offsetRects"
+    <*> o A..:? "scrollRects"
+    <*> o A..:? "clientRects"
+    <*> o A..:? "blendedBackgroundColors"
+    <*> o A..:? "textColorOpacities"
+instance ToJSON DOMSnapshotLayoutTreeSnapshot where
+  toJSON p = A.object $ catMaybes [
+    ("nodeIndex" A..=) <$> Just (dOMSnapshotLayoutTreeSnapshotNodeIndex p),
+    ("styles" A..=) <$> Just (dOMSnapshotLayoutTreeSnapshotStyles p),
+    ("bounds" A..=) <$> Just (dOMSnapshotLayoutTreeSnapshotBounds p),
+    ("text" A..=) <$> Just (dOMSnapshotLayoutTreeSnapshotText p),
+    ("stackingContexts" A..=) <$> Just (dOMSnapshotLayoutTreeSnapshotStackingContexts p),
+    ("paintOrders" A..=) <$> (dOMSnapshotLayoutTreeSnapshotPaintOrders p),
+    ("offsetRects" A..=) <$> (dOMSnapshotLayoutTreeSnapshotOffsetRects p),
+    ("scrollRects" A..=) <$> (dOMSnapshotLayoutTreeSnapshotScrollRects p),
+    ("clientRects" A..=) <$> (dOMSnapshotLayoutTreeSnapshotClientRects p),
+    ("blendedBackgroundColors" A..=) <$> (dOMSnapshotLayoutTreeSnapshotBlendedBackgroundColors p),
+    ("textColorOpacities" A..=) <$> (dOMSnapshotLayoutTreeSnapshotTextColorOpacities p)
+    ]
+
+-- | Type 'DOMSnapshot.TextBoxSnapshot'.
+--   Table of details of the post layout rendered text positions. The exact layout should not be regarded as
+--   stable and may change between versions.
+data DOMSnapshotTextBoxSnapshot = DOMSnapshotTextBoxSnapshot
+  {
+    -- | Index of the layout tree node that owns this box collection.
+    dOMSnapshotTextBoxSnapshotLayoutIndex :: [Int],
+    -- | The absolute position bounding box.
+    dOMSnapshotTextBoxSnapshotBounds :: [DOMSnapshotRectangle],
+    -- | The starting index in characters, for this post layout textbox substring. Characters that
+    --   would be represented as a surrogate pair in UTF-16 have length 2.
+    dOMSnapshotTextBoxSnapshotStart :: [Int],
+    -- | The number of characters in this post layout textbox substring. Characters that would be
+    --   represented as a surrogate pair in UTF-16 have length 2.
+    dOMSnapshotTextBoxSnapshotLength :: [Int]
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMSnapshotTextBoxSnapshot where
+  parseJSON = A.withObject "DOMSnapshotTextBoxSnapshot" $ \o -> DOMSnapshotTextBoxSnapshot
+    <$> o A..: "layoutIndex"
+    <*> o A..: "bounds"
+    <*> o A..: "start"
+    <*> o A..: "length"
+instance ToJSON DOMSnapshotTextBoxSnapshot where
+  toJSON p = A.object $ catMaybes [
+    ("layoutIndex" A..=) <$> Just (dOMSnapshotTextBoxSnapshotLayoutIndex p),
+    ("bounds" A..=) <$> Just (dOMSnapshotTextBoxSnapshotBounds p),
+    ("start" A..=) <$> Just (dOMSnapshotTextBoxSnapshotStart p),
+    ("length" A..=) <$> Just (dOMSnapshotTextBoxSnapshotLength p)
+    ]
+
+-- | Disables DOM snapshot agent for the given page.
+
+-- | Parameters of the 'DOMSnapshot.disable' command.
+data PDOMSnapshotDisable = PDOMSnapshotDisable
+  deriving (Eq, Show)
+pDOMSnapshotDisable
+  :: PDOMSnapshotDisable
+pDOMSnapshotDisable
+  = PDOMSnapshotDisable
+instance ToJSON PDOMSnapshotDisable where
+  toJSON _ = A.Null
+instance Command PDOMSnapshotDisable where
+  type CommandResponse PDOMSnapshotDisable = ()
+  commandName _ = "DOMSnapshot.disable"
+  fromJSON = const . A.Success . const ()
+
+-- | Enables DOM snapshot agent for the given page.
+
+-- | Parameters of the 'DOMSnapshot.enable' command.
+data PDOMSnapshotEnable = PDOMSnapshotEnable
+  deriving (Eq, Show)
+pDOMSnapshotEnable
+  :: PDOMSnapshotEnable
+pDOMSnapshotEnable
+  = PDOMSnapshotEnable
+instance ToJSON PDOMSnapshotEnable where
+  toJSON _ = A.Null
+instance Command PDOMSnapshotEnable where
+  type CommandResponse PDOMSnapshotEnable = ()
+  commandName _ = "DOMSnapshot.enable"
+  fromJSON = const . A.Success . const ()
+
+-- | Returns a document snapshot, including the full DOM tree of the root node (including iframes,
+--   template contents, and imported documents) in a flattened array, as well as layout and
+--   white-listed computed style information for the nodes. Shadow DOM in the returned DOM tree is
+--   flattened.
+
+-- | Parameters of the 'DOMSnapshot.captureSnapshot' command.
+data PDOMSnapshotCaptureSnapshot = PDOMSnapshotCaptureSnapshot
+  {
+    -- | Whitelist of computed styles to return.
+    pDOMSnapshotCaptureSnapshotComputedStyles :: [T.Text],
+    -- | Whether to include layout object paint orders into the snapshot.
+    pDOMSnapshotCaptureSnapshotIncludePaintOrder :: Maybe Bool,
+    -- | Whether to include DOM rectangles (offsetRects, clientRects, scrollRects) into the snapshot
+    pDOMSnapshotCaptureSnapshotIncludeDOMRects :: Maybe Bool,
+    -- | Whether to include blended background colors in the snapshot (default: false).
+    --   Blended background color is achieved by blending background colors of all elements
+    --   that overlap with the current element.
+    pDOMSnapshotCaptureSnapshotIncludeBlendedBackgroundColors :: Maybe Bool,
+    -- | Whether to include text color opacity in the snapshot (default: false).
+    --   An element might have the opacity property set that affects the text color of the element.
+    --   The final text color opacity is computed based on the opacity of all overlapping elements.
+    pDOMSnapshotCaptureSnapshotIncludeTextColorOpacities :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pDOMSnapshotCaptureSnapshot
+  {-
+  -- | Whitelist of computed styles to return.
+  -}
+  :: [T.Text]
+  -> PDOMSnapshotCaptureSnapshot
+pDOMSnapshotCaptureSnapshot
+  arg_pDOMSnapshotCaptureSnapshotComputedStyles
+  = PDOMSnapshotCaptureSnapshot
+    arg_pDOMSnapshotCaptureSnapshotComputedStyles
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PDOMSnapshotCaptureSnapshot where
+  toJSON p = A.object $ catMaybes [
+    ("computedStyles" A..=) <$> Just (pDOMSnapshotCaptureSnapshotComputedStyles p),
+    ("includePaintOrder" A..=) <$> (pDOMSnapshotCaptureSnapshotIncludePaintOrder p),
+    ("includeDOMRects" A..=) <$> (pDOMSnapshotCaptureSnapshotIncludeDOMRects p),
+    ("includeBlendedBackgroundColors" A..=) <$> (pDOMSnapshotCaptureSnapshotIncludeBlendedBackgroundColors p),
+    ("includeTextColorOpacities" A..=) <$> (pDOMSnapshotCaptureSnapshotIncludeTextColorOpacities p)
+    ]
+data DOMSnapshotCaptureSnapshot = DOMSnapshotCaptureSnapshot
+  {
+    -- | The nodes in the DOM tree. The DOMNode at index 0 corresponds to the root document.
+    dOMSnapshotCaptureSnapshotDocuments :: [DOMSnapshotDocumentSnapshot],
+    -- | Shared string table that all string properties refer to with indexes.
+    dOMSnapshotCaptureSnapshotStrings :: [T.Text]
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMSnapshotCaptureSnapshot where
+  parseJSON = A.withObject "DOMSnapshotCaptureSnapshot" $ \o -> DOMSnapshotCaptureSnapshot
+    <$> o A..: "documents"
+    <*> o A..: "strings"
+instance Command PDOMSnapshotCaptureSnapshot where
+  type CommandResponse PDOMSnapshotCaptureSnapshot = DOMSnapshotCaptureSnapshot
+  commandName _ = "DOMSnapshot.captureSnapshot"
+
diff --git a/src/CDP/Domains/DOMStorage.hs b/src/CDP/Domains/DOMStorage.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains/DOMStorage.hs
@@ -0,0 +1,287 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+
+
+{- |
+= DOMStorage
+
+Query and modify DOM storage.
+-}
+
+
+module CDP.Domains.DOMStorage (module CDP.Domains.DOMStorage) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+
+
+
+-- | Type 'DOMStorage.SerializedStorageKey'.
+type DOMStorageSerializedStorageKey = T.Text
+
+-- | Type 'DOMStorage.StorageId'.
+--   DOM Storage identifier.
+data DOMStorageStorageId = DOMStorageStorageId
+  {
+    -- | Security origin for the storage.
+    dOMStorageStorageIdSecurityOrigin :: Maybe T.Text,
+    -- | Represents a key by which DOM Storage keys its CachedStorageAreas
+    dOMStorageStorageIdStorageKey :: Maybe DOMStorageSerializedStorageKey,
+    -- | Whether the storage is local storage (not session storage).
+    dOMStorageStorageIdIsLocalStorage :: Bool
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMStorageStorageId where
+  parseJSON = A.withObject "DOMStorageStorageId" $ \o -> DOMStorageStorageId
+    <$> o A..:? "securityOrigin"
+    <*> o A..:? "storageKey"
+    <*> o A..: "isLocalStorage"
+instance ToJSON DOMStorageStorageId where
+  toJSON p = A.object $ catMaybes [
+    ("securityOrigin" A..=) <$> (dOMStorageStorageIdSecurityOrigin p),
+    ("storageKey" A..=) <$> (dOMStorageStorageIdStorageKey p),
+    ("isLocalStorage" A..=) <$> Just (dOMStorageStorageIdIsLocalStorage p)
+    ]
+
+-- | Type 'DOMStorage.Item'.
+--   DOM Storage item.
+type DOMStorageItem = [T.Text]
+
+-- | Type of the 'DOMStorage.domStorageItemAdded' event.
+data DOMStorageDomStorageItemAdded = DOMStorageDomStorageItemAdded
+  {
+    dOMStorageDomStorageItemAddedStorageId :: DOMStorageStorageId,
+    dOMStorageDomStorageItemAddedKey :: T.Text,
+    dOMStorageDomStorageItemAddedNewValue :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMStorageDomStorageItemAdded where
+  parseJSON = A.withObject "DOMStorageDomStorageItemAdded" $ \o -> DOMStorageDomStorageItemAdded
+    <$> o A..: "storageId"
+    <*> o A..: "key"
+    <*> o A..: "newValue"
+instance Event DOMStorageDomStorageItemAdded where
+  eventName _ = "DOMStorage.domStorageItemAdded"
+
+-- | Type of the 'DOMStorage.domStorageItemRemoved' event.
+data DOMStorageDomStorageItemRemoved = DOMStorageDomStorageItemRemoved
+  {
+    dOMStorageDomStorageItemRemovedStorageId :: DOMStorageStorageId,
+    dOMStorageDomStorageItemRemovedKey :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMStorageDomStorageItemRemoved where
+  parseJSON = A.withObject "DOMStorageDomStorageItemRemoved" $ \o -> DOMStorageDomStorageItemRemoved
+    <$> o A..: "storageId"
+    <*> o A..: "key"
+instance Event DOMStorageDomStorageItemRemoved where
+  eventName _ = "DOMStorage.domStorageItemRemoved"
+
+-- | Type of the 'DOMStorage.domStorageItemUpdated' event.
+data DOMStorageDomStorageItemUpdated = DOMStorageDomStorageItemUpdated
+  {
+    dOMStorageDomStorageItemUpdatedStorageId :: DOMStorageStorageId,
+    dOMStorageDomStorageItemUpdatedKey :: T.Text,
+    dOMStorageDomStorageItemUpdatedOldValue :: T.Text,
+    dOMStorageDomStorageItemUpdatedNewValue :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMStorageDomStorageItemUpdated where
+  parseJSON = A.withObject "DOMStorageDomStorageItemUpdated" $ \o -> DOMStorageDomStorageItemUpdated
+    <$> o A..: "storageId"
+    <*> o A..: "key"
+    <*> o A..: "oldValue"
+    <*> o A..: "newValue"
+instance Event DOMStorageDomStorageItemUpdated where
+  eventName _ = "DOMStorage.domStorageItemUpdated"
+
+-- | Type of the 'DOMStorage.domStorageItemsCleared' event.
+data DOMStorageDomStorageItemsCleared = DOMStorageDomStorageItemsCleared
+  {
+    dOMStorageDomStorageItemsClearedStorageId :: DOMStorageStorageId
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMStorageDomStorageItemsCleared where
+  parseJSON = A.withObject "DOMStorageDomStorageItemsCleared" $ \o -> DOMStorageDomStorageItemsCleared
+    <$> o A..: "storageId"
+instance Event DOMStorageDomStorageItemsCleared where
+  eventName _ = "DOMStorage.domStorageItemsCleared"
+
+
+-- | Parameters of the 'DOMStorage.clear' command.
+data PDOMStorageClear = PDOMStorageClear
+  {
+    pDOMStorageClearStorageId :: DOMStorageStorageId
+  }
+  deriving (Eq, Show)
+pDOMStorageClear
+  :: DOMStorageStorageId
+  -> PDOMStorageClear
+pDOMStorageClear
+  arg_pDOMStorageClearStorageId
+  = PDOMStorageClear
+    arg_pDOMStorageClearStorageId
+instance ToJSON PDOMStorageClear where
+  toJSON p = A.object $ catMaybes [
+    ("storageId" A..=) <$> Just (pDOMStorageClearStorageId p)
+    ]
+instance Command PDOMStorageClear where
+  type CommandResponse PDOMStorageClear = ()
+  commandName _ = "DOMStorage.clear"
+  fromJSON = const . A.Success . const ()
+
+-- | Disables storage tracking, prevents storage events from being sent to the client.
+
+-- | Parameters of the 'DOMStorage.disable' command.
+data PDOMStorageDisable = PDOMStorageDisable
+  deriving (Eq, Show)
+pDOMStorageDisable
+  :: PDOMStorageDisable
+pDOMStorageDisable
+  = PDOMStorageDisable
+instance ToJSON PDOMStorageDisable where
+  toJSON _ = A.Null
+instance Command PDOMStorageDisable where
+  type CommandResponse PDOMStorageDisable = ()
+  commandName _ = "DOMStorage.disable"
+  fromJSON = const . A.Success . const ()
+
+-- | Enables storage tracking, storage events will now be delivered to the client.
+
+-- | Parameters of the 'DOMStorage.enable' command.
+data PDOMStorageEnable = PDOMStorageEnable
+  deriving (Eq, Show)
+pDOMStorageEnable
+  :: PDOMStorageEnable
+pDOMStorageEnable
+  = PDOMStorageEnable
+instance ToJSON PDOMStorageEnable where
+  toJSON _ = A.Null
+instance Command PDOMStorageEnable where
+  type CommandResponse PDOMStorageEnable = ()
+  commandName _ = "DOMStorage.enable"
+  fromJSON = const . A.Success . const ()
+
+
+-- | Parameters of the 'DOMStorage.getDOMStorageItems' command.
+data PDOMStorageGetDOMStorageItems = PDOMStorageGetDOMStorageItems
+  {
+    pDOMStorageGetDOMStorageItemsStorageId :: DOMStorageStorageId
+  }
+  deriving (Eq, Show)
+pDOMStorageGetDOMStorageItems
+  :: DOMStorageStorageId
+  -> PDOMStorageGetDOMStorageItems
+pDOMStorageGetDOMStorageItems
+  arg_pDOMStorageGetDOMStorageItemsStorageId
+  = PDOMStorageGetDOMStorageItems
+    arg_pDOMStorageGetDOMStorageItemsStorageId
+instance ToJSON PDOMStorageGetDOMStorageItems where
+  toJSON p = A.object $ catMaybes [
+    ("storageId" A..=) <$> Just (pDOMStorageGetDOMStorageItemsStorageId p)
+    ]
+data DOMStorageGetDOMStorageItems = DOMStorageGetDOMStorageItems
+  {
+    dOMStorageGetDOMStorageItemsEntries :: [DOMStorageItem]
+  }
+  deriving (Eq, Show)
+instance FromJSON DOMStorageGetDOMStorageItems where
+  parseJSON = A.withObject "DOMStorageGetDOMStorageItems" $ \o -> DOMStorageGetDOMStorageItems
+    <$> o A..: "entries"
+instance Command PDOMStorageGetDOMStorageItems where
+  type CommandResponse PDOMStorageGetDOMStorageItems = DOMStorageGetDOMStorageItems
+  commandName _ = "DOMStorage.getDOMStorageItems"
+
+
+-- | Parameters of the 'DOMStorage.removeDOMStorageItem' command.
+data PDOMStorageRemoveDOMStorageItem = PDOMStorageRemoveDOMStorageItem
+  {
+    pDOMStorageRemoveDOMStorageItemStorageId :: DOMStorageStorageId,
+    pDOMStorageRemoveDOMStorageItemKey :: T.Text
+  }
+  deriving (Eq, Show)
+pDOMStorageRemoveDOMStorageItem
+  :: DOMStorageStorageId
+  -> T.Text
+  -> PDOMStorageRemoveDOMStorageItem
+pDOMStorageRemoveDOMStorageItem
+  arg_pDOMStorageRemoveDOMStorageItemStorageId
+  arg_pDOMStorageRemoveDOMStorageItemKey
+  = PDOMStorageRemoveDOMStorageItem
+    arg_pDOMStorageRemoveDOMStorageItemStorageId
+    arg_pDOMStorageRemoveDOMStorageItemKey
+instance ToJSON PDOMStorageRemoveDOMStorageItem where
+  toJSON p = A.object $ catMaybes [
+    ("storageId" A..=) <$> Just (pDOMStorageRemoveDOMStorageItemStorageId p),
+    ("key" A..=) <$> Just (pDOMStorageRemoveDOMStorageItemKey p)
+    ]
+instance Command PDOMStorageRemoveDOMStorageItem where
+  type CommandResponse PDOMStorageRemoveDOMStorageItem = ()
+  commandName _ = "DOMStorage.removeDOMStorageItem"
+  fromJSON = const . A.Success . const ()
+
+
+-- | Parameters of the 'DOMStorage.setDOMStorageItem' command.
+data PDOMStorageSetDOMStorageItem = PDOMStorageSetDOMStorageItem
+  {
+    pDOMStorageSetDOMStorageItemStorageId :: DOMStorageStorageId,
+    pDOMStorageSetDOMStorageItemKey :: T.Text,
+    pDOMStorageSetDOMStorageItemValue :: T.Text
+  }
+  deriving (Eq, Show)
+pDOMStorageSetDOMStorageItem
+  :: DOMStorageStorageId
+  -> T.Text
+  -> T.Text
+  -> PDOMStorageSetDOMStorageItem
+pDOMStorageSetDOMStorageItem
+  arg_pDOMStorageSetDOMStorageItemStorageId
+  arg_pDOMStorageSetDOMStorageItemKey
+  arg_pDOMStorageSetDOMStorageItemValue
+  = PDOMStorageSetDOMStorageItem
+    arg_pDOMStorageSetDOMStorageItemStorageId
+    arg_pDOMStorageSetDOMStorageItemKey
+    arg_pDOMStorageSetDOMStorageItemValue
+instance ToJSON PDOMStorageSetDOMStorageItem where
+  toJSON p = A.object $ catMaybes [
+    ("storageId" A..=) <$> Just (pDOMStorageSetDOMStorageItemStorageId p),
+    ("key" A..=) <$> Just (pDOMStorageSetDOMStorageItemKey p),
+    ("value" A..=) <$> Just (pDOMStorageSetDOMStorageItemValue p)
+    ]
+instance Command PDOMStorageSetDOMStorageItem where
+  type CommandResponse PDOMStorageSetDOMStorageItem = ()
+  commandName _ = "DOMStorage.setDOMStorageItem"
+  fromJSON = const . A.Success . const ()
+
diff --git a/src/CDP/Domains/Database.hs b/src/CDP/Domains/Database.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains/Database.hs
@@ -0,0 +1,214 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+
+
+{- |
+= Database
+
+-}
+
+
+module CDP.Domains.Database (module CDP.Domains.Database) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+
+
+
+-- | Type 'Database.DatabaseId'.
+--   Unique identifier of Database object.
+type DatabaseDatabaseId = T.Text
+
+-- | Type 'Database.Database'.
+--   Database object.
+data DatabaseDatabase = DatabaseDatabase
+  {
+    -- | Database ID.
+    databaseDatabaseId :: DatabaseDatabaseId,
+    -- | Database domain.
+    databaseDatabaseDomain :: T.Text,
+    -- | Database name.
+    databaseDatabaseName :: T.Text,
+    -- | Database version.
+    databaseDatabaseVersion :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON DatabaseDatabase where
+  parseJSON = A.withObject "DatabaseDatabase" $ \o -> DatabaseDatabase
+    <$> o A..: "id"
+    <*> o A..: "domain"
+    <*> o A..: "name"
+    <*> o A..: "version"
+instance ToJSON DatabaseDatabase where
+  toJSON p = A.object $ catMaybes [
+    ("id" A..=) <$> Just (databaseDatabaseId p),
+    ("domain" A..=) <$> Just (databaseDatabaseDomain p),
+    ("name" A..=) <$> Just (databaseDatabaseName p),
+    ("version" A..=) <$> Just (databaseDatabaseVersion p)
+    ]
+
+-- | Type 'Database.Error'.
+--   Database error.
+data DatabaseError = DatabaseError
+  {
+    -- | Error message.
+    databaseErrorMessage :: T.Text,
+    -- | Error code.
+    databaseErrorCode :: Int
+  }
+  deriving (Eq, Show)
+instance FromJSON DatabaseError where
+  parseJSON = A.withObject "DatabaseError" $ \o -> DatabaseError
+    <$> o A..: "message"
+    <*> o A..: "code"
+instance ToJSON DatabaseError where
+  toJSON p = A.object $ catMaybes [
+    ("message" A..=) <$> Just (databaseErrorMessage p),
+    ("code" A..=) <$> Just (databaseErrorCode p)
+    ]
+
+-- | Type of the 'Database.addDatabase' event.
+data DatabaseAddDatabase = DatabaseAddDatabase
+  {
+    databaseAddDatabaseDatabase :: DatabaseDatabase
+  }
+  deriving (Eq, Show)
+instance FromJSON DatabaseAddDatabase where
+  parseJSON = A.withObject "DatabaseAddDatabase" $ \o -> DatabaseAddDatabase
+    <$> o A..: "database"
+instance Event DatabaseAddDatabase where
+  eventName _ = "Database.addDatabase"
+
+-- | Disables database tracking, prevents database events from being sent to the client.
+
+-- | Parameters of the 'Database.disable' command.
+data PDatabaseDisable = PDatabaseDisable
+  deriving (Eq, Show)
+pDatabaseDisable
+  :: PDatabaseDisable
+pDatabaseDisable
+  = PDatabaseDisable
+instance ToJSON PDatabaseDisable where
+  toJSON _ = A.Null
+instance Command PDatabaseDisable where
+  type CommandResponse PDatabaseDisable = ()
+  commandName _ = "Database.disable"
+  fromJSON = const . A.Success . const ()
+
+-- | Enables database tracking, database events will now be delivered to the client.
+
+-- | Parameters of the 'Database.enable' command.
+data PDatabaseEnable = PDatabaseEnable
+  deriving (Eq, Show)
+pDatabaseEnable
+  :: PDatabaseEnable
+pDatabaseEnable
+  = PDatabaseEnable
+instance ToJSON PDatabaseEnable where
+  toJSON _ = A.Null
+instance Command PDatabaseEnable where
+  type CommandResponse PDatabaseEnable = ()
+  commandName _ = "Database.enable"
+  fromJSON = const . A.Success . const ()
+
+
+-- | Parameters of the 'Database.executeSQL' command.
+data PDatabaseExecuteSQL = PDatabaseExecuteSQL
+  {
+    pDatabaseExecuteSQLDatabaseId :: DatabaseDatabaseId,
+    pDatabaseExecuteSQLQuery :: T.Text
+  }
+  deriving (Eq, Show)
+pDatabaseExecuteSQL
+  :: DatabaseDatabaseId
+  -> T.Text
+  -> PDatabaseExecuteSQL
+pDatabaseExecuteSQL
+  arg_pDatabaseExecuteSQLDatabaseId
+  arg_pDatabaseExecuteSQLQuery
+  = PDatabaseExecuteSQL
+    arg_pDatabaseExecuteSQLDatabaseId
+    arg_pDatabaseExecuteSQLQuery
+instance ToJSON PDatabaseExecuteSQL where
+  toJSON p = A.object $ catMaybes [
+    ("databaseId" A..=) <$> Just (pDatabaseExecuteSQLDatabaseId p),
+    ("query" A..=) <$> Just (pDatabaseExecuteSQLQuery p)
+    ]
+data DatabaseExecuteSQL = DatabaseExecuteSQL
+  {
+    databaseExecuteSQLColumnNames :: Maybe [T.Text],
+    databaseExecuteSQLValues :: Maybe [A.Value],
+    databaseExecuteSQLSqlError :: Maybe DatabaseError
+  }
+  deriving (Eq, Show)
+instance FromJSON DatabaseExecuteSQL where
+  parseJSON = A.withObject "DatabaseExecuteSQL" $ \o -> DatabaseExecuteSQL
+    <$> o A..:? "columnNames"
+    <*> o A..:? "values"
+    <*> o A..:? "sqlError"
+instance Command PDatabaseExecuteSQL where
+  type CommandResponse PDatabaseExecuteSQL = DatabaseExecuteSQL
+  commandName _ = "Database.executeSQL"
+
+
+-- | Parameters of the 'Database.getDatabaseTableNames' command.
+data PDatabaseGetDatabaseTableNames = PDatabaseGetDatabaseTableNames
+  {
+    pDatabaseGetDatabaseTableNamesDatabaseId :: DatabaseDatabaseId
+  }
+  deriving (Eq, Show)
+pDatabaseGetDatabaseTableNames
+  :: DatabaseDatabaseId
+  -> PDatabaseGetDatabaseTableNames
+pDatabaseGetDatabaseTableNames
+  arg_pDatabaseGetDatabaseTableNamesDatabaseId
+  = PDatabaseGetDatabaseTableNames
+    arg_pDatabaseGetDatabaseTableNamesDatabaseId
+instance ToJSON PDatabaseGetDatabaseTableNames where
+  toJSON p = A.object $ catMaybes [
+    ("databaseId" A..=) <$> Just (pDatabaseGetDatabaseTableNamesDatabaseId p)
+    ]
+data DatabaseGetDatabaseTableNames = DatabaseGetDatabaseTableNames
+  {
+    databaseGetDatabaseTableNamesTableNames :: [T.Text]
+  }
+  deriving (Eq, Show)
+instance FromJSON DatabaseGetDatabaseTableNames where
+  parseJSON = A.withObject "DatabaseGetDatabaseTableNames" $ \o -> DatabaseGetDatabaseTableNames
+    <$> o A..: "tableNames"
+instance Command PDatabaseGetDatabaseTableNames where
+  type CommandResponse PDatabaseGetDatabaseTableNames = DatabaseGetDatabaseTableNames
+  commandName _ = "Database.getDatabaseTableNames"
+
diff --git a/src/CDP/Domains/Debugger.hs b/src/CDP/Domains/Debugger.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains/Debugger.hs
@@ -0,0 +1,1735 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+
+
+{- |
+= Debugger
+
+Debugger domain exposes JavaScript debugging capabilities. It allows setting and removing
+breakpoints, stepping through execution, exploring stack traces, etc.
+-}
+
+
+module CDP.Domains.Debugger (module CDP.Domains.Debugger) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+
+import CDP.Domains.Runtime as Runtime
+
+
+-- | Type 'Debugger.BreakpointId'.
+--   Breakpoint identifier.
+type DebuggerBreakpointId = T.Text
+
+-- | Type 'Debugger.CallFrameId'.
+--   Call frame identifier.
+type DebuggerCallFrameId = T.Text
+
+-- | Type 'Debugger.Location'.
+--   Location in the source code.
+data DebuggerLocation = DebuggerLocation
+  {
+    -- | Script identifier as reported in the `Debugger.scriptParsed`.
+    debuggerLocationScriptId :: Runtime.RuntimeScriptId,
+    -- | Line number in the script (0-based).
+    debuggerLocationLineNumber :: Int,
+    -- | Column number in the script (0-based).
+    debuggerLocationColumnNumber :: Maybe Int
+  }
+  deriving (Eq, Show)
+instance FromJSON DebuggerLocation where
+  parseJSON = A.withObject "DebuggerLocation" $ \o -> DebuggerLocation
+    <$> o A..: "scriptId"
+    <*> o A..: "lineNumber"
+    <*> o A..:? "columnNumber"
+instance ToJSON DebuggerLocation where
+  toJSON p = A.object $ catMaybes [
+    ("scriptId" A..=) <$> Just (debuggerLocationScriptId p),
+    ("lineNumber" A..=) <$> Just (debuggerLocationLineNumber p),
+    ("columnNumber" A..=) <$> (debuggerLocationColumnNumber p)
+    ]
+
+-- | Type 'Debugger.ScriptPosition'.
+--   Location in the source code.
+data DebuggerScriptPosition = DebuggerScriptPosition
+  {
+    debuggerScriptPositionLineNumber :: Int,
+    debuggerScriptPositionColumnNumber :: Int
+  }
+  deriving (Eq, Show)
+instance FromJSON DebuggerScriptPosition where
+  parseJSON = A.withObject "DebuggerScriptPosition" $ \o -> DebuggerScriptPosition
+    <$> o A..: "lineNumber"
+    <*> o A..: "columnNumber"
+instance ToJSON DebuggerScriptPosition where
+  toJSON p = A.object $ catMaybes [
+    ("lineNumber" A..=) <$> Just (debuggerScriptPositionLineNumber p),
+    ("columnNumber" A..=) <$> Just (debuggerScriptPositionColumnNumber p)
+    ]
+
+-- | Type 'Debugger.LocationRange'.
+--   Location range within one script.
+data DebuggerLocationRange = DebuggerLocationRange
+  {
+    debuggerLocationRangeScriptId :: Runtime.RuntimeScriptId,
+    debuggerLocationRangeStart :: DebuggerScriptPosition,
+    debuggerLocationRangeEnd :: DebuggerScriptPosition
+  }
+  deriving (Eq, Show)
+instance FromJSON DebuggerLocationRange where
+  parseJSON = A.withObject "DebuggerLocationRange" $ \o -> DebuggerLocationRange
+    <$> o A..: "scriptId"
+    <*> o A..: "start"
+    <*> o A..: "end"
+instance ToJSON DebuggerLocationRange where
+  toJSON p = A.object $ catMaybes [
+    ("scriptId" A..=) <$> Just (debuggerLocationRangeScriptId p),
+    ("start" A..=) <$> Just (debuggerLocationRangeStart p),
+    ("end" A..=) <$> Just (debuggerLocationRangeEnd p)
+    ]
+
+-- | Type 'Debugger.CallFrame'.
+--   JavaScript call frame. Array of call frames form the call stack.
+data DebuggerCallFrame = DebuggerCallFrame
+  {
+    -- | Call frame identifier. This identifier is only valid while the virtual machine is paused.
+    debuggerCallFrameCallFrameId :: DebuggerCallFrameId,
+    -- | Name of the JavaScript function called on this call frame.
+    debuggerCallFrameFunctionName :: T.Text,
+    -- | Location in the source code.
+    debuggerCallFrameFunctionLocation :: Maybe DebuggerLocation,
+    -- | Location in the source code.
+    debuggerCallFrameLocation :: DebuggerLocation,
+    -- | Scope chain for this call frame.
+    debuggerCallFrameScopeChain :: [DebuggerScope],
+    -- | `this` object for this call frame.
+    debuggerCallFrameThis :: Runtime.RuntimeRemoteObject,
+    -- | The value being returned, if the function is at return point.
+    debuggerCallFrameReturnValue :: Maybe Runtime.RuntimeRemoteObject,
+    -- | Valid only while the VM is paused and indicates whether this frame
+    --   can be restarted or not. Note that a `true` value here does not
+    --   guarantee that Debugger#restartFrame with this CallFrameId will be
+    --   successful, but it is very likely.
+    debuggerCallFrameCanBeRestarted :: Maybe Bool
+  }
+  deriving (Eq, Show)
+instance FromJSON DebuggerCallFrame where
+  parseJSON = A.withObject "DebuggerCallFrame" $ \o -> DebuggerCallFrame
+    <$> o A..: "callFrameId"
+    <*> o A..: "functionName"
+    <*> o A..:? "functionLocation"
+    <*> o A..: "location"
+    <*> o A..: "scopeChain"
+    <*> o A..: "this"
+    <*> o A..:? "returnValue"
+    <*> o A..:? "canBeRestarted"
+instance ToJSON DebuggerCallFrame where
+  toJSON p = A.object $ catMaybes [
+    ("callFrameId" A..=) <$> Just (debuggerCallFrameCallFrameId p),
+    ("functionName" A..=) <$> Just (debuggerCallFrameFunctionName p),
+    ("functionLocation" A..=) <$> (debuggerCallFrameFunctionLocation p),
+    ("location" A..=) <$> Just (debuggerCallFrameLocation p),
+    ("scopeChain" A..=) <$> Just (debuggerCallFrameScopeChain p),
+    ("this" A..=) <$> Just (debuggerCallFrameThis p),
+    ("returnValue" A..=) <$> (debuggerCallFrameReturnValue p),
+    ("canBeRestarted" A..=) <$> (debuggerCallFrameCanBeRestarted p)
+    ]
+
+-- | Type 'Debugger.Scope'.
+--   Scope description.
+data DebuggerScopeType = DebuggerScopeTypeGlobal | DebuggerScopeTypeLocal | DebuggerScopeTypeWith | DebuggerScopeTypeClosure | DebuggerScopeTypeCatch | DebuggerScopeTypeBlock | DebuggerScopeTypeScript | DebuggerScopeTypeEval | DebuggerScopeTypeModule | DebuggerScopeTypeWasmExpressionStack
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON DebuggerScopeType where
+  parseJSON = A.withText "DebuggerScopeType" $ \v -> case v of
+    "global" -> pure DebuggerScopeTypeGlobal
+    "local" -> pure DebuggerScopeTypeLocal
+    "with" -> pure DebuggerScopeTypeWith
+    "closure" -> pure DebuggerScopeTypeClosure
+    "catch" -> pure DebuggerScopeTypeCatch
+    "block" -> pure DebuggerScopeTypeBlock
+    "script" -> pure DebuggerScopeTypeScript
+    "eval" -> pure DebuggerScopeTypeEval
+    "module" -> pure DebuggerScopeTypeModule
+    "wasm-expression-stack" -> pure DebuggerScopeTypeWasmExpressionStack
+    "_" -> fail "failed to parse DebuggerScopeType"
+instance ToJSON DebuggerScopeType where
+  toJSON v = A.String $ case v of
+    DebuggerScopeTypeGlobal -> "global"
+    DebuggerScopeTypeLocal -> "local"
+    DebuggerScopeTypeWith -> "with"
+    DebuggerScopeTypeClosure -> "closure"
+    DebuggerScopeTypeCatch -> "catch"
+    DebuggerScopeTypeBlock -> "block"
+    DebuggerScopeTypeScript -> "script"
+    DebuggerScopeTypeEval -> "eval"
+    DebuggerScopeTypeModule -> "module"
+    DebuggerScopeTypeWasmExpressionStack -> "wasm-expression-stack"
+data DebuggerScope = DebuggerScope
+  {
+    -- | Scope type.
+    debuggerScopeType :: DebuggerScopeType,
+    -- | Object representing the scope. For `global` and `with` scopes it represents the actual
+    --   object; for the rest of the scopes, it is artificial transient object enumerating scope
+    --   variables as its properties.
+    debuggerScopeObject :: Runtime.RuntimeRemoteObject,
+    debuggerScopeName :: Maybe T.Text,
+    -- | Location in the source code where scope starts
+    debuggerScopeStartLocation :: Maybe DebuggerLocation,
+    -- | Location in the source code where scope ends
+    debuggerScopeEndLocation :: Maybe DebuggerLocation
+  }
+  deriving (Eq, Show)
+instance FromJSON DebuggerScope where
+  parseJSON = A.withObject "DebuggerScope" $ \o -> DebuggerScope
+    <$> o A..: "type"
+    <*> o A..: "object"
+    <*> o A..:? "name"
+    <*> o A..:? "startLocation"
+    <*> o A..:? "endLocation"
+instance ToJSON DebuggerScope where
+  toJSON p = A.object $ catMaybes [
+    ("type" A..=) <$> Just (debuggerScopeType p),
+    ("object" A..=) <$> Just (debuggerScopeObject p),
+    ("name" A..=) <$> (debuggerScopeName p),
+    ("startLocation" A..=) <$> (debuggerScopeStartLocation p),
+    ("endLocation" A..=) <$> (debuggerScopeEndLocation p)
+    ]
+
+-- | Type 'Debugger.SearchMatch'.
+--   Search match for resource.
+data DebuggerSearchMatch = DebuggerSearchMatch
+  {
+    -- | Line number in resource content.
+    debuggerSearchMatchLineNumber :: Double,
+    -- | Line with match content.
+    debuggerSearchMatchLineContent :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON DebuggerSearchMatch where
+  parseJSON = A.withObject "DebuggerSearchMatch" $ \o -> DebuggerSearchMatch
+    <$> o A..: "lineNumber"
+    <*> o A..: "lineContent"
+instance ToJSON DebuggerSearchMatch where
+  toJSON p = A.object $ catMaybes [
+    ("lineNumber" A..=) <$> Just (debuggerSearchMatchLineNumber p),
+    ("lineContent" A..=) <$> Just (debuggerSearchMatchLineContent p)
+    ]
+
+-- | Type 'Debugger.BreakLocation'.
+data DebuggerBreakLocationType = DebuggerBreakLocationTypeDebuggerStatement | DebuggerBreakLocationTypeCall | DebuggerBreakLocationTypeReturn
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON DebuggerBreakLocationType where
+  parseJSON = A.withText "DebuggerBreakLocationType" $ \v -> case v of
+    "debuggerStatement" -> pure DebuggerBreakLocationTypeDebuggerStatement
+    "call" -> pure DebuggerBreakLocationTypeCall
+    "return" -> pure DebuggerBreakLocationTypeReturn
+    "_" -> fail "failed to parse DebuggerBreakLocationType"
+instance ToJSON DebuggerBreakLocationType where
+  toJSON v = A.String $ case v of
+    DebuggerBreakLocationTypeDebuggerStatement -> "debuggerStatement"
+    DebuggerBreakLocationTypeCall -> "call"
+    DebuggerBreakLocationTypeReturn -> "return"
+data DebuggerBreakLocation = DebuggerBreakLocation
+  {
+    -- | Script identifier as reported in the `Debugger.scriptParsed`.
+    debuggerBreakLocationScriptId :: Runtime.RuntimeScriptId,
+    -- | Line number in the script (0-based).
+    debuggerBreakLocationLineNumber :: Int,
+    -- | Column number in the script (0-based).
+    debuggerBreakLocationColumnNumber :: Maybe Int,
+    debuggerBreakLocationType :: Maybe DebuggerBreakLocationType
+  }
+  deriving (Eq, Show)
+instance FromJSON DebuggerBreakLocation where
+  parseJSON = A.withObject "DebuggerBreakLocation" $ \o -> DebuggerBreakLocation
+    <$> o A..: "scriptId"
+    <*> o A..: "lineNumber"
+    <*> o A..:? "columnNumber"
+    <*> o A..:? "type"
+instance ToJSON DebuggerBreakLocation where
+  toJSON p = A.object $ catMaybes [
+    ("scriptId" A..=) <$> Just (debuggerBreakLocationScriptId p),
+    ("lineNumber" A..=) <$> Just (debuggerBreakLocationLineNumber p),
+    ("columnNumber" A..=) <$> (debuggerBreakLocationColumnNumber p),
+    ("type" A..=) <$> (debuggerBreakLocationType p)
+    ]
+
+-- | Type 'Debugger.WasmDisassemblyChunk'.
+data DebuggerWasmDisassemblyChunk = DebuggerWasmDisassemblyChunk
+  {
+    -- | The next chunk of disassembled lines.
+    debuggerWasmDisassemblyChunkLines :: [T.Text],
+    -- | The bytecode offsets describing the start of each line.
+    debuggerWasmDisassemblyChunkBytecodeOffsets :: [Int]
+  }
+  deriving (Eq, Show)
+instance FromJSON DebuggerWasmDisassemblyChunk where
+  parseJSON = A.withObject "DebuggerWasmDisassemblyChunk" $ \o -> DebuggerWasmDisassemblyChunk
+    <$> o A..: "lines"
+    <*> o A..: "bytecodeOffsets"
+instance ToJSON DebuggerWasmDisassemblyChunk where
+  toJSON p = A.object $ catMaybes [
+    ("lines" A..=) <$> Just (debuggerWasmDisassemblyChunkLines p),
+    ("bytecodeOffsets" A..=) <$> Just (debuggerWasmDisassemblyChunkBytecodeOffsets p)
+    ]
+
+-- | Type 'Debugger.ScriptLanguage'.
+--   Enum of possible script languages.
+data DebuggerScriptLanguage = DebuggerScriptLanguageJavaScript | DebuggerScriptLanguageWebAssembly
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON DebuggerScriptLanguage where
+  parseJSON = A.withText "DebuggerScriptLanguage" $ \v -> case v of
+    "JavaScript" -> pure DebuggerScriptLanguageJavaScript
+    "WebAssembly" -> pure DebuggerScriptLanguageWebAssembly
+    "_" -> fail "failed to parse DebuggerScriptLanguage"
+instance ToJSON DebuggerScriptLanguage where
+  toJSON v = A.String $ case v of
+    DebuggerScriptLanguageJavaScript -> "JavaScript"
+    DebuggerScriptLanguageWebAssembly -> "WebAssembly"
+
+-- | Type 'Debugger.DebugSymbols'.
+--   Debug symbols available for a wasm script.
+data DebuggerDebugSymbolsType = DebuggerDebugSymbolsTypeNone | DebuggerDebugSymbolsTypeSourceMap | DebuggerDebugSymbolsTypeEmbeddedDWARF | DebuggerDebugSymbolsTypeExternalDWARF
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON DebuggerDebugSymbolsType where
+  parseJSON = A.withText "DebuggerDebugSymbolsType" $ \v -> case v of
+    "None" -> pure DebuggerDebugSymbolsTypeNone
+    "SourceMap" -> pure DebuggerDebugSymbolsTypeSourceMap
+    "EmbeddedDWARF" -> pure DebuggerDebugSymbolsTypeEmbeddedDWARF
+    "ExternalDWARF" -> pure DebuggerDebugSymbolsTypeExternalDWARF
+    "_" -> fail "failed to parse DebuggerDebugSymbolsType"
+instance ToJSON DebuggerDebugSymbolsType where
+  toJSON v = A.String $ case v of
+    DebuggerDebugSymbolsTypeNone -> "None"
+    DebuggerDebugSymbolsTypeSourceMap -> "SourceMap"
+    DebuggerDebugSymbolsTypeEmbeddedDWARF -> "EmbeddedDWARF"
+    DebuggerDebugSymbolsTypeExternalDWARF -> "ExternalDWARF"
+data DebuggerDebugSymbols = DebuggerDebugSymbols
+  {
+    -- | Type of the debug symbols.
+    debuggerDebugSymbolsType :: DebuggerDebugSymbolsType,
+    -- | URL of the external symbol source.
+    debuggerDebugSymbolsExternalURL :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON DebuggerDebugSymbols where
+  parseJSON = A.withObject "DebuggerDebugSymbols" $ \o -> DebuggerDebugSymbols
+    <$> o A..: "type"
+    <*> o A..:? "externalURL"
+instance ToJSON DebuggerDebugSymbols where
+  toJSON p = A.object $ catMaybes [
+    ("type" A..=) <$> Just (debuggerDebugSymbolsType p),
+    ("externalURL" A..=) <$> (debuggerDebugSymbolsExternalURL p)
+    ]
+
+-- | Type of the 'Debugger.breakpointResolved' event.
+data DebuggerBreakpointResolved = DebuggerBreakpointResolved
+  {
+    -- | Breakpoint unique identifier.
+    debuggerBreakpointResolvedBreakpointId :: DebuggerBreakpointId,
+    -- | Actual breakpoint location.
+    debuggerBreakpointResolvedLocation :: DebuggerLocation
+  }
+  deriving (Eq, Show)
+instance FromJSON DebuggerBreakpointResolved where
+  parseJSON = A.withObject "DebuggerBreakpointResolved" $ \o -> DebuggerBreakpointResolved
+    <$> o A..: "breakpointId"
+    <*> o A..: "location"
+instance Event DebuggerBreakpointResolved where
+  eventName _ = "Debugger.breakpointResolved"
+
+-- | Type of the 'Debugger.paused' event.
+data DebuggerPausedReason = DebuggerPausedReasonAmbiguous | DebuggerPausedReasonAssert | DebuggerPausedReasonCSPViolation | DebuggerPausedReasonDebugCommand | DebuggerPausedReasonDOM | DebuggerPausedReasonEventListener | DebuggerPausedReasonException | DebuggerPausedReasonInstrumentation | DebuggerPausedReasonOOM | DebuggerPausedReasonOther | DebuggerPausedReasonPromiseRejection | DebuggerPausedReasonXHR
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON DebuggerPausedReason where
+  parseJSON = A.withText "DebuggerPausedReason" $ \v -> case v of
+    "ambiguous" -> pure DebuggerPausedReasonAmbiguous
+    "assert" -> pure DebuggerPausedReasonAssert
+    "CSPViolation" -> pure DebuggerPausedReasonCSPViolation
+    "debugCommand" -> pure DebuggerPausedReasonDebugCommand
+    "DOM" -> pure DebuggerPausedReasonDOM
+    "EventListener" -> pure DebuggerPausedReasonEventListener
+    "exception" -> pure DebuggerPausedReasonException
+    "instrumentation" -> pure DebuggerPausedReasonInstrumentation
+    "OOM" -> pure DebuggerPausedReasonOOM
+    "other" -> pure DebuggerPausedReasonOther
+    "promiseRejection" -> pure DebuggerPausedReasonPromiseRejection
+    "XHR" -> pure DebuggerPausedReasonXHR
+    "_" -> fail "failed to parse DebuggerPausedReason"
+instance ToJSON DebuggerPausedReason where
+  toJSON v = A.String $ case v of
+    DebuggerPausedReasonAmbiguous -> "ambiguous"
+    DebuggerPausedReasonAssert -> "assert"
+    DebuggerPausedReasonCSPViolation -> "CSPViolation"
+    DebuggerPausedReasonDebugCommand -> "debugCommand"
+    DebuggerPausedReasonDOM -> "DOM"
+    DebuggerPausedReasonEventListener -> "EventListener"
+    DebuggerPausedReasonException -> "exception"
+    DebuggerPausedReasonInstrumentation -> "instrumentation"
+    DebuggerPausedReasonOOM -> "OOM"
+    DebuggerPausedReasonOther -> "other"
+    DebuggerPausedReasonPromiseRejection -> "promiseRejection"
+    DebuggerPausedReasonXHR -> "XHR"
+data DebuggerPaused = DebuggerPaused
+  {
+    -- | Call stack the virtual machine stopped on.
+    debuggerPausedCallFrames :: [DebuggerCallFrame],
+    -- | Pause reason.
+    debuggerPausedReason :: DebuggerPausedReason,
+    -- | Object containing break-specific auxiliary properties.
+    debuggerPausedData :: Maybe [(T.Text, T.Text)],
+    -- | Hit breakpoints IDs
+    debuggerPausedHitBreakpoints :: Maybe [T.Text],
+    -- | Async stack trace, if any.
+    debuggerPausedAsyncStackTrace :: Maybe Runtime.RuntimeStackTrace,
+    -- | Async stack trace, if any.
+    debuggerPausedAsyncStackTraceId :: Maybe Runtime.RuntimeStackTraceId
+  }
+  deriving (Eq, Show)
+instance FromJSON DebuggerPaused where
+  parseJSON = A.withObject "DebuggerPaused" $ \o -> DebuggerPaused
+    <$> o A..: "callFrames"
+    <*> o A..: "reason"
+    <*> o A..:? "data"
+    <*> o A..:? "hitBreakpoints"
+    <*> o A..:? "asyncStackTrace"
+    <*> o A..:? "asyncStackTraceId"
+instance Event DebuggerPaused where
+  eventName _ = "Debugger.paused"
+
+-- | Type of the 'Debugger.resumed' event.
+data DebuggerResumed = DebuggerResumed
+  deriving (Eq, Show, Read)
+instance FromJSON DebuggerResumed where
+  parseJSON _ = pure DebuggerResumed
+instance Event DebuggerResumed where
+  eventName _ = "Debugger.resumed"
+
+-- | Type of the 'Debugger.scriptFailedToParse' event.
+data DebuggerScriptFailedToParse = DebuggerScriptFailedToParse
+  {
+    -- | Identifier of the script parsed.
+    debuggerScriptFailedToParseScriptId :: Runtime.RuntimeScriptId,
+    -- | URL or name of the script parsed (if any).
+    debuggerScriptFailedToParseUrl :: T.Text,
+    -- | Line offset of the script within the resource with given URL (for script tags).
+    debuggerScriptFailedToParseStartLine :: Int,
+    -- | Column offset of the script within the resource with given URL.
+    debuggerScriptFailedToParseStartColumn :: Int,
+    -- | Last line of the script.
+    debuggerScriptFailedToParseEndLine :: Int,
+    -- | Length of the last line of the script.
+    debuggerScriptFailedToParseEndColumn :: Int,
+    -- | Specifies script creation context.
+    debuggerScriptFailedToParseExecutionContextId :: Runtime.RuntimeExecutionContextId,
+    -- | Content hash of the script, SHA-256.
+    debuggerScriptFailedToParseHash :: T.Text,
+    -- | Embedder-specific auxiliary data.
+    debuggerScriptFailedToParseExecutionContextAuxData :: Maybe [(T.Text, T.Text)],
+    -- | URL of source map associated with script (if any).
+    debuggerScriptFailedToParseSourceMapURL :: Maybe T.Text,
+    -- | True, if this script has sourceURL.
+    debuggerScriptFailedToParseHasSourceURL :: Maybe Bool,
+    -- | True, if this script is ES6 module.
+    debuggerScriptFailedToParseIsModule :: Maybe Bool,
+    -- | This script length.
+    debuggerScriptFailedToParseLength :: Maybe Int,
+    -- | JavaScript top stack frame of where the script parsed event was triggered if available.
+    debuggerScriptFailedToParseStackTrace :: Maybe Runtime.RuntimeStackTrace,
+    -- | If the scriptLanguage is WebAssembly, the code section offset in the module.
+    debuggerScriptFailedToParseCodeOffset :: Maybe Int,
+    -- | The language of the script.
+    debuggerScriptFailedToParseScriptLanguage :: Maybe DebuggerScriptLanguage,
+    -- | The name the embedder supplied for this script.
+    debuggerScriptFailedToParseEmbedderName :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON DebuggerScriptFailedToParse where
+  parseJSON = A.withObject "DebuggerScriptFailedToParse" $ \o -> DebuggerScriptFailedToParse
+    <$> o A..: "scriptId"
+    <*> o A..: "url"
+    <*> o A..: "startLine"
+    <*> o A..: "startColumn"
+    <*> o A..: "endLine"
+    <*> o A..: "endColumn"
+    <*> o A..: "executionContextId"
+    <*> o A..: "hash"
+    <*> o A..:? "executionContextAuxData"
+    <*> o A..:? "sourceMapURL"
+    <*> o A..:? "hasSourceURL"
+    <*> o A..:? "isModule"
+    <*> o A..:? "length"
+    <*> o A..:? "stackTrace"
+    <*> o A..:? "codeOffset"
+    <*> o A..:? "scriptLanguage"
+    <*> o A..:? "embedderName"
+instance Event DebuggerScriptFailedToParse where
+  eventName _ = "Debugger.scriptFailedToParse"
+
+-- | Type of the 'Debugger.scriptParsed' event.
+data DebuggerScriptParsed = DebuggerScriptParsed
+  {
+    -- | Identifier of the script parsed.
+    debuggerScriptParsedScriptId :: Runtime.RuntimeScriptId,
+    -- | URL or name of the script parsed (if any).
+    debuggerScriptParsedUrl :: T.Text,
+    -- | Line offset of the script within the resource with given URL (for script tags).
+    debuggerScriptParsedStartLine :: Int,
+    -- | Column offset of the script within the resource with given URL.
+    debuggerScriptParsedStartColumn :: Int,
+    -- | Last line of the script.
+    debuggerScriptParsedEndLine :: Int,
+    -- | Length of the last line of the script.
+    debuggerScriptParsedEndColumn :: Int,
+    -- | Specifies script creation context.
+    debuggerScriptParsedExecutionContextId :: Runtime.RuntimeExecutionContextId,
+    -- | Content hash of the script, SHA-256.
+    debuggerScriptParsedHash :: T.Text,
+    -- | Embedder-specific auxiliary data.
+    debuggerScriptParsedExecutionContextAuxData :: Maybe [(T.Text, T.Text)],
+    -- | True, if this script is generated as a result of the live edit operation.
+    debuggerScriptParsedIsLiveEdit :: Maybe Bool,
+    -- | URL of source map associated with script (if any).
+    debuggerScriptParsedSourceMapURL :: Maybe T.Text,
+    -- | True, if this script has sourceURL.
+    debuggerScriptParsedHasSourceURL :: Maybe Bool,
+    -- | True, if this script is ES6 module.
+    debuggerScriptParsedIsModule :: Maybe Bool,
+    -- | This script length.
+    debuggerScriptParsedLength :: Maybe Int,
+    -- | JavaScript top stack frame of where the script parsed event was triggered if available.
+    debuggerScriptParsedStackTrace :: Maybe Runtime.RuntimeStackTrace,
+    -- | If the scriptLanguage is WebAssembly, the code section offset in the module.
+    debuggerScriptParsedCodeOffset :: Maybe Int,
+    -- | The language of the script.
+    debuggerScriptParsedScriptLanguage :: Maybe DebuggerScriptLanguage,
+    -- | If the scriptLanguage is WebASsembly, the source of debug symbols for the module.
+    debuggerScriptParsedDebugSymbols :: Maybe DebuggerDebugSymbols,
+    -- | The name the embedder supplied for this script.
+    debuggerScriptParsedEmbedderName :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON DebuggerScriptParsed where
+  parseJSON = A.withObject "DebuggerScriptParsed" $ \o -> DebuggerScriptParsed
+    <$> o A..: "scriptId"
+    <*> o A..: "url"
+    <*> o A..: "startLine"
+    <*> o A..: "startColumn"
+    <*> o A..: "endLine"
+    <*> o A..: "endColumn"
+    <*> o A..: "executionContextId"
+    <*> o A..: "hash"
+    <*> o A..:? "executionContextAuxData"
+    <*> o A..:? "isLiveEdit"
+    <*> o A..:? "sourceMapURL"
+    <*> o A..:? "hasSourceURL"
+    <*> o A..:? "isModule"
+    <*> o A..:? "length"
+    <*> o A..:? "stackTrace"
+    <*> o A..:? "codeOffset"
+    <*> o A..:? "scriptLanguage"
+    <*> o A..:? "debugSymbols"
+    <*> o A..:? "embedderName"
+instance Event DebuggerScriptParsed where
+  eventName _ = "Debugger.scriptParsed"
+
+-- | Continues execution until specific location is reached.
+
+-- | Parameters of the 'Debugger.continueToLocation' command.
+data PDebuggerContinueToLocationTargetCallFrames = PDebuggerContinueToLocationTargetCallFramesAny | PDebuggerContinueToLocationTargetCallFramesCurrent
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PDebuggerContinueToLocationTargetCallFrames where
+  parseJSON = A.withText "PDebuggerContinueToLocationTargetCallFrames" $ \v -> case v of
+    "any" -> pure PDebuggerContinueToLocationTargetCallFramesAny
+    "current" -> pure PDebuggerContinueToLocationTargetCallFramesCurrent
+    "_" -> fail "failed to parse PDebuggerContinueToLocationTargetCallFrames"
+instance ToJSON PDebuggerContinueToLocationTargetCallFrames where
+  toJSON v = A.String $ case v of
+    PDebuggerContinueToLocationTargetCallFramesAny -> "any"
+    PDebuggerContinueToLocationTargetCallFramesCurrent -> "current"
+data PDebuggerContinueToLocation = PDebuggerContinueToLocation
+  {
+    -- | Location to continue to.
+    pDebuggerContinueToLocationLocation :: DebuggerLocation,
+    pDebuggerContinueToLocationTargetCallFrames :: Maybe PDebuggerContinueToLocationTargetCallFrames
+  }
+  deriving (Eq, Show)
+pDebuggerContinueToLocation
+  {-
+  -- | Location to continue to.
+  -}
+  :: DebuggerLocation
+  -> PDebuggerContinueToLocation
+pDebuggerContinueToLocation
+  arg_pDebuggerContinueToLocationLocation
+  = PDebuggerContinueToLocation
+    arg_pDebuggerContinueToLocationLocation
+    Nothing
+instance ToJSON PDebuggerContinueToLocation where
+  toJSON p = A.object $ catMaybes [
+    ("location" A..=) <$> Just (pDebuggerContinueToLocationLocation p),
+    ("targetCallFrames" A..=) <$> (pDebuggerContinueToLocationTargetCallFrames p)
+    ]
+instance Command PDebuggerContinueToLocation where
+  type CommandResponse PDebuggerContinueToLocation = ()
+  commandName _ = "Debugger.continueToLocation"
+  fromJSON = const . A.Success . const ()
+
+-- | Disables debugger for given page.
+
+-- | Parameters of the 'Debugger.disable' command.
+data PDebuggerDisable = PDebuggerDisable
+  deriving (Eq, Show)
+pDebuggerDisable
+  :: PDebuggerDisable
+pDebuggerDisable
+  = PDebuggerDisable
+instance ToJSON PDebuggerDisable where
+  toJSON _ = A.Null
+instance Command PDebuggerDisable where
+  type CommandResponse PDebuggerDisable = ()
+  commandName _ = "Debugger.disable"
+  fromJSON = const . A.Success . const ()
+
+-- | Enables debugger for the given page. Clients should not assume that the debugging has been
+--   enabled until the result for this command is received.
+
+-- | Parameters of the 'Debugger.enable' command.
+data PDebuggerEnable = PDebuggerEnable
+  {
+    -- | The maximum size in bytes of collected scripts (not referenced by other heap objects)
+    --   the debugger can hold. Puts no limit if parameter is omitted.
+    pDebuggerEnableMaxScriptsCacheSize :: Maybe Double
+  }
+  deriving (Eq, Show)
+pDebuggerEnable
+  :: PDebuggerEnable
+pDebuggerEnable
+  = PDebuggerEnable
+    Nothing
+instance ToJSON PDebuggerEnable where
+  toJSON p = A.object $ catMaybes [
+    ("maxScriptsCacheSize" A..=) <$> (pDebuggerEnableMaxScriptsCacheSize p)
+    ]
+data DebuggerEnable = DebuggerEnable
+  {
+    -- | Unique identifier of the debugger.
+    debuggerEnableDebuggerId :: Runtime.RuntimeUniqueDebuggerId
+  }
+  deriving (Eq, Show)
+instance FromJSON DebuggerEnable where
+  parseJSON = A.withObject "DebuggerEnable" $ \o -> DebuggerEnable
+    <$> o A..: "debuggerId"
+instance Command PDebuggerEnable where
+  type CommandResponse PDebuggerEnable = DebuggerEnable
+  commandName _ = "Debugger.enable"
+
+-- | Evaluates expression on a given call frame.
+
+-- | Parameters of the 'Debugger.evaluateOnCallFrame' command.
+data PDebuggerEvaluateOnCallFrame = PDebuggerEvaluateOnCallFrame
+  {
+    -- | Call frame identifier to evaluate on.
+    pDebuggerEvaluateOnCallFrameCallFrameId :: DebuggerCallFrameId,
+    -- | Expression to evaluate.
+    pDebuggerEvaluateOnCallFrameExpression :: T.Text,
+    -- | String object group name to put result into (allows rapid releasing resulting object handles
+    --   using `releaseObjectGroup`).
+    pDebuggerEvaluateOnCallFrameObjectGroup :: Maybe T.Text,
+    -- | Specifies whether command line API should be available to the evaluated expression, defaults
+    --   to false.
+    pDebuggerEvaluateOnCallFrameIncludeCommandLineAPI :: Maybe Bool,
+    -- | In silent mode exceptions thrown during evaluation are not reported and do not pause
+    --   execution. Overrides `setPauseOnException` state.
+    pDebuggerEvaluateOnCallFrameSilent :: Maybe Bool,
+    -- | Whether the result is expected to be a JSON object that should be sent by value.
+    pDebuggerEvaluateOnCallFrameReturnByValue :: Maybe Bool,
+    -- | Whether preview should be generated for the result.
+    pDebuggerEvaluateOnCallFrameGeneratePreview :: Maybe Bool,
+    -- | Whether to throw an exception if side effect cannot be ruled out during evaluation.
+    pDebuggerEvaluateOnCallFrameThrowOnSideEffect :: Maybe Bool,
+    -- | Terminate execution after timing out (number of milliseconds).
+    pDebuggerEvaluateOnCallFrameTimeout :: Maybe Runtime.RuntimeTimeDelta
+  }
+  deriving (Eq, Show)
+pDebuggerEvaluateOnCallFrame
+  {-
+  -- | Call frame identifier to evaluate on.
+  -}
+  :: DebuggerCallFrameId
+  {-
+  -- | Expression to evaluate.
+  -}
+  -> T.Text
+  -> PDebuggerEvaluateOnCallFrame
+pDebuggerEvaluateOnCallFrame
+  arg_pDebuggerEvaluateOnCallFrameCallFrameId
+  arg_pDebuggerEvaluateOnCallFrameExpression
+  = PDebuggerEvaluateOnCallFrame
+    arg_pDebuggerEvaluateOnCallFrameCallFrameId
+    arg_pDebuggerEvaluateOnCallFrameExpression
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PDebuggerEvaluateOnCallFrame where
+  toJSON p = A.object $ catMaybes [
+    ("callFrameId" A..=) <$> Just (pDebuggerEvaluateOnCallFrameCallFrameId p),
+    ("expression" A..=) <$> Just (pDebuggerEvaluateOnCallFrameExpression p),
+    ("objectGroup" A..=) <$> (pDebuggerEvaluateOnCallFrameObjectGroup p),
+    ("includeCommandLineAPI" A..=) <$> (pDebuggerEvaluateOnCallFrameIncludeCommandLineAPI p),
+    ("silent" A..=) <$> (pDebuggerEvaluateOnCallFrameSilent p),
+    ("returnByValue" A..=) <$> (pDebuggerEvaluateOnCallFrameReturnByValue p),
+    ("generatePreview" A..=) <$> (pDebuggerEvaluateOnCallFrameGeneratePreview p),
+    ("throwOnSideEffect" A..=) <$> (pDebuggerEvaluateOnCallFrameThrowOnSideEffect p),
+    ("timeout" A..=) <$> (pDebuggerEvaluateOnCallFrameTimeout p)
+    ]
+data DebuggerEvaluateOnCallFrame = DebuggerEvaluateOnCallFrame
+  {
+    -- | Object wrapper for the evaluation result.
+    debuggerEvaluateOnCallFrameResult :: Runtime.RuntimeRemoteObject,
+    -- | Exception details.
+    debuggerEvaluateOnCallFrameExceptionDetails :: Maybe Runtime.RuntimeExceptionDetails
+  }
+  deriving (Eq, Show)
+instance FromJSON DebuggerEvaluateOnCallFrame where
+  parseJSON = A.withObject "DebuggerEvaluateOnCallFrame" $ \o -> DebuggerEvaluateOnCallFrame
+    <$> o A..: "result"
+    <*> o A..:? "exceptionDetails"
+instance Command PDebuggerEvaluateOnCallFrame where
+  type CommandResponse PDebuggerEvaluateOnCallFrame = DebuggerEvaluateOnCallFrame
+  commandName _ = "Debugger.evaluateOnCallFrame"
+
+-- | Returns possible locations for breakpoint. scriptId in start and end range locations should be
+--   the same.
+
+-- | Parameters of the 'Debugger.getPossibleBreakpoints' command.
+data PDebuggerGetPossibleBreakpoints = PDebuggerGetPossibleBreakpoints
+  {
+    -- | Start of range to search possible breakpoint locations in.
+    pDebuggerGetPossibleBreakpointsStart :: DebuggerLocation,
+    -- | End of range to search possible breakpoint locations in (excluding). When not specified, end
+    --   of scripts is used as end of range.
+    pDebuggerGetPossibleBreakpointsEnd :: Maybe DebuggerLocation,
+    -- | Only consider locations which are in the same (non-nested) function as start.
+    pDebuggerGetPossibleBreakpointsRestrictToFunction :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pDebuggerGetPossibleBreakpoints
+  {-
+  -- | Start of range to search possible breakpoint locations in.
+  -}
+  :: DebuggerLocation
+  -> PDebuggerGetPossibleBreakpoints
+pDebuggerGetPossibleBreakpoints
+  arg_pDebuggerGetPossibleBreakpointsStart
+  = PDebuggerGetPossibleBreakpoints
+    arg_pDebuggerGetPossibleBreakpointsStart
+    Nothing
+    Nothing
+instance ToJSON PDebuggerGetPossibleBreakpoints where
+  toJSON p = A.object $ catMaybes [
+    ("start" A..=) <$> Just (pDebuggerGetPossibleBreakpointsStart p),
+    ("end" A..=) <$> (pDebuggerGetPossibleBreakpointsEnd p),
+    ("restrictToFunction" A..=) <$> (pDebuggerGetPossibleBreakpointsRestrictToFunction p)
+    ]
+data DebuggerGetPossibleBreakpoints = DebuggerGetPossibleBreakpoints
+  {
+    -- | List of the possible breakpoint locations.
+    debuggerGetPossibleBreakpointsLocations :: [DebuggerBreakLocation]
+  }
+  deriving (Eq, Show)
+instance FromJSON DebuggerGetPossibleBreakpoints where
+  parseJSON = A.withObject "DebuggerGetPossibleBreakpoints" $ \o -> DebuggerGetPossibleBreakpoints
+    <$> o A..: "locations"
+instance Command PDebuggerGetPossibleBreakpoints where
+  type CommandResponse PDebuggerGetPossibleBreakpoints = DebuggerGetPossibleBreakpoints
+  commandName _ = "Debugger.getPossibleBreakpoints"
+
+-- | Returns source for the script with given id.
+
+-- | Parameters of the 'Debugger.getScriptSource' command.
+data PDebuggerGetScriptSource = PDebuggerGetScriptSource
+  {
+    -- | Id of the script to get source for.
+    pDebuggerGetScriptSourceScriptId :: Runtime.RuntimeScriptId
+  }
+  deriving (Eq, Show)
+pDebuggerGetScriptSource
+  {-
+  -- | Id of the script to get source for.
+  -}
+  :: Runtime.RuntimeScriptId
+  -> PDebuggerGetScriptSource
+pDebuggerGetScriptSource
+  arg_pDebuggerGetScriptSourceScriptId
+  = PDebuggerGetScriptSource
+    arg_pDebuggerGetScriptSourceScriptId
+instance ToJSON PDebuggerGetScriptSource where
+  toJSON p = A.object $ catMaybes [
+    ("scriptId" A..=) <$> Just (pDebuggerGetScriptSourceScriptId p)
+    ]
+data DebuggerGetScriptSource = DebuggerGetScriptSource
+  {
+    -- | Script source (empty in case of Wasm bytecode).
+    debuggerGetScriptSourceScriptSource :: T.Text,
+    -- | Wasm bytecode. (Encoded as a base64 string when passed over JSON)
+    debuggerGetScriptSourceBytecode :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON DebuggerGetScriptSource where
+  parseJSON = A.withObject "DebuggerGetScriptSource" $ \o -> DebuggerGetScriptSource
+    <$> o A..: "scriptSource"
+    <*> o A..:? "bytecode"
+instance Command PDebuggerGetScriptSource where
+  type CommandResponse PDebuggerGetScriptSource = DebuggerGetScriptSource
+  commandName _ = "Debugger.getScriptSource"
+
+
+-- | Parameters of the 'Debugger.disassembleWasmModule' command.
+data PDebuggerDisassembleWasmModule = PDebuggerDisassembleWasmModule
+  {
+    -- | Id of the script to disassemble
+    pDebuggerDisassembleWasmModuleScriptId :: Runtime.RuntimeScriptId
+  }
+  deriving (Eq, Show)
+pDebuggerDisassembleWasmModule
+  {-
+  -- | Id of the script to disassemble
+  -}
+  :: Runtime.RuntimeScriptId
+  -> PDebuggerDisassembleWasmModule
+pDebuggerDisassembleWasmModule
+  arg_pDebuggerDisassembleWasmModuleScriptId
+  = PDebuggerDisassembleWasmModule
+    arg_pDebuggerDisassembleWasmModuleScriptId
+instance ToJSON PDebuggerDisassembleWasmModule where
+  toJSON p = A.object $ catMaybes [
+    ("scriptId" A..=) <$> Just (pDebuggerDisassembleWasmModuleScriptId p)
+    ]
+data DebuggerDisassembleWasmModule = DebuggerDisassembleWasmModule
+  {
+    -- | For large modules, return a stream from which additional chunks of
+    --   disassembly can be read successively.
+    debuggerDisassembleWasmModuleStreamId :: Maybe T.Text,
+    -- | The total number of lines in the disassembly text.
+    debuggerDisassembleWasmModuleTotalNumberOfLines :: Int,
+    -- | The offsets of all function bodies, in the format [start1, end1,
+    --   start2, end2, ...] where all ends are exclusive.
+    debuggerDisassembleWasmModuleFunctionBodyOffsets :: [Int],
+    -- | The first chunk of disassembly.
+    debuggerDisassembleWasmModuleChunk :: DebuggerWasmDisassemblyChunk
+  }
+  deriving (Eq, Show)
+instance FromJSON DebuggerDisassembleWasmModule where
+  parseJSON = A.withObject "DebuggerDisassembleWasmModule" $ \o -> DebuggerDisassembleWasmModule
+    <$> o A..:? "streamId"
+    <*> o A..: "totalNumberOfLines"
+    <*> o A..: "functionBodyOffsets"
+    <*> o A..: "chunk"
+instance Command PDebuggerDisassembleWasmModule where
+  type CommandResponse PDebuggerDisassembleWasmModule = DebuggerDisassembleWasmModule
+  commandName _ = "Debugger.disassembleWasmModule"
+
+-- | Disassemble the next chunk of lines for the module corresponding to the
+--   stream. If disassembly is complete, this API will invalidate the streamId
+--   and return an empty chunk. Any subsequent calls for the now invalid stream
+--   will return errors.
+
+-- | Parameters of the 'Debugger.nextWasmDisassemblyChunk' command.
+data PDebuggerNextWasmDisassemblyChunk = PDebuggerNextWasmDisassemblyChunk
+  {
+    pDebuggerNextWasmDisassemblyChunkStreamId :: T.Text
+  }
+  deriving (Eq, Show)
+pDebuggerNextWasmDisassemblyChunk
+  :: T.Text
+  -> PDebuggerNextWasmDisassemblyChunk
+pDebuggerNextWasmDisassemblyChunk
+  arg_pDebuggerNextWasmDisassemblyChunkStreamId
+  = PDebuggerNextWasmDisassemblyChunk
+    arg_pDebuggerNextWasmDisassemblyChunkStreamId
+instance ToJSON PDebuggerNextWasmDisassemblyChunk where
+  toJSON p = A.object $ catMaybes [
+    ("streamId" A..=) <$> Just (pDebuggerNextWasmDisassemblyChunkStreamId p)
+    ]
+data DebuggerNextWasmDisassemblyChunk = DebuggerNextWasmDisassemblyChunk
+  {
+    -- | The next chunk of disassembly.
+    debuggerNextWasmDisassemblyChunkChunk :: DebuggerWasmDisassemblyChunk
+  }
+  deriving (Eq, Show)
+instance FromJSON DebuggerNextWasmDisassemblyChunk where
+  parseJSON = A.withObject "DebuggerNextWasmDisassemblyChunk" $ \o -> DebuggerNextWasmDisassemblyChunk
+    <$> o A..: "chunk"
+instance Command PDebuggerNextWasmDisassemblyChunk where
+  type CommandResponse PDebuggerNextWasmDisassemblyChunk = DebuggerNextWasmDisassemblyChunk
+  commandName _ = "Debugger.nextWasmDisassemblyChunk"
+
+-- | Returns stack trace with given `stackTraceId`.
+
+-- | Parameters of the 'Debugger.getStackTrace' command.
+data PDebuggerGetStackTrace = PDebuggerGetStackTrace
+  {
+    pDebuggerGetStackTraceStackTraceId :: Runtime.RuntimeStackTraceId
+  }
+  deriving (Eq, Show)
+pDebuggerGetStackTrace
+  :: Runtime.RuntimeStackTraceId
+  -> PDebuggerGetStackTrace
+pDebuggerGetStackTrace
+  arg_pDebuggerGetStackTraceStackTraceId
+  = PDebuggerGetStackTrace
+    arg_pDebuggerGetStackTraceStackTraceId
+instance ToJSON PDebuggerGetStackTrace where
+  toJSON p = A.object $ catMaybes [
+    ("stackTraceId" A..=) <$> Just (pDebuggerGetStackTraceStackTraceId p)
+    ]
+data DebuggerGetStackTrace = DebuggerGetStackTrace
+  {
+    debuggerGetStackTraceStackTrace :: Runtime.RuntimeStackTrace
+  }
+  deriving (Eq, Show)
+instance FromJSON DebuggerGetStackTrace where
+  parseJSON = A.withObject "DebuggerGetStackTrace" $ \o -> DebuggerGetStackTrace
+    <$> o A..: "stackTrace"
+instance Command PDebuggerGetStackTrace where
+  type CommandResponse PDebuggerGetStackTrace = DebuggerGetStackTrace
+  commandName _ = "Debugger.getStackTrace"
+
+-- | Stops on the next JavaScript statement.
+
+-- | Parameters of the 'Debugger.pause' command.
+data PDebuggerPause = PDebuggerPause
+  deriving (Eq, Show)
+pDebuggerPause
+  :: PDebuggerPause
+pDebuggerPause
+  = PDebuggerPause
+instance ToJSON PDebuggerPause where
+  toJSON _ = A.Null
+instance Command PDebuggerPause where
+  type CommandResponse PDebuggerPause = ()
+  commandName _ = "Debugger.pause"
+  fromJSON = const . A.Success . const ()
+
+-- | Removes JavaScript breakpoint.
+
+-- | Parameters of the 'Debugger.removeBreakpoint' command.
+data PDebuggerRemoveBreakpoint = PDebuggerRemoveBreakpoint
+  {
+    pDebuggerRemoveBreakpointBreakpointId :: DebuggerBreakpointId
+  }
+  deriving (Eq, Show)
+pDebuggerRemoveBreakpoint
+  :: DebuggerBreakpointId
+  -> PDebuggerRemoveBreakpoint
+pDebuggerRemoveBreakpoint
+  arg_pDebuggerRemoveBreakpointBreakpointId
+  = PDebuggerRemoveBreakpoint
+    arg_pDebuggerRemoveBreakpointBreakpointId
+instance ToJSON PDebuggerRemoveBreakpoint where
+  toJSON p = A.object $ catMaybes [
+    ("breakpointId" A..=) <$> Just (pDebuggerRemoveBreakpointBreakpointId p)
+    ]
+instance Command PDebuggerRemoveBreakpoint where
+  type CommandResponse PDebuggerRemoveBreakpoint = ()
+  commandName _ = "Debugger.removeBreakpoint"
+  fromJSON = const . A.Success . const ()
+
+-- | Restarts particular call frame from the beginning. The old, deprecated
+--   behavior of `restartFrame` is to stay paused and allow further CDP commands
+--   after a restart was scheduled. This can cause problems with restarting, so
+--   we now continue execution immediatly after it has been scheduled until we
+--   reach the beginning of the restarted frame.
+--   
+--   To stay back-wards compatible, `restartFrame` now expects a `mode`
+--   parameter to be present. If the `mode` parameter is missing, `restartFrame`
+--   errors out.
+--   
+--   The various return values are deprecated and `callFrames` is always empty.
+--   Use the call frames from the `Debugger#paused` events instead, that fires
+--   once V8 pauses at the beginning of the restarted function.
+
+-- | Parameters of the 'Debugger.restartFrame' command.
+data PDebuggerRestartFrameMode = PDebuggerRestartFrameModeStepInto
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PDebuggerRestartFrameMode where
+  parseJSON = A.withText "PDebuggerRestartFrameMode" $ \v -> case v of
+    "StepInto" -> pure PDebuggerRestartFrameModeStepInto
+    "_" -> fail "failed to parse PDebuggerRestartFrameMode"
+instance ToJSON PDebuggerRestartFrameMode where
+  toJSON v = A.String $ case v of
+    PDebuggerRestartFrameModeStepInto -> "StepInto"
+data PDebuggerRestartFrame = PDebuggerRestartFrame
+  {
+    -- | Call frame identifier to evaluate on.
+    pDebuggerRestartFrameCallFrameId :: DebuggerCallFrameId,
+    -- | The `mode` parameter must be present and set to 'StepInto', otherwise
+    --   `restartFrame` will error out.
+    pDebuggerRestartFrameMode :: Maybe PDebuggerRestartFrameMode
+  }
+  deriving (Eq, Show)
+pDebuggerRestartFrame
+  {-
+  -- | Call frame identifier to evaluate on.
+  -}
+  :: DebuggerCallFrameId
+  -> PDebuggerRestartFrame
+pDebuggerRestartFrame
+  arg_pDebuggerRestartFrameCallFrameId
+  = PDebuggerRestartFrame
+    arg_pDebuggerRestartFrameCallFrameId
+    Nothing
+instance ToJSON PDebuggerRestartFrame where
+  toJSON p = A.object $ catMaybes [
+    ("callFrameId" A..=) <$> Just (pDebuggerRestartFrameCallFrameId p),
+    ("mode" A..=) <$> (pDebuggerRestartFrameMode p)
+    ]
+instance Command PDebuggerRestartFrame where
+  type CommandResponse PDebuggerRestartFrame = ()
+  commandName _ = "Debugger.restartFrame"
+  fromJSON = const . A.Success . const ()
+
+-- | Resumes JavaScript execution.
+
+-- | Parameters of the 'Debugger.resume' command.
+data PDebuggerResume = PDebuggerResume
+  {
+    -- | Set to true to terminate execution upon resuming execution. In contrast
+    --   to Runtime.terminateExecution, this will allows to execute further
+    --   JavaScript (i.e. via evaluation) until execution of the paused code
+    --   is actually resumed, at which point termination is triggered.
+    --   If execution is currently not paused, this parameter has no effect.
+    pDebuggerResumeTerminateOnResume :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pDebuggerResume
+  :: PDebuggerResume
+pDebuggerResume
+  = PDebuggerResume
+    Nothing
+instance ToJSON PDebuggerResume where
+  toJSON p = A.object $ catMaybes [
+    ("terminateOnResume" A..=) <$> (pDebuggerResumeTerminateOnResume p)
+    ]
+instance Command PDebuggerResume where
+  type CommandResponse PDebuggerResume = ()
+  commandName _ = "Debugger.resume"
+  fromJSON = const . A.Success . const ()
+
+-- | Searches for given string in script content.
+
+-- | Parameters of the 'Debugger.searchInContent' command.
+data PDebuggerSearchInContent = PDebuggerSearchInContent
+  {
+    -- | Id of the script to search in.
+    pDebuggerSearchInContentScriptId :: Runtime.RuntimeScriptId,
+    -- | String to search for.
+    pDebuggerSearchInContentQuery :: T.Text,
+    -- | If true, search is case sensitive.
+    pDebuggerSearchInContentCaseSensitive :: Maybe Bool,
+    -- | If true, treats string parameter as regex.
+    pDebuggerSearchInContentIsRegex :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pDebuggerSearchInContent
+  {-
+  -- | Id of the script to search in.
+  -}
+  :: Runtime.RuntimeScriptId
+  {-
+  -- | String to search for.
+  -}
+  -> T.Text
+  -> PDebuggerSearchInContent
+pDebuggerSearchInContent
+  arg_pDebuggerSearchInContentScriptId
+  arg_pDebuggerSearchInContentQuery
+  = PDebuggerSearchInContent
+    arg_pDebuggerSearchInContentScriptId
+    arg_pDebuggerSearchInContentQuery
+    Nothing
+    Nothing
+instance ToJSON PDebuggerSearchInContent where
+  toJSON p = A.object $ catMaybes [
+    ("scriptId" A..=) <$> Just (pDebuggerSearchInContentScriptId p),
+    ("query" A..=) <$> Just (pDebuggerSearchInContentQuery p),
+    ("caseSensitive" A..=) <$> (pDebuggerSearchInContentCaseSensitive p),
+    ("isRegex" A..=) <$> (pDebuggerSearchInContentIsRegex p)
+    ]
+data DebuggerSearchInContent = DebuggerSearchInContent
+  {
+    -- | List of search matches.
+    debuggerSearchInContentResult :: [DebuggerSearchMatch]
+  }
+  deriving (Eq, Show)
+instance FromJSON DebuggerSearchInContent where
+  parseJSON = A.withObject "DebuggerSearchInContent" $ \o -> DebuggerSearchInContent
+    <$> o A..: "result"
+instance Command PDebuggerSearchInContent where
+  type CommandResponse PDebuggerSearchInContent = DebuggerSearchInContent
+  commandName _ = "Debugger.searchInContent"
+
+-- | Enables or disables async call stacks tracking.
+
+-- | Parameters of the 'Debugger.setAsyncCallStackDepth' command.
+data PDebuggerSetAsyncCallStackDepth = PDebuggerSetAsyncCallStackDepth
+  {
+    -- | Maximum depth of async call stacks. Setting to `0` will effectively disable collecting async
+    --   call stacks (default).
+    pDebuggerSetAsyncCallStackDepthMaxDepth :: Int
+  }
+  deriving (Eq, Show)
+pDebuggerSetAsyncCallStackDepth
+  {-
+  -- | Maximum depth of async call stacks. Setting to `0` will effectively disable collecting async
+  --   call stacks (default).
+  -}
+  :: Int
+  -> PDebuggerSetAsyncCallStackDepth
+pDebuggerSetAsyncCallStackDepth
+  arg_pDebuggerSetAsyncCallStackDepthMaxDepth
+  = PDebuggerSetAsyncCallStackDepth
+    arg_pDebuggerSetAsyncCallStackDepthMaxDepth
+instance ToJSON PDebuggerSetAsyncCallStackDepth where
+  toJSON p = A.object $ catMaybes [
+    ("maxDepth" A..=) <$> Just (pDebuggerSetAsyncCallStackDepthMaxDepth p)
+    ]
+instance Command PDebuggerSetAsyncCallStackDepth where
+  type CommandResponse PDebuggerSetAsyncCallStackDepth = ()
+  commandName _ = "Debugger.setAsyncCallStackDepth"
+  fromJSON = const . A.Success . const ()
+
+-- | Replace previous blackbox patterns with passed ones. Forces backend to skip stepping/pausing in
+--   scripts with url matching one of the patterns. VM will try to leave blackboxed script by
+--   performing 'step in' several times, finally resorting to 'step out' if unsuccessful.
+
+-- | Parameters of the 'Debugger.setBlackboxPatterns' command.
+data PDebuggerSetBlackboxPatterns = PDebuggerSetBlackboxPatterns
+  {
+    -- | Array of regexps that will be used to check script url for blackbox state.
+    pDebuggerSetBlackboxPatternsPatterns :: [T.Text]
+  }
+  deriving (Eq, Show)
+pDebuggerSetBlackboxPatterns
+  {-
+  -- | Array of regexps that will be used to check script url for blackbox state.
+  -}
+  :: [T.Text]
+  -> PDebuggerSetBlackboxPatterns
+pDebuggerSetBlackboxPatterns
+  arg_pDebuggerSetBlackboxPatternsPatterns
+  = PDebuggerSetBlackboxPatterns
+    arg_pDebuggerSetBlackboxPatternsPatterns
+instance ToJSON PDebuggerSetBlackboxPatterns where
+  toJSON p = A.object $ catMaybes [
+    ("patterns" A..=) <$> Just (pDebuggerSetBlackboxPatternsPatterns p)
+    ]
+instance Command PDebuggerSetBlackboxPatterns where
+  type CommandResponse PDebuggerSetBlackboxPatterns = ()
+  commandName _ = "Debugger.setBlackboxPatterns"
+  fromJSON = const . A.Success . const ()
+
+-- | Makes backend skip steps in the script in blackboxed ranges. VM will try leave blacklisted
+--   scripts by performing 'step in' several times, finally resorting to 'step out' if unsuccessful.
+--   Positions array contains positions where blackbox state is changed. First interval isn't
+--   blackboxed. Array should be sorted.
+
+-- | Parameters of the 'Debugger.setBlackboxedRanges' command.
+data PDebuggerSetBlackboxedRanges = PDebuggerSetBlackboxedRanges
+  {
+    -- | Id of the script.
+    pDebuggerSetBlackboxedRangesScriptId :: Runtime.RuntimeScriptId,
+    pDebuggerSetBlackboxedRangesPositions :: [DebuggerScriptPosition]
+  }
+  deriving (Eq, Show)
+pDebuggerSetBlackboxedRanges
+  {-
+  -- | Id of the script.
+  -}
+  :: Runtime.RuntimeScriptId
+  -> [DebuggerScriptPosition]
+  -> PDebuggerSetBlackboxedRanges
+pDebuggerSetBlackboxedRanges
+  arg_pDebuggerSetBlackboxedRangesScriptId
+  arg_pDebuggerSetBlackboxedRangesPositions
+  = PDebuggerSetBlackboxedRanges
+    arg_pDebuggerSetBlackboxedRangesScriptId
+    arg_pDebuggerSetBlackboxedRangesPositions
+instance ToJSON PDebuggerSetBlackboxedRanges where
+  toJSON p = A.object $ catMaybes [
+    ("scriptId" A..=) <$> Just (pDebuggerSetBlackboxedRangesScriptId p),
+    ("positions" A..=) <$> Just (pDebuggerSetBlackboxedRangesPositions p)
+    ]
+instance Command PDebuggerSetBlackboxedRanges where
+  type CommandResponse PDebuggerSetBlackboxedRanges = ()
+  commandName _ = "Debugger.setBlackboxedRanges"
+  fromJSON = const . A.Success . const ()
+
+-- | Sets JavaScript breakpoint at a given location.
+
+-- | Parameters of the 'Debugger.setBreakpoint' command.
+data PDebuggerSetBreakpoint = PDebuggerSetBreakpoint
+  {
+    -- | Location to set breakpoint in.
+    pDebuggerSetBreakpointLocation :: DebuggerLocation,
+    -- | Expression to use as a breakpoint condition. When specified, debugger will only stop on the
+    --   breakpoint if this expression evaluates to true.
+    pDebuggerSetBreakpointCondition :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+pDebuggerSetBreakpoint
+  {-
+  -- | Location to set breakpoint in.
+  -}
+  :: DebuggerLocation
+  -> PDebuggerSetBreakpoint
+pDebuggerSetBreakpoint
+  arg_pDebuggerSetBreakpointLocation
+  = PDebuggerSetBreakpoint
+    arg_pDebuggerSetBreakpointLocation
+    Nothing
+instance ToJSON PDebuggerSetBreakpoint where
+  toJSON p = A.object $ catMaybes [
+    ("location" A..=) <$> Just (pDebuggerSetBreakpointLocation p),
+    ("condition" A..=) <$> (pDebuggerSetBreakpointCondition p)
+    ]
+data DebuggerSetBreakpoint = DebuggerSetBreakpoint
+  {
+    -- | Id of the created breakpoint for further reference.
+    debuggerSetBreakpointBreakpointId :: DebuggerBreakpointId,
+    -- | Location this breakpoint resolved into.
+    debuggerSetBreakpointActualLocation :: DebuggerLocation
+  }
+  deriving (Eq, Show)
+instance FromJSON DebuggerSetBreakpoint where
+  parseJSON = A.withObject "DebuggerSetBreakpoint" $ \o -> DebuggerSetBreakpoint
+    <$> o A..: "breakpointId"
+    <*> o A..: "actualLocation"
+instance Command PDebuggerSetBreakpoint where
+  type CommandResponse PDebuggerSetBreakpoint = DebuggerSetBreakpoint
+  commandName _ = "Debugger.setBreakpoint"
+
+-- | Sets instrumentation breakpoint.
+
+-- | Parameters of the 'Debugger.setInstrumentationBreakpoint' command.
+data PDebuggerSetInstrumentationBreakpointInstrumentation = PDebuggerSetInstrumentationBreakpointInstrumentationBeforeScriptExecution | PDebuggerSetInstrumentationBreakpointInstrumentationBeforeScriptWithSourceMapExecution
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PDebuggerSetInstrumentationBreakpointInstrumentation where
+  parseJSON = A.withText "PDebuggerSetInstrumentationBreakpointInstrumentation" $ \v -> case v of
+    "beforeScriptExecution" -> pure PDebuggerSetInstrumentationBreakpointInstrumentationBeforeScriptExecution
+    "beforeScriptWithSourceMapExecution" -> pure PDebuggerSetInstrumentationBreakpointInstrumentationBeforeScriptWithSourceMapExecution
+    "_" -> fail "failed to parse PDebuggerSetInstrumentationBreakpointInstrumentation"
+instance ToJSON PDebuggerSetInstrumentationBreakpointInstrumentation where
+  toJSON v = A.String $ case v of
+    PDebuggerSetInstrumentationBreakpointInstrumentationBeforeScriptExecution -> "beforeScriptExecution"
+    PDebuggerSetInstrumentationBreakpointInstrumentationBeforeScriptWithSourceMapExecution -> "beforeScriptWithSourceMapExecution"
+data PDebuggerSetInstrumentationBreakpoint = PDebuggerSetInstrumentationBreakpoint
+  {
+    -- | Instrumentation name.
+    pDebuggerSetInstrumentationBreakpointInstrumentation :: PDebuggerSetInstrumentationBreakpointInstrumentation
+  }
+  deriving (Eq, Show)
+pDebuggerSetInstrumentationBreakpoint
+  {-
+  -- | Instrumentation name.
+  -}
+  :: PDebuggerSetInstrumentationBreakpointInstrumentation
+  -> PDebuggerSetInstrumentationBreakpoint
+pDebuggerSetInstrumentationBreakpoint
+  arg_pDebuggerSetInstrumentationBreakpointInstrumentation
+  = PDebuggerSetInstrumentationBreakpoint
+    arg_pDebuggerSetInstrumentationBreakpointInstrumentation
+instance ToJSON PDebuggerSetInstrumentationBreakpoint where
+  toJSON p = A.object $ catMaybes [
+    ("instrumentation" A..=) <$> Just (pDebuggerSetInstrumentationBreakpointInstrumentation p)
+    ]
+data DebuggerSetInstrumentationBreakpoint = DebuggerSetInstrumentationBreakpoint
+  {
+    -- | Id of the created breakpoint for further reference.
+    debuggerSetInstrumentationBreakpointBreakpointId :: DebuggerBreakpointId
+  }
+  deriving (Eq, Show)
+instance FromJSON DebuggerSetInstrumentationBreakpoint where
+  parseJSON = A.withObject "DebuggerSetInstrumentationBreakpoint" $ \o -> DebuggerSetInstrumentationBreakpoint
+    <$> o A..: "breakpointId"
+instance Command PDebuggerSetInstrumentationBreakpoint where
+  type CommandResponse PDebuggerSetInstrumentationBreakpoint = DebuggerSetInstrumentationBreakpoint
+  commandName _ = "Debugger.setInstrumentationBreakpoint"
+
+-- | Sets JavaScript breakpoint at given location specified either by URL or URL regex. Once this
+--   command is issued, all existing parsed scripts will have breakpoints resolved and returned in
+--   `locations` property. Further matching script parsing will result in subsequent
+--   `breakpointResolved` events issued. This logical breakpoint will survive page reloads.
+
+-- | Parameters of the 'Debugger.setBreakpointByUrl' command.
+data PDebuggerSetBreakpointByUrl = PDebuggerSetBreakpointByUrl
+  {
+    -- | Line number to set breakpoint at.
+    pDebuggerSetBreakpointByUrlLineNumber :: Int,
+    -- | URL of the resources to set breakpoint on.
+    pDebuggerSetBreakpointByUrlUrl :: Maybe T.Text,
+    -- | Regex pattern for the URLs of the resources to set breakpoints on. Either `url` or
+    --   `urlRegex` must be specified.
+    pDebuggerSetBreakpointByUrlUrlRegex :: Maybe T.Text,
+    -- | Script hash of the resources to set breakpoint on.
+    pDebuggerSetBreakpointByUrlScriptHash :: Maybe T.Text,
+    -- | Offset in the line to set breakpoint at.
+    pDebuggerSetBreakpointByUrlColumnNumber :: Maybe Int,
+    -- | Expression to use as a breakpoint condition. When specified, debugger will only stop on the
+    --   breakpoint if this expression evaluates to true.
+    pDebuggerSetBreakpointByUrlCondition :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+pDebuggerSetBreakpointByUrl
+  {-
+  -- | Line number to set breakpoint at.
+  -}
+  :: Int
+  -> PDebuggerSetBreakpointByUrl
+pDebuggerSetBreakpointByUrl
+  arg_pDebuggerSetBreakpointByUrlLineNumber
+  = PDebuggerSetBreakpointByUrl
+    arg_pDebuggerSetBreakpointByUrlLineNumber
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PDebuggerSetBreakpointByUrl where
+  toJSON p = A.object $ catMaybes [
+    ("lineNumber" A..=) <$> Just (pDebuggerSetBreakpointByUrlLineNumber p),
+    ("url" A..=) <$> (pDebuggerSetBreakpointByUrlUrl p),
+    ("urlRegex" A..=) <$> (pDebuggerSetBreakpointByUrlUrlRegex p),
+    ("scriptHash" A..=) <$> (pDebuggerSetBreakpointByUrlScriptHash p),
+    ("columnNumber" A..=) <$> (pDebuggerSetBreakpointByUrlColumnNumber p),
+    ("condition" A..=) <$> (pDebuggerSetBreakpointByUrlCondition p)
+    ]
+data DebuggerSetBreakpointByUrl = DebuggerSetBreakpointByUrl
+  {
+    -- | Id of the created breakpoint for further reference.
+    debuggerSetBreakpointByUrlBreakpointId :: DebuggerBreakpointId,
+    -- | List of the locations this breakpoint resolved into upon addition.
+    debuggerSetBreakpointByUrlLocations :: [DebuggerLocation]
+  }
+  deriving (Eq, Show)
+instance FromJSON DebuggerSetBreakpointByUrl where
+  parseJSON = A.withObject "DebuggerSetBreakpointByUrl" $ \o -> DebuggerSetBreakpointByUrl
+    <$> o A..: "breakpointId"
+    <*> o A..: "locations"
+instance Command PDebuggerSetBreakpointByUrl where
+  type CommandResponse PDebuggerSetBreakpointByUrl = DebuggerSetBreakpointByUrl
+  commandName _ = "Debugger.setBreakpointByUrl"
+
+-- | Sets JavaScript breakpoint before each call to the given function.
+--   If another function was created from the same source as a given one,
+--   calling it will also trigger the breakpoint.
+
+-- | Parameters of the 'Debugger.setBreakpointOnFunctionCall' command.
+data PDebuggerSetBreakpointOnFunctionCall = PDebuggerSetBreakpointOnFunctionCall
+  {
+    -- | Function object id.
+    pDebuggerSetBreakpointOnFunctionCallObjectId :: Runtime.RuntimeRemoteObjectId,
+    -- | Expression to use as a breakpoint condition. When specified, debugger will
+    --   stop on the breakpoint if this expression evaluates to true.
+    pDebuggerSetBreakpointOnFunctionCallCondition :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+pDebuggerSetBreakpointOnFunctionCall
+  {-
+  -- | Function object id.
+  -}
+  :: Runtime.RuntimeRemoteObjectId
+  -> PDebuggerSetBreakpointOnFunctionCall
+pDebuggerSetBreakpointOnFunctionCall
+  arg_pDebuggerSetBreakpointOnFunctionCallObjectId
+  = PDebuggerSetBreakpointOnFunctionCall
+    arg_pDebuggerSetBreakpointOnFunctionCallObjectId
+    Nothing
+instance ToJSON PDebuggerSetBreakpointOnFunctionCall where
+  toJSON p = A.object $ catMaybes [
+    ("objectId" A..=) <$> Just (pDebuggerSetBreakpointOnFunctionCallObjectId p),
+    ("condition" A..=) <$> (pDebuggerSetBreakpointOnFunctionCallCondition p)
+    ]
+data DebuggerSetBreakpointOnFunctionCall = DebuggerSetBreakpointOnFunctionCall
+  {
+    -- | Id of the created breakpoint for further reference.
+    debuggerSetBreakpointOnFunctionCallBreakpointId :: DebuggerBreakpointId
+  }
+  deriving (Eq, Show)
+instance FromJSON DebuggerSetBreakpointOnFunctionCall where
+  parseJSON = A.withObject "DebuggerSetBreakpointOnFunctionCall" $ \o -> DebuggerSetBreakpointOnFunctionCall
+    <$> o A..: "breakpointId"
+instance Command PDebuggerSetBreakpointOnFunctionCall where
+  type CommandResponse PDebuggerSetBreakpointOnFunctionCall = DebuggerSetBreakpointOnFunctionCall
+  commandName _ = "Debugger.setBreakpointOnFunctionCall"
+
+-- | Activates / deactivates all breakpoints on the page.
+
+-- | Parameters of the 'Debugger.setBreakpointsActive' command.
+data PDebuggerSetBreakpointsActive = PDebuggerSetBreakpointsActive
+  {
+    -- | New value for breakpoints active state.
+    pDebuggerSetBreakpointsActiveActive :: Bool
+  }
+  deriving (Eq, Show)
+pDebuggerSetBreakpointsActive
+  {-
+  -- | New value for breakpoints active state.
+  -}
+  :: Bool
+  -> PDebuggerSetBreakpointsActive
+pDebuggerSetBreakpointsActive
+  arg_pDebuggerSetBreakpointsActiveActive
+  = PDebuggerSetBreakpointsActive
+    arg_pDebuggerSetBreakpointsActiveActive
+instance ToJSON PDebuggerSetBreakpointsActive where
+  toJSON p = A.object $ catMaybes [
+    ("active" A..=) <$> Just (pDebuggerSetBreakpointsActiveActive p)
+    ]
+instance Command PDebuggerSetBreakpointsActive where
+  type CommandResponse PDebuggerSetBreakpointsActive = ()
+  commandName _ = "Debugger.setBreakpointsActive"
+  fromJSON = const . A.Success . const ()
+
+-- | Defines pause on exceptions state. Can be set to stop on all exceptions, uncaught exceptions or
+--   no exceptions. Initial pause on exceptions state is `none`.
+
+-- | Parameters of the 'Debugger.setPauseOnExceptions' command.
+data PDebuggerSetPauseOnExceptionsState = PDebuggerSetPauseOnExceptionsStateNone | PDebuggerSetPauseOnExceptionsStateUncaught | PDebuggerSetPauseOnExceptionsStateAll
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PDebuggerSetPauseOnExceptionsState where
+  parseJSON = A.withText "PDebuggerSetPauseOnExceptionsState" $ \v -> case v of
+    "none" -> pure PDebuggerSetPauseOnExceptionsStateNone
+    "uncaught" -> pure PDebuggerSetPauseOnExceptionsStateUncaught
+    "all" -> pure PDebuggerSetPauseOnExceptionsStateAll
+    "_" -> fail "failed to parse PDebuggerSetPauseOnExceptionsState"
+instance ToJSON PDebuggerSetPauseOnExceptionsState where
+  toJSON v = A.String $ case v of
+    PDebuggerSetPauseOnExceptionsStateNone -> "none"
+    PDebuggerSetPauseOnExceptionsStateUncaught -> "uncaught"
+    PDebuggerSetPauseOnExceptionsStateAll -> "all"
+data PDebuggerSetPauseOnExceptions = PDebuggerSetPauseOnExceptions
+  {
+    -- | Pause on exceptions mode.
+    pDebuggerSetPauseOnExceptionsState :: PDebuggerSetPauseOnExceptionsState
+  }
+  deriving (Eq, Show)
+pDebuggerSetPauseOnExceptions
+  {-
+  -- | Pause on exceptions mode.
+  -}
+  :: PDebuggerSetPauseOnExceptionsState
+  -> PDebuggerSetPauseOnExceptions
+pDebuggerSetPauseOnExceptions
+  arg_pDebuggerSetPauseOnExceptionsState
+  = PDebuggerSetPauseOnExceptions
+    arg_pDebuggerSetPauseOnExceptionsState
+instance ToJSON PDebuggerSetPauseOnExceptions where
+  toJSON p = A.object $ catMaybes [
+    ("state" A..=) <$> Just (pDebuggerSetPauseOnExceptionsState p)
+    ]
+instance Command PDebuggerSetPauseOnExceptions where
+  type CommandResponse PDebuggerSetPauseOnExceptions = ()
+  commandName _ = "Debugger.setPauseOnExceptions"
+  fromJSON = const . A.Success . const ()
+
+-- | Changes return value in top frame. Available only at return break position.
+
+-- | Parameters of the 'Debugger.setReturnValue' command.
+data PDebuggerSetReturnValue = PDebuggerSetReturnValue
+  {
+    -- | New return value.
+    pDebuggerSetReturnValueNewValue :: Runtime.RuntimeCallArgument
+  }
+  deriving (Eq, Show)
+pDebuggerSetReturnValue
+  {-
+  -- | New return value.
+  -}
+  :: Runtime.RuntimeCallArgument
+  -> PDebuggerSetReturnValue
+pDebuggerSetReturnValue
+  arg_pDebuggerSetReturnValueNewValue
+  = PDebuggerSetReturnValue
+    arg_pDebuggerSetReturnValueNewValue
+instance ToJSON PDebuggerSetReturnValue where
+  toJSON p = A.object $ catMaybes [
+    ("newValue" A..=) <$> Just (pDebuggerSetReturnValueNewValue p)
+    ]
+instance Command PDebuggerSetReturnValue where
+  type CommandResponse PDebuggerSetReturnValue = ()
+  commandName _ = "Debugger.setReturnValue"
+  fromJSON = const . A.Success . const ()
+
+-- | Edits JavaScript source live.
+--   
+--   In general, functions that are currently on the stack can not be edited with
+--   a single exception: If the edited function is the top-most stack frame and
+--   that is the only activation of that function on the stack. In this case
+--   the live edit will be successful and a `Debugger.restartFrame` for the
+--   top-most function is automatically triggered.
+
+-- | Parameters of the 'Debugger.setScriptSource' command.
+data PDebuggerSetScriptSource = PDebuggerSetScriptSource
+  {
+    -- | Id of the script to edit.
+    pDebuggerSetScriptSourceScriptId :: Runtime.RuntimeScriptId,
+    -- | New content of the script.
+    pDebuggerSetScriptSourceScriptSource :: T.Text,
+    -- | If true the change will not actually be applied. Dry run may be used to get result
+    --   description without actually modifying the code.
+    pDebuggerSetScriptSourceDryRun :: Maybe Bool,
+    -- | If true, then `scriptSource` is allowed to change the function on top of the stack
+    --   as long as the top-most stack frame is the only activation of that function.
+    pDebuggerSetScriptSourceAllowTopFrameEditing :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pDebuggerSetScriptSource
+  {-
+  -- | Id of the script to edit.
+  -}
+  :: Runtime.RuntimeScriptId
+  {-
+  -- | New content of the script.
+  -}
+  -> T.Text
+  -> PDebuggerSetScriptSource
+pDebuggerSetScriptSource
+  arg_pDebuggerSetScriptSourceScriptId
+  arg_pDebuggerSetScriptSourceScriptSource
+  = PDebuggerSetScriptSource
+    arg_pDebuggerSetScriptSourceScriptId
+    arg_pDebuggerSetScriptSourceScriptSource
+    Nothing
+    Nothing
+instance ToJSON PDebuggerSetScriptSource where
+  toJSON p = A.object $ catMaybes [
+    ("scriptId" A..=) <$> Just (pDebuggerSetScriptSourceScriptId p),
+    ("scriptSource" A..=) <$> Just (pDebuggerSetScriptSourceScriptSource p),
+    ("dryRun" A..=) <$> (pDebuggerSetScriptSourceDryRun p),
+    ("allowTopFrameEditing" A..=) <$> (pDebuggerSetScriptSourceAllowTopFrameEditing p)
+    ]
+data DebuggerSetScriptSourceStatus = DebuggerSetScriptSourceStatusOk | DebuggerSetScriptSourceStatusCompileError | DebuggerSetScriptSourceStatusBlockedByActiveGenerator | DebuggerSetScriptSourceStatusBlockedByActiveFunction
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON DebuggerSetScriptSourceStatus where
+  parseJSON = A.withText "DebuggerSetScriptSourceStatus" $ \v -> case v of
+    "Ok" -> pure DebuggerSetScriptSourceStatusOk
+    "CompileError" -> pure DebuggerSetScriptSourceStatusCompileError
+    "BlockedByActiveGenerator" -> pure DebuggerSetScriptSourceStatusBlockedByActiveGenerator
+    "BlockedByActiveFunction" -> pure DebuggerSetScriptSourceStatusBlockedByActiveFunction
+    "_" -> fail "failed to parse DebuggerSetScriptSourceStatus"
+instance ToJSON DebuggerSetScriptSourceStatus where
+  toJSON v = A.String $ case v of
+    DebuggerSetScriptSourceStatusOk -> "Ok"
+    DebuggerSetScriptSourceStatusCompileError -> "CompileError"
+    DebuggerSetScriptSourceStatusBlockedByActiveGenerator -> "BlockedByActiveGenerator"
+    DebuggerSetScriptSourceStatusBlockedByActiveFunction -> "BlockedByActiveFunction"
+data DebuggerSetScriptSource = DebuggerSetScriptSource
+  {
+    -- | Whether the operation was successful or not. Only `Ok` denotes a
+    --   successful live edit while the other enum variants denote why
+    --   the live edit failed.
+    debuggerSetScriptSourceStatus :: DebuggerSetScriptSourceStatus,
+    -- | Exception details if any. Only present when `status` is `CompileError`.
+    debuggerSetScriptSourceExceptionDetails :: Maybe Runtime.RuntimeExceptionDetails
+  }
+  deriving (Eq, Show)
+instance FromJSON DebuggerSetScriptSource where
+  parseJSON = A.withObject "DebuggerSetScriptSource" $ \o -> DebuggerSetScriptSource
+    <$> o A..: "status"
+    <*> o A..:? "exceptionDetails"
+instance Command PDebuggerSetScriptSource where
+  type CommandResponse PDebuggerSetScriptSource = DebuggerSetScriptSource
+  commandName _ = "Debugger.setScriptSource"
+
+-- | Makes page not interrupt on any pauses (breakpoint, exception, dom exception etc).
+
+-- | Parameters of the 'Debugger.setSkipAllPauses' command.
+data PDebuggerSetSkipAllPauses = PDebuggerSetSkipAllPauses
+  {
+    -- | New value for skip pauses state.
+    pDebuggerSetSkipAllPausesSkip :: Bool
+  }
+  deriving (Eq, Show)
+pDebuggerSetSkipAllPauses
+  {-
+  -- | New value for skip pauses state.
+  -}
+  :: Bool
+  -> PDebuggerSetSkipAllPauses
+pDebuggerSetSkipAllPauses
+  arg_pDebuggerSetSkipAllPausesSkip
+  = PDebuggerSetSkipAllPauses
+    arg_pDebuggerSetSkipAllPausesSkip
+instance ToJSON PDebuggerSetSkipAllPauses where
+  toJSON p = A.object $ catMaybes [
+    ("skip" A..=) <$> Just (pDebuggerSetSkipAllPausesSkip p)
+    ]
+instance Command PDebuggerSetSkipAllPauses where
+  type CommandResponse PDebuggerSetSkipAllPauses = ()
+  commandName _ = "Debugger.setSkipAllPauses"
+  fromJSON = const . A.Success . const ()
+
+-- | Changes value of variable in a callframe. Object-based scopes are not supported and must be
+--   mutated manually.
+
+-- | Parameters of the 'Debugger.setVariableValue' command.
+data PDebuggerSetVariableValue = PDebuggerSetVariableValue
+  {
+    -- | 0-based number of scope as was listed in scope chain. Only 'local', 'closure' and 'catch'
+    --   scope types are allowed. Other scopes could be manipulated manually.
+    pDebuggerSetVariableValueScopeNumber :: Int,
+    -- | Variable name.
+    pDebuggerSetVariableValueVariableName :: T.Text,
+    -- | New variable value.
+    pDebuggerSetVariableValueNewValue :: Runtime.RuntimeCallArgument,
+    -- | Id of callframe that holds variable.
+    pDebuggerSetVariableValueCallFrameId :: DebuggerCallFrameId
+  }
+  deriving (Eq, Show)
+pDebuggerSetVariableValue
+  {-
+  -- | 0-based number of scope as was listed in scope chain. Only 'local', 'closure' and 'catch'
+  --   scope types are allowed. Other scopes could be manipulated manually.
+  -}
+  :: Int
+  {-
+  -- | Variable name.
+  -}
+  -> T.Text
+  {-
+  -- | New variable value.
+  -}
+  -> Runtime.RuntimeCallArgument
+  {-
+  -- | Id of callframe that holds variable.
+  -}
+  -> DebuggerCallFrameId
+  -> PDebuggerSetVariableValue
+pDebuggerSetVariableValue
+  arg_pDebuggerSetVariableValueScopeNumber
+  arg_pDebuggerSetVariableValueVariableName
+  arg_pDebuggerSetVariableValueNewValue
+  arg_pDebuggerSetVariableValueCallFrameId
+  = PDebuggerSetVariableValue
+    arg_pDebuggerSetVariableValueScopeNumber
+    arg_pDebuggerSetVariableValueVariableName
+    arg_pDebuggerSetVariableValueNewValue
+    arg_pDebuggerSetVariableValueCallFrameId
+instance ToJSON PDebuggerSetVariableValue where
+  toJSON p = A.object $ catMaybes [
+    ("scopeNumber" A..=) <$> Just (pDebuggerSetVariableValueScopeNumber p),
+    ("variableName" A..=) <$> Just (pDebuggerSetVariableValueVariableName p),
+    ("newValue" A..=) <$> Just (pDebuggerSetVariableValueNewValue p),
+    ("callFrameId" A..=) <$> Just (pDebuggerSetVariableValueCallFrameId p)
+    ]
+instance Command PDebuggerSetVariableValue where
+  type CommandResponse PDebuggerSetVariableValue = ()
+  commandName _ = "Debugger.setVariableValue"
+  fromJSON = const . A.Success . const ()
+
+-- | Steps into the function call.
+
+-- | Parameters of the 'Debugger.stepInto' command.
+data PDebuggerStepInto = PDebuggerStepInto
+  {
+    -- | Debugger will pause on the execution of the first async task which was scheduled
+    --   before next pause.
+    pDebuggerStepIntoBreakOnAsyncCall :: Maybe Bool,
+    -- | The skipList specifies location ranges that should be skipped on step into.
+    pDebuggerStepIntoSkipList :: Maybe [DebuggerLocationRange]
+  }
+  deriving (Eq, Show)
+pDebuggerStepInto
+  :: PDebuggerStepInto
+pDebuggerStepInto
+  = PDebuggerStepInto
+    Nothing
+    Nothing
+instance ToJSON PDebuggerStepInto where
+  toJSON p = A.object $ catMaybes [
+    ("breakOnAsyncCall" A..=) <$> (pDebuggerStepIntoBreakOnAsyncCall p),
+    ("skipList" A..=) <$> (pDebuggerStepIntoSkipList p)
+    ]
+instance Command PDebuggerStepInto where
+  type CommandResponse PDebuggerStepInto = ()
+  commandName _ = "Debugger.stepInto"
+  fromJSON = const . A.Success . const ()
+
+-- | Steps out of the function call.
+
+-- | Parameters of the 'Debugger.stepOut' command.
+data PDebuggerStepOut = PDebuggerStepOut
+  deriving (Eq, Show)
+pDebuggerStepOut
+  :: PDebuggerStepOut
+pDebuggerStepOut
+  = PDebuggerStepOut
+instance ToJSON PDebuggerStepOut where
+  toJSON _ = A.Null
+instance Command PDebuggerStepOut where
+  type CommandResponse PDebuggerStepOut = ()
+  commandName _ = "Debugger.stepOut"
+  fromJSON = const . A.Success . const ()
+
+-- | Steps over the statement.
+
+-- | Parameters of the 'Debugger.stepOver' command.
+data PDebuggerStepOver = PDebuggerStepOver
+  {
+    -- | The skipList specifies location ranges that should be skipped on step over.
+    pDebuggerStepOverSkipList :: Maybe [DebuggerLocationRange]
+  }
+  deriving (Eq, Show)
+pDebuggerStepOver
+  :: PDebuggerStepOver
+pDebuggerStepOver
+  = PDebuggerStepOver
+    Nothing
+instance ToJSON PDebuggerStepOver where
+  toJSON p = A.object $ catMaybes [
+    ("skipList" A..=) <$> (pDebuggerStepOverSkipList p)
+    ]
+instance Command PDebuggerStepOver where
+  type CommandResponse PDebuggerStepOver = ()
+  commandName _ = "Debugger.stepOver"
+  fromJSON = const . A.Success . const ()
+
diff --git a/src/CDP/Domains/DeviceOrientation.hs b/src/CDP/Domains/DeviceOrientation.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains/DeviceOrientation.hs
@@ -0,0 +1,111 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+
+
+{- |
+= DeviceOrientation
+
+-}
+
+
+module CDP.Domains.DeviceOrientation (module CDP.Domains.DeviceOrientation) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+
+
+
+-- | Clears the overridden Device Orientation.
+
+-- | Parameters of the 'DeviceOrientation.clearDeviceOrientationOverride' command.
+data PDeviceOrientationClearDeviceOrientationOverride = PDeviceOrientationClearDeviceOrientationOverride
+  deriving (Eq, Show)
+pDeviceOrientationClearDeviceOrientationOverride
+  :: PDeviceOrientationClearDeviceOrientationOverride
+pDeviceOrientationClearDeviceOrientationOverride
+  = PDeviceOrientationClearDeviceOrientationOverride
+instance ToJSON PDeviceOrientationClearDeviceOrientationOverride where
+  toJSON _ = A.Null
+instance Command PDeviceOrientationClearDeviceOrientationOverride where
+  type CommandResponse PDeviceOrientationClearDeviceOrientationOverride = ()
+  commandName _ = "DeviceOrientation.clearDeviceOrientationOverride"
+  fromJSON = const . A.Success . const ()
+
+-- | Overrides the Device Orientation.
+
+-- | Parameters of the 'DeviceOrientation.setDeviceOrientationOverride' command.
+data PDeviceOrientationSetDeviceOrientationOverride = PDeviceOrientationSetDeviceOrientationOverride
+  {
+    -- | Mock alpha
+    pDeviceOrientationSetDeviceOrientationOverrideAlpha :: Double,
+    -- | Mock beta
+    pDeviceOrientationSetDeviceOrientationOverrideBeta :: Double,
+    -- | Mock gamma
+    pDeviceOrientationSetDeviceOrientationOverrideGamma :: Double
+  }
+  deriving (Eq, Show)
+pDeviceOrientationSetDeviceOrientationOverride
+  {-
+  -- | Mock alpha
+  -}
+  :: Double
+  {-
+  -- | Mock beta
+  -}
+  -> Double
+  {-
+  -- | Mock gamma
+  -}
+  -> Double
+  -> PDeviceOrientationSetDeviceOrientationOverride
+pDeviceOrientationSetDeviceOrientationOverride
+  arg_pDeviceOrientationSetDeviceOrientationOverrideAlpha
+  arg_pDeviceOrientationSetDeviceOrientationOverrideBeta
+  arg_pDeviceOrientationSetDeviceOrientationOverrideGamma
+  = PDeviceOrientationSetDeviceOrientationOverride
+    arg_pDeviceOrientationSetDeviceOrientationOverrideAlpha
+    arg_pDeviceOrientationSetDeviceOrientationOverrideBeta
+    arg_pDeviceOrientationSetDeviceOrientationOverrideGamma
+instance ToJSON PDeviceOrientationSetDeviceOrientationOverride where
+  toJSON p = A.object $ catMaybes [
+    ("alpha" A..=) <$> Just (pDeviceOrientationSetDeviceOrientationOverrideAlpha p),
+    ("beta" A..=) <$> Just (pDeviceOrientationSetDeviceOrientationOverrideBeta p),
+    ("gamma" A..=) <$> Just (pDeviceOrientationSetDeviceOrientationOverrideGamma p)
+    ]
+instance Command PDeviceOrientationSetDeviceOrientationOverride where
+  type CommandResponse PDeviceOrientationSetDeviceOrientationOverride = ()
+  commandName _ = "DeviceOrientation.setDeviceOrientationOverride"
+  fromJSON = const . A.Success . const ()
+
diff --git a/src/CDP/Domains/EventBreakpoints.hs b/src/CDP/Domains/EventBreakpoints.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains/EventBreakpoints.hs
@@ -0,0 +1,109 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+
+
+{- |
+= EventBreakpoints
+
+EventBreakpoints permits setting breakpoints on particular operations and
+events in targets that run JavaScript but do not have a DOM.
+JavaScript execution will stop on these operations as if there was a regular
+breakpoint set.
+-}
+
+
+module CDP.Domains.EventBreakpoints (module CDP.Domains.EventBreakpoints) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+
+
+
+-- | Sets breakpoint on particular native event.
+
+-- | Parameters of the 'EventBreakpoints.setInstrumentationBreakpoint' command.
+data PEventBreakpointsSetInstrumentationBreakpoint = PEventBreakpointsSetInstrumentationBreakpoint
+  {
+    -- | Instrumentation name to stop on.
+    pEventBreakpointsSetInstrumentationBreakpointEventName :: T.Text
+  }
+  deriving (Eq, Show)
+pEventBreakpointsSetInstrumentationBreakpoint
+  {-
+  -- | Instrumentation name to stop on.
+  -}
+  :: T.Text
+  -> PEventBreakpointsSetInstrumentationBreakpoint
+pEventBreakpointsSetInstrumentationBreakpoint
+  arg_pEventBreakpointsSetInstrumentationBreakpointEventName
+  = PEventBreakpointsSetInstrumentationBreakpoint
+    arg_pEventBreakpointsSetInstrumentationBreakpointEventName
+instance ToJSON PEventBreakpointsSetInstrumentationBreakpoint where
+  toJSON p = A.object $ catMaybes [
+    ("eventName" A..=) <$> Just (pEventBreakpointsSetInstrumentationBreakpointEventName p)
+    ]
+instance Command PEventBreakpointsSetInstrumentationBreakpoint where
+  type CommandResponse PEventBreakpointsSetInstrumentationBreakpoint = ()
+  commandName _ = "EventBreakpoints.setInstrumentationBreakpoint"
+  fromJSON = const . A.Success . const ()
+
+-- | Removes breakpoint on particular native event.
+
+-- | Parameters of the 'EventBreakpoints.removeInstrumentationBreakpoint' command.
+data PEventBreakpointsRemoveInstrumentationBreakpoint = PEventBreakpointsRemoveInstrumentationBreakpoint
+  {
+    -- | Instrumentation name to stop on.
+    pEventBreakpointsRemoveInstrumentationBreakpointEventName :: T.Text
+  }
+  deriving (Eq, Show)
+pEventBreakpointsRemoveInstrumentationBreakpoint
+  {-
+  -- | Instrumentation name to stop on.
+  -}
+  :: T.Text
+  -> PEventBreakpointsRemoveInstrumentationBreakpoint
+pEventBreakpointsRemoveInstrumentationBreakpoint
+  arg_pEventBreakpointsRemoveInstrumentationBreakpointEventName
+  = PEventBreakpointsRemoveInstrumentationBreakpoint
+    arg_pEventBreakpointsRemoveInstrumentationBreakpointEventName
+instance ToJSON PEventBreakpointsRemoveInstrumentationBreakpoint where
+  toJSON p = A.object $ catMaybes [
+    ("eventName" A..=) <$> Just (pEventBreakpointsRemoveInstrumentationBreakpointEventName p)
+    ]
+instance Command PEventBreakpointsRemoveInstrumentationBreakpoint where
+  type CommandResponse PEventBreakpointsRemoveInstrumentationBreakpoint = ()
+  commandName _ = "EventBreakpoints.removeInstrumentationBreakpoint"
+  fromJSON = const . A.Success . const ()
+
diff --git a/src/CDP/Domains/Fetch.hs b/src/CDP/Domains/Fetch.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains/Fetch.hs
@@ -0,0 +1,627 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+
+
+{- |
+= Fetch
+
+A domain for letting clients substitute browser's network layer with client code.
+-}
+
+
+module CDP.Domains.Fetch (module CDP.Domains.Fetch) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+
+import CDP.Domains.DOMPageNetworkEmulationSecurity as DOMPageNetworkEmulationSecurity
+import CDP.Domains.IO as IO
+
+
+-- | Type 'Fetch.RequestId'.
+--   Unique request identifier.
+type FetchRequestId = T.Text
+
+-- | Type 'Fetch.RequestStage'.
+--   Stages of the request to handle. Request will intercept before the request is
+--   sent. Response will intercept after the response is received (but before response
+--   body is received).
+data FetchRequestStage = FetchRequestStageRequest | FetchRequestStageResponse
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON FetchRequestStage where
+  parseJSON = A.withText "FetchRequestStage" $ \v -> case v of
+    "Request" -> pure FetchRequestStageRequest
+    "Response" -> pure FetchRequestStageResponse
+    "_" -> fail "failed to parse FetchRequestStage"
+instance ToJSON FetchRequestStage where
+  toJSON v = A.String $ case v of
+    FetchRequestStageRequest -> "Request"
+    FetchRequestStageResponse -> "Response"
+
+-- | Type 'Fetch.RequestPattern'.
+data FetchRequestPattern = FetchRequestPattern
+  {
+    -- | Wildcards (`'*'` -> zero or more, `'?'` -> exactly one) are allowed. Escape character is
+    --   backslash. Omitting is equivalent to `"*"`.
+    fetchRequestPatternUrlPattern :: Maybe T.Text,
+    -- | If set, only requests for matching resource types will be intercepted.
+    fetchRequestPatternResourceType :: Maybe DOMPageNetworkEmulationSecurity.NetworkResourceType,
+    -- | Stage at which to begin intercepting requests. Default is Request.
+    fetchRequestPatternRequestStage :: Maybe FetchRequestStage
+  }
+  deriving (Eq, Show)
+instance FromJSON FetchRequestPattern where
+  parseJSON = A.withObject "FetchRequestPattern" $ \o -> FetchRequestPattern
+    <$> o A..:? "urlPattern"
+    <*> o A..:? "resourceType"
+    <*> o A..:? "requestStage"
+instance ToJSON FetchRequestPattern where
+  toJSON p = A.object $ catMaybes [
+    ("urlPattern" A..=) <$> (fetchRequestPatternUrlPattern p),
+    ("resourceType" A..=) <$> (fetchRequestPatternResourceType p),
+    ("requestStage" A..=) <$> (fetchRequestPatternRequestStage p)
+    ]
+
+-- | Type 'Fetch.HeaderEntry'.
+--   Response HTTP header entry
+data FetchHeaderEntry = FetchHeaderEntry
+  {
+    fetchHeaderEntryName :: T.Text,
+    fetchHeaderEntryValue :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON FetchHeaderEntry where
+  parseJSON = A.withObject "FetchHeaderEntry" $ \o -> FetchHeaderEntry
+    <$> o A..: "name"
+    <*> o A..: "value"
+instance ToJSON FetchHeaderEntry where
+  toJSON p = A.object $ catMaybes [
+    ("name" A..=) <$> Just (fetchHeaderEntryName p),
+    ("value" A..=) <$> Just (fetchHeaderEntryValue p)
+    ]
+
+-- | Type 'Fetch.AuthChallenge'.
+--   Authorization challenge for HTTP status code 401 or 407.
+data FetchAuthChallengeSource = FetchAuthChallengeSourceServer | FetchAuthChallengeSourceProxy
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON FetchAuthChallengeSource where
+  parseJSON = A.withText "FetchAuthChallengeSource" $ \v -> case v of
+    "Server" -> pure FetchAuthChallengeSourceServer
+    "Proxy" -> pure FetchAuthChallengeSourceProxy
+    "_" -> fail "failed to parse FetchAuthChallengeSource"
+instance ToJSON FetchAuthChallengeSource where
+  toJSON v = A.String $ case v of
+    FetchAuthChallengeSourceServer -> "Server"
+    FetchAuthChallengeSourceProxy -> "Proxy"
+data FetchAuthChallenge = FetchAuthChallenge
+  {
+    -- | Source of the authentication challenge.
+    fetchAuthChallengeSource :: Maybe FetchAuthChallengeSource,
+    -- | Origin of the challenger.
+    fetchAuthChallengeOrigin :: T.Text,
+    -- | The authentication scheme used, such as basic or digest
+    fetchAuthChallengeScheme :: T.Text,
+    -- | The realm of the challenge. May be empty.
+    fetchAuthChallengeRealm :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON FetchAuthChallenge where
+  parseJSON = A.withObject "FetchAuthChallenge" $ \o -> FetchAuthChallenge
+    <$> o A..:? "source"
+    <*> o A..: "origin"
+    <*> o A..: "scheme"
+    <*> o A..: "realm"
+instance ToJSON FetchAuthChallenge where
+  toJSON p = A.object $ catMaybes [
+    ("source" A..=) <$> (fetchAuthChallengeSource p),
+    ("origin" A..=) <$> Just (fetchAuthChallengeOrigin p),
+    ("scheme" A..=) <$> Just (fetchAuthChallengeScheme p),
+    ("realm" A..=) <$> Just (fetchAuthChallengeRealm p)
+    ]
+
+-- | Type 'Fetch.AuthChallengeResponse'.
+--   Response to an AuthChallenge.
+data FetchAuthChallengeResponseResponse = FetchAuthChallengeResponseResponseDefault | FetchAuthChallengeResponseResponseCancelAuth | FetchAuthChallengeResponseResponseProvideCredentials
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON FetchAuthChallengeResponseResponse where
+  parseJSON = A.withText "FetchAuthChallengeResponseResponse" $ \v -> case v of
+    "Default" -> pure FetchAuthChallengeResponseResponseDefault
+    "CancelAuth" -> pure FetchAuthChallengeResponseResponseCancelAuth
+    "ProvideCredentials" -> pure FetchAuthChallengeResponseResponseProvideCredentials
+    "_" -> fail "failed to parse FetchAuthChallengeResponseResponse"
+instance ToJSON FetchAuthChallengeResponseResponse where
+  toJSON v = A.String $ case v of
+    FetchAuthChallengeResponseResponseDefault -> "Default"
+    FetchAuthChallengeResponseResponseCancelAuth -> "CancelAuth"
+    FetchAuthChallengeResponseResponseProvideCredentials -> "ProvideCredentials"
+data FetchAuthChallengeResponse = FetchAuthChallengeResponse
+  {
+    -- | The decision on what to do in response to the authorization challenge.  Default means
+    --   deferring to the default behavior of the net stack, which will likely either the Cancel
+    --   authentication or display a popup dialog box.
+    fetchAuthChallengeResponseResponse :: FetchAuthChallengeResponseResponse,
+    -- | The username to provide, possibly empty. Should only be set if response is
+    --   ProvideCredentials.
+    fetchAuthChallengeResponseUsername :: Maybe T.Text,
+    -- | The password to provide, possibly empty. Should only be set if response is
+    --   ProvideCredentials.
+    fetchAuthChallengeResponsePassword :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON FetchAuthChallengeResponse where
+  parseJSON = A.withObject "FetchAuthChallengeResponse" $ \o -> FetchAuthChallengeResponse
+    <$> o A..: "response"
+    <*> o A..:? "username"
+    <*> o A..:? "password"
+instance ToJSON FetchAuthChallengeResponse where
+  toJSON p = A.object $ catMaybes [
+    ("response" A..=) <$> Just (fetchAuthChallengeResponseResponse p),
+    ("username" A..=) <$> (fetchAuthChallengeResponseUsername p),
+    ("password" A..=) <$> (fetchAuthChallengeResponsePassword p)
+    ]
+
+-- | Type of the 'Fetch.requestPaused' event.
+data FetchRequestPaused = FetchRequestPaused
+  {
+    -- | Each request the page makes will have a unique id.
+    fetchRequestPausedRequestId :: FetchRequestId,
+    -- | The details of the request.
+    fetchRequestPausedRequest :: DOMPageNetworkEmulationSecurity.NetworkRequest,
+    -- | The id of the frame that initiated the request.
+    fetchRequestPausedFrameId :: DOMPageNetworkEmulationSecurity.PageFrameId,
+    -- | How the requested resource will be used.
+    fetchRequestPausedResourceType :: DOMPageNetworkEmulationSecurity.NetworkResourceType,
+    -- | Response error if intercepted at response stage.
+    fetchRequestPausedResponseErrorReason :: Maybe DOMPageNetworkEmulationSecurity.NetworkErrorReason,
+    -- | Response code if intercepted at response stage.
+    fetchRequestPausedResponseStatusCode :: Maybe Int,
+    -- | Response status text if intercepted at response stage.
+    fetchRequestPausedResponseStatusText :: Maybe T.Text,
+    -- | Response headers if intercepted at the response stage.
+    fetchRequestPausedResponseHeaders :: Maybe [FetchHeaderEntry],
+    -- | If the intercepted request had a corresponding Network.requestWillBeSent event fired for it,
+    --   then this networkId will be the same as the requestId present in the requestWillBeSent event.
+    fetchRequestPausedNetworkId :: Maybe DOMPageNetworkEmulationSecurity.NetworkRequestId,
+    -- | If the request is due to a redirect response from the server, the id of the request that
+    --   has caused the redirect.
+    fetchRequestPausedRedirectedRequestId :: Maybe FetchRequestId
+  }
+  deriving (Eq, Show)
+instance FromJSON FetchRequestPaused where
+  parseJSON = A.withObject "FetchRequestPaused" $ \o -> FetchRequestPaused
+    <$> o A..: "requestId"
+    <*> o A..: "request"
+    <*> o A..: "frameId"
+    <*> o A..: "resourceType"
+    <*> o A..:? "responseErrorReason"
+    <*> o A..:? "responseStatusCode"
+    <*> o A..:? "responseStatusText"
+    <*> o A..:? "responseHeaders"
+    <*> o A..:? "networkId"
+    <*> o A..:? "redirectedRequestId"
+instance Event FetchRequestPaused where
+  eventName _ = "Fetch.requestPaused"
+
+-- | Type of the 'Fetch.authRequired' event.
+data FetchAuthRequired = FetchAuthRequired
+  {
+    -- | Each request the page makes will have a unique id.
+    fetchAuthRequiredRequestId :: FetchRequestId,
+    -- | The details of the request.
+    fetchAuthRequiredRequest :: DOMPageNetworkEmulationSecurity.NetworkRequest,
+    -- | The id of the frame that initiated the request.
+    fetchAuthRequiredFrameId :: DOMPageNetworkEmulationSecurity.PageFrameId,
+    -- | How the requested resource will be used.
+    fetchAuthRequiredResourceType :: DOMPageNetworkEmulationSecurity.NetworkResourceType,
+    -- | Details of the Authorization Challenge encountered.
+    --   If this is set, client should respond with continueRequest that
+    --   contains AuthChallengeResponse.
+    fetchAuthRequiredAuthChallenge :: FetchAuthChallenge
+  }
+  deriving (Eq, Show)
+instance FromJSON FetchAuthRequired where
+  parseJSON = A.withObject "FetchAuthRequired" $ \o -> FetchAuthRequired
+    <$> o A..: "requestId"
+    <*> o A..: "request"
+    <*> o A..: "frameId"
+    <*> o A..: "resourceType"
+    <*> o A..: "authChallenge"
+instance Event FetchAuthRequired where
+  eventName _ = "Fetch.authRequired"
+
+-- | Disables the fetch domain.
+
+-- | Parameters of the 'Fetch.disable' command.
+data PFetchDisable = PFetchDisable
+  deriving (Eq, Show)
+pFetchDisable
+  :: PFetchDisable
+pFetchDisable
+  = PFetchDisable
+instance ToJSON PFetchDisable where
+  toJSON _ = A.Null
+instance Command PFetchDisable where
+  type CommandResponse PFetchDisable = ()
+  commandName _ = "Fetch.disable"
+  fromJSON = const . A.Success . const ()
+
+-- | Enables issuing of requestPaused events. A request will be paused until client
+--   calls one of failRequest, fulfillRequest or continueRequest/continueWithAuth.
+
+-- | Parameters of the 'Fetch.enable' command.
+data PFetchEnable = PFetchEnable
+  {
+    -- | If specified, only requests matching any of these patterns will produce
+    --   fetchRequested event and will be paused until clients response. If not set,
+    --   all requests will be affected.
+    pFetchEnablePatterns :: Maybe [FetchRequestPattern],
+    -- | If true, authRequired events will be issued and requests will be paused
+    --   expecting a call to continueWithAuth.
+    pFetchEnableHandleAuthRequests :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pFetchEnable
+  :: PFetchEnable
+pFetchEnable
+  = PFetchEnable
+    Nothing
+    Nothing
+instance ToJSON PFetchEnable where
+  toJSON p = A.object $ catMaybes [
+    ("patterns" A..=) <$> (pFetchEnablePatterns p),
+    ("handleAuthRequests" A..=) <$> (pFetchEnableHandleAuthRequests p)
+    ]
+instance Command PFetchEnable where
+  type CommandResponse PFetchEnable = ()
+  commandName _ = "Fetch.enable"
+  fromJSON = const . A.Success . const ()
+
+-- | Causes the request to fail with specified reason.
+
+-- | Parameters of the 'Fetch.failRequest' command.
+data PFetchFailRequest = PFetchFailRequest
+  {
+    -- | An id the client received in requestPaused event.
+    pFetchFailRequestRequestId :: FetchRequestId,
+    -- | Causes the request to fail with the given reason.
+    pFetchFailRequestErrorReason :: DOMPageNetworkEmulationSecurity.NetworkErrorReason
+  }
+  deriving (Eq, Show)
+pFetchFailRequest
+  {-
+  -- | An id the client received in requestPaused event.
+  -}
+  :: FetchRequestId
+  {-
+  -- | Causes the request to fail with the given reason.
+  -}
+  -> DOMPageNetworkEmulationSecurity.NetworkErrorReason
+  -> PFetchFailRequest
+pFetchFailRequest
+  arg_pFetchFailRequestRequestId
+  arg_pFetchFailRequestErrorReason
+  = PFetchFailRequest
+    arg_pFetchFailRequestRequestId
+    arg_pFetchFailRequestErrorReason
+instance ToJSON PFetchFailRequest where
+  toJSON p = A.object $ catMaybes [
+    ("requestId" A..=) <$> Just (pFetchFailRequestRequestId p),
+    ("errorReason" A..=) <$> Just (pFetchFailRequestErrorReason p)
+    ]
+instance Command PFetchFailRequest where
+  type CommandResponse PFetchFailRequest = ()
+  commandName _ = "Fetch.failRequest"
+  fromJSON = const . A.Success . const ()
+
+-- | Provides response to the request.
+
+-- | Parameters of the 'Fetch.fulfillRequest' command.
+data PFetchFulfillRequest = PFetchFulfillRequest
+  {
+    -- | An id the client received in requestPaused event.
+    pFetchFulfillRequestRequestId :: FetchRequestId,
+    -- | An HTTP response code.
+    pFetchFulfillRequestResponseCode :: Int,
+    -- | Response headers.
+    pFetchFulfillRequestResponseHeaders :: Maybe [FetchHeaderEntry],
+    -- | Alternative way of specifying response headers as a \0-separated
+    --   series of name: value pairs. Prefer the above method unless you
+    --   need to represent some non-UTF8 values that can't be transmitted
+    --   over the protocol as text. (Encoded as a base64 string when passed over JSON)
+    pFetchFulfillRequestBinaryResponseHeaders :: Maybe T.Text,
+    -- | A response body. If absent, original response body will be used if
+    --   the request is intercepted at the response stage and empty body
+    --   will be used if the request is intercepted at the request stage. (Encoded as a base64 string when passed over JSON)
+    pFetchFulfillRequestBody :: Maybe T.Text,
+    -- | A textual representation of responseCode.
+    --   If absent, a standard phrase matching responseCode is used.
+    pFetchFulfillRequestResponsePhrase :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+pFetchFulfillRequest
+  {-
+  -- | An id the client received in requestPaused event.
+  -}
+  :: FetchRequestId
+  {-
+  -- | An HTTP response code.
+  -}
+  -> Int
+  -> PFetchFulfillRequest
+pFetchFulfillRequest
+  arg_pFetchFulfillRequestRequestId
+  arg_pFetchFulfillRequestResponseCode
+  = PFetchFulfillRequest
+    arg_pFetchFulfillRequestRequestId
+    arg_pFetchFulfillRequestResponseCode
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PFetchFulfillRequest where
+  toJSON p = A.object $ catMaybes [
+    ("requestId" A..=) <$> Just (pFetchFulfillRequestRequestId p),
+    ("responseCode" A..=) <$> Just (pFetchFulfillRequestResponseCode p),
+    ("responseHeaders" A..=) <$> (pFetchFulfillRequestResponseHeaders p),
+    ("binaryResponseHeaders" A..=) <$> (pFetchFulfillRequestBinaryResponseHeaders p),
+    ("body" A..=) <$> (pFetchFulfillRequestBody p),
+    ("responsePhrase" A..=) <$> (pFetchFulfillRequestResponsePhrase p)
+    ]
+instance Command PFetchFulfillRequest where
+  type CommandResponse PFetchFulfillRequest = ()
+  commandName _ = "Fetch.fulfillRequest"
+  fromJSON = const . A.Success . const ()
+
+-- | Continues the request, optionally modifying some of its parameters.
+
+-- | Parameters of the 'Fetch.continueRequest' command.
+data PFetchContinueRequest = PFetchContinueRequest
+  {
+    -- | An id the client received in requestPaused event.
+    pFetchContinueRequestRequestId :: FetchRequestId,
+    -- | If set, the request url will be modified in a way that's not observable by page.
+    pFetchContinueRequestUrl :: Maybe T.Text,
+    -- | If set, the request method is overridden.
+    pFetchContinueRequestMethod :: Maybe T.Text,
+    -- | If set, overrides the post data in the request. (Encoded as a base64 string when passed over JSON)
+    pFetchContinueRequestPostData :: Maybe T.Text,
+    -- | If set, overrides the request headers. Note that the overrides do not
+    --   extend to subsequent redirect hops, if a redirect happens. Another override
+    --   may be applied to a different request produced by a redirect.
+    pFetchContinueRequestHeaders :: Maybe [FetchHeaderEntry],
+    -- | If set, overrides response interception behavior for this request.
+    pFetchContinueRequestInterceptResponse :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pFetchContinueRequest
+  {-
+  -- | An id the client received in requestPaused event.
+  -}
+  :: FetchRequestId
+  -> PFetchContinueRequest
+pFetchContinueRequest
+  arg_pFetchContinueRequestRequestId
+  = PFetchContinueRequest
+    arg_pFetchContinueRequestRequestId
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PFetchContinueRequest where
+  toJSON p = A.object $ catMaybes [
+    ("requestId" A..=) <$> Just (pFetchContinueRequestRequestId p),
+    ("url" A..=) <$> (pFetchContinueRequestUrl p),
+    ("method" A..=) <$> (pFetchContinueRequestMethod p),
+    ("postData" A..=) <$> (pFetchContinueRequestPostData p),
+    ("headers" A..=) <$> (pFetchContinueRequestHeaders p),
+    ("interceptResponse" A..=) <$> (pFetchContinueRequestInterceptResponse p)
+    ]
+instance Command PFetchContinueRequest where
+  type CommandResponse PFetchContinueRequest = ()
+  commandName _ = "Fetch.continueRequest"
+  fromJSON = const . A.Success . const ()
+
+-- | Continues a request supplying authChallengeResponse following authRequired event.
+
+-- | Parameters of the 'Fetch.continueWithAuth' command.
+data PFetchContinueWithAuth = PFetchContinueWithAuth
+  {
+    -- | An id the client received in authRequired event.
+    pFetchContinueWithAuthRequestId :: FetchRequestId,
+    -- | Response to  with an authChallenge.
+    pFetchContinueWithAuthAuthChallengeResponse :: FetchAuthChallengeResponse
+  }
+  deriving (Eq, Show)
+pFetchContinueWithAuth
+  {-
+  -- | An id the client received in authRequired event.
+  -}
+  :: FetchRequestId
+  {-
+  -- | Response to  with an authChallenge.
+  -}
+  -> FetchAuthChallengeResponse
+  -> PFetchContinueWithAuth
+pFetchContinueWithAuth
+  arg_pFetchContinueWithAuthRequestId
+  arg_pFetchContinueWithAuthAuthChallengeResponse
+  = PFetchContinueWithAuth
+    arg_pFetchContinueWithAuthRequestId
+    arg_pFetchContinueWithAuthAuthChallengeResponse
+instance ToJSON PFetchContinueWithAuth where
+  toJSON p = A.object $ catMaybes [
+    ("requestId" A..=) <$> Just (pFetchContinueWithAuthRequestId p),
+    ("authChallengeResponse" A..=) <$> Just (pFetchContinueWithAuthAuthChallengeResponse p)
+    ]
+instance Command PFetchContinueWithAuth where
+  type CommandResponse PFetchContinueWithAuth = ()
+  commandName _ = "Fetch.continueWithAuth"
+  fromJSON = const . A.Success . const ()
+
+-- | Continues loading of the paused response, optionally modifying the
+--   response headers. If either responseCode or headers are modified, all of them
+--   must be present.
+
+-- | Parameters of the 'Fetch.continueResponse' command.
+data PFetchContinueResponse = PFetchContinueResponse
+  {
+    -- | An id the client received in requestPaused event.
+    pFetchContinueResponseRequestId :: FetchRequestId,
+    -- | An HTTP response code. If absent, original response code will be used.
+    pFetchContinueResponseResponseCode :: Maybe Int,
+    -- | A textual representation of responseCode.
+    --   If absent, a standard phrase matching responseCode is used.
+    pFetchContinueResponseResponsePhrase :: Maybe T.Text,
+    -- | Response headers. If absent, original response headers will be used.
+    pFetchContinueResponseResponseHeaders :: Maybe [FetchHeaderEntry],
+    -- | Alternative way of specifying response headers as a \0-separated
+    --   series of name: value pairs. Prefer the above method unless you
+    --   need to represent some non-UTF8 values that can't be transmitted
+    --   over the protocol as text. (Encoded as a base64 string when passed over JSON)
+    pFetchContinueResponseBinaryResponseHeaders :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+pFetchContinueResponse
+  {-
+  -- | An id the client received in requestPaused event.
+  -}
+  :: FetchRequestId
+  -> PFetchContinueResponse
+pFetchContinueResponse
+  arg_pFetchContinueResponseRequestId
+  = PFetchContinueResponse
+    arg_pFetchContinueResponseRequestId
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PFetchContinueResponse where
+  toJSON p = A.object $ catMaybes [
+    ("requestId" A..=) <$> Just (pFetchContinueResponseRequestId p),
+    ("responseCode" A..=) <$> (pFetchContinueResponseResponseCode p),
+    ("responsePhrase" A..=) <$> (pFetchContinueResponseResponsePhrase p),
+    ("responseHeaders" A..=) <$> (pFetchContinueResponseResponseHeaders p),
+    ("binaryResponseHeaders" A..=) <$> (pFetchContinueResponseBinaryResponseHeaders p)
+    ]
+instance Command PFetchContinueResponse where
+  type CommandResponse PFetchContinueResponse = ()
+  commandName _ = "Fetch.continueResponse"
+  fromJSON = const . A.Success . const ()
+
+-- | Causes the body of the response to be received from the server and
+--   returned as a single string. May only be issued for a request that
+--   is paused in the Response stage and is mutually exclusive with
+--   takeResponseBodyForInterceptionAsStream. Calling other methods that
+--   affect the request or disabling fetch domain before body is received
+--   results in an undefined behavior.
+
+-- | Parameters of the 'Fetch.getResponseBody' command.
+data PFetchGetResponseBody = PFetchGetResponseBody
+  {
+    -- | Identifier for the intercepted request to get body for.
+    pFetchGetResponseBodyRequestId :: FetchRequestId
+  }
+  deriving (Eq, Show)
+pFetchGetResponseBody
+  {-
+  -- | Identifier for the intercepted request to get body for.
+  -}
+  :: FetchRequestId
+  -> PFetchGetResponseBody
+pFetchGetResponseBody
+  arg_pFetchGetResponseBodyRequestId
+  = PFetchGetResponseBody
+    arg_pFetchGetResponseBodyRequestId
+instance ToJSON PFetchGetResponseBody where
+  toJSON p = A.object $ catMaybes [
+    ("requestId" A..=) <$> Just (pFetchGetResponseBodyRequestId p)
+    ]
+data FetchGetResponseBody = FetchGetResponseBody
+  {
+    -- | Response body.
+    fetchGetResponseBodyBody :: T.Text,
+    -- | True, if content was sent as base64.
+    fetchGetResponseBodyBase64Encoded :: Bool
+  }
+  deriving (Eq, Show)
+instance FromJSON FetchGetResponseBody where
+  parseJSON = A.withObject "FetchGetResponseBody" $ \o -> FetchGetResponseBody
+    <$> o A..: "body"
+    <*> o A..: "base64Encoded"
+instance Command PFetchGetResponseBody where
+  type CommandResponse PFetchGetResponseBody = FetchGetResponseBody
+  commandName _ = "Fetch.getResponseBody"
+
+-- | Returns a handle to the stream representing the response body.
+--   The request must be paused in the HeadersReceived stage.
+--   Note that after this command the request can't be continued
+--   as is -- client either needs to cancel it or to provide the
+--   response body.
+--   The stream only supports sequential read, IO.read will fail if the position
+--   is specified.
+--   This method is mutually exclusive with getResponseBody.
+--   Calling other methods that affect the request or disabling fetch
+--   domain before body is received results in an undefined behavior.
+
+-- | Parameters of the 'Fetch.takeResponseBodyAsStream' command.
+data PFetchTakeResponseBodyAsStream = PFetchTakeResponseBodyAsStream
+  {
+    pFetchTakeResponseBodyAsStreamRequestId :: FetchRequestId
+  }
+  deriving (Eq, Show)
+pFetchTakeResponseBodyAsStream
+  :: FetchRequestId
+  -> PFetchTakeResponseBodyAsStream
+pFetchTakeResponseBodyAsStream
+  arg_pFetchTakeResponseBodyAsStreamRequestId
+  = PFetchTakeResponseBodyAsStream
+    arg_pFetchTakeResponseBodyAsStreamRequestId
+instance ToJSON PFetchTakeResponseBodyAsStream where
+  toJSON p = A.object $ catMaybes [
+    ("requestId" A..=) <$> Just (pFetchTakeResponseBodyAsStreamRequestId p)
+    ]
+data FetchTakeResponseBodyAsStream = FetchTakeResponseBodyAsStream
+  {
+    fetchTakeResponseBodyAsStreamStream :: IO.IOStreamHandle
+  }
+  deriving (Eq, Show)
+instance FromJSON FetchTakeResponseBodyAsStream where
+  parseJSON = A.withObject "FetchTakeResponseBodyAsStream" $ \o -> FetchTakeResponseBodyAsStream
+    <$> o A..: "stream"
+instance Command PFetchTakeResponseBodyAsStream where
+  type CommandResponse PFetchTakeResponseBodyAsStream = FetchTakeResponseBodyAsStream
+  commandName _ = "Fetch.takeResponseBodyAsStream"
+
diff --git a/src/CDP/Domains/HeadlessExperimental.hs b/src/CDP/Domains/HeadlessExperimental.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains/HeadlessExperimental.hs
@@ -0,0 +1,169 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+
+
+{- |
+= HeadlessExperimental
+
+This domain provides experimental commands only supported in headless mode.
+-}
+
+
+module CDP.Domains.HeadlessExperimental (module CDP.Domains.HeadlessExperimental) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+
+
+
+-- | Type 'HeadlessExperimental.ScreenshotParams'.
+--   Encoding options for a screenshot.
+data HeadlessExperimentalScreenshotParamsFormat = HeadlessExperimentalScreenshotParamsFormatJpeg | HeadlessExperimentalScreenshotParamsFormatPng
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON HeadlessExperimentalScreenshotParamsFormat where
+  parseJSON = A.withText "HeadlessExperimentalScreenshotParamsFormat" $ \v -> case v of
+    "jpeg" -> pure HeadlessExperimentalScreenshotParamsFormatJpeg
+    "png" -> pure HeadlessExperimentalScreenshotParamsFormatPng
+    "_" -> fail "failed to parse HeadlessExperimentalScreenshotParamsFormat"
+instance ToJSON HeadlessExperimentalScreenshotParamsFormat where
+  toJSON v = A.String $ case v of
+    HeadlessExperimentalScreenshotParamsFormatJpeg -> "jpeg"
+    HeadlessExperimentalScreenshotParamsFormatPng -> "png"
+data HeadlessExperimentalScreenshotParams = HeadlessExperimentalScreenshotParams
+  {
+    -- | Image compression format (defaults to png).
+    headlessExperimentalScreenshotParamsFormat :: Maybe HeadlessExperimentalScreenshotParamsFormat,
+    -- | Compression quality from range [0..100] (jpeg only).
+    headlessExperimentalScreenshotParamsQuality :: Maybe Int
+  }
+  deriving (Eq, Show)
+instance FromJSON HeadlessExperimentalScreenshotParams where
+  parseJSON = A.withObject "HeadlessExperimentalScreenshotParams" $ \o -> HeadlessExperimentalScreenshotParams
+    <$> o A..:? "format"
+    <*> o A..:? "quality"
+instance ToJSON HeadlessExperimentalScreenshotParams where
+  toJSON p = A.object $ catMaybes [
+    ("format" A..=) <$> (headlessExperimentalScreenshotParamsFormat p),
+    ("quality" A..=) <$> (headlessExperimentalScreenshotParamsQuality p)
+    ]
+
+-- | Sends a BeginFrame to the target and returns when the frame was completed. Optionally captures a
+--   screenshot from the resulting frame. Requires that the target was created with enabled
+--   BeginFrameControl. Designed for use with --run-all-compositor-stages-before-draw, see also
+--   https://goo.gle/chrome-headless-rendering for more background.
+
+-- | Parameters of the 'HeadlessExperimental.beginFrame' command.
+data PHeadlessExperimentalBeginFrame = PHeadlessExperimentalBeginFrame
+  {
+    -- | Timestamp of this BeginFrame in Renderer TimeTicks (milliseconds of uptime). If not set,
+    --   the current time will be used.
+    pHeadlessExperimentalBeginFrameFrameTimeTicks :: Maybe Double,
+    -- | The interval between BeginFrames that is reported to the compositor, in milliseconds.
+    --   Defaults to a 60 frames/second interval, i.e. about 16.666 milliseconds.
+    pHeadlessExperimentalBeginFrameInterval :: Maybe Double,
+    -- | Whether updates should not be committed and drawn onto the display. False by default. If
+    --   true, only side effects of the BeginFrame will be run, such as layout and animations, but
+    --   any visual updates may not be visible on the display or in screenshots.
+    pHeadlessExperimentalBeginFrameNoDisplayUpdates :: Maybe Bool,
+    -- | If set, a screenshot of the frame will be captured and returned in the response. Otherwise,
+    --   no screenshot will be captured. Note that capturing a screenshot can fail, for example,
+    --   during renderer initialization. In such a case, no screenshot data will be returned.
+    pHeadlessExperimentalBeginFrameScreenshot :: Maybe HeadlessExperimentalScreenshotParams
+  }
+  deriving (Eq, Show)
+pHeadlessExperimentalBeginFrame
+  :: PHeadlessExperimentalBeginFrame
+pHeadlessExperimentalBeginFrame
+  = PHeadlessExperimentalBeginFrame
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PHeadlessExperimentalBeginFrame where
+  toJSON p = A.object $ catMaybes [
+    ("frameTimeTicks" A..=) <$> (pHeadlessExperimentalBeginFrameFrameTimeTicks p),
+    ("interval" A..=) <$> (pHeadlessExperimentalBeginFrameInterval p),
+    ("noDisplayUpdates" A..=) <$> (pHeadlessExperimentalBeginFrameNoDisplayUpdates p),
+    ("screenshot" A..=) <$> (pHeadlessExperimentalBeginFrameScreenshot p)
+    ]
+data HeadlessExperimentalBeginFrame = HeadlessExperimentalBeginFrame
+  {
+    -- | Whether the BeginFrame resulted in damage and, thus, a new frame was committed to the
+    --   display. Reported for diagnostic uses, may be removed in the future.
+    headlessExperimentalBeginFrameHasDamage :: Bool,
+    -- | Base64-encoded image data of the screenshot, if one was requested and successfully taken. (Encoded as a base64 string when passed over JSON)
+    headlessExperimentalBeginFrameScreenshotData :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON HeadlessExperimentalBeginFrame where
+  parseJSON = A.withObject "HeadlessExperimentalBeginFrame" $ \o -> HeadlessExperimentalBeginFrame
+    <$> o A..: "hasDamage"
+    <*> o A..:? "screenshotData"
+instance Command PHeadlessExperimentalBeginFrame where
+  type CommandResponse PHeadlessExperimentalBeginFrame = HeadlessExperimentalBeginFrame
+  commandName _ = "HeadlessExperimental.beginFrame"
+
+-- | Disables headless events for the target.
+
+-- | Parameters of the 'HeadlessExperimental.disable' command.
+data PHeadlessExperimentalDisable = PHeadlessExperimentalDisable
+  deriving (Eq, Show)
+pHeadlessExperimentalDisable
+  :: PHeadlessExperimentalDisable
+pHeadlessExperimentalDisable
+  = PHeadlessExperimentalDisable
+instance ToJSON PHeadlessExperimentalDisable where
+  toJSON _ = A.Null
+instance Command PHeadlessExperimentalDisable where
+  type CommandResponse PHeadlessExperimentalDisable = ()
+  commandName _ = "HeadlessExperimental.disable"
+  fromJSON = const . A.Success . const ()
+
+-- | Enables headless events for the target.
+
+-- | Parameters of the 'HeadlessExperimental.enable' command.
+data PHeadlessExperimentalEnable = PHeadlessExperimentalEnable
+  deriving (Eq, Show)
+pHeadlessExperimentalEnable
+  :: PHeadlessExperimentalEnable
+pHeadlessExperimentalEnable
+  = PHeadlessExperimentalEnable
+instance ToJSON PHeadlessExperimentalEnable where
+  toJSON _ = A.Null
+instance Command PHeadlessExperimentalEnable where
+  type CommandResponse PHeadlessExperimentalEnable = ()
+  commandName _ = "HeadlessExperimental.enable"
+  fromJSON = const . A.Success . const ()
+
diff --git a/src/CDP/Domains/HeapProfiler.hs b/src/CDP/Domains/HeapProfiler.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains/HeapProfiler.hs
@@ -0,0 +1,505 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+
+
+{- |
+= HeapProfiler
+
+-}
+
+
+module CDP.Domains.HeapProfiler (module CDP.Domains.HeapProfiler) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+
+import CDP.Domains.Runtime as Runtime
+
+
+-- | Type 'HeapProfiler.HeapSnapshotObjectId'.
+--   Heap snapshot object id.
+type HeapProfilerHeapSnapshotObjectId = T.Text
+
+-- | Type 'HeapProfiler.SamplingHeapProfileNode'.
+--   Sampling Heap Profile node. Holds callsite information, allocation statistics and child nodes.
+data HeapProfilerSamplingHeapProfileNode = HeapProfilerSamplingHeapProfileNode
+  {
+    -- | Function location.
+    heapProfilerSamplingHeapProfileNodeCallFrame :: Runtime.RuntimeCallFrame,
+    -- | Allocations size in bytes for the node excluding children.
+    heapProfilerSamplingHeapProfileNodeSelfSize :: Double,
+    -- | Node id. Ids are unique across all profiles collected between startSampling and stopSampling.
+    heapProfilerSamplingHeapProfileNodeId :: Int,
+    -- | Child nodes.
+    heapProfilerSamplingHeapProfileNodeChildren :: [HeapProfilerSamplingHeapProfileNode]
+  }
+  deriving (Eq, Show)
+instance FromJSON HeapProfilerSamplingHeapProfileNode where
+  parseJSON = A.withObject "HeapProfilerSamplingHeapProfileNode" $ \o -> HeapProfilerSamplingHeapProfileNode
+    <$> o A..: "callFrame"
+    <*> o A..: "selfSize"
+    <*> o A..: "id"
+    <*> o A..: "children"
+instance ToJSON HeapProfilerSamplingHeapProfileNode where
+  toJSON p = A.object $ catMaybes [
+    ("callFrame" A..=) <$> Just (heapProfilerSamplingHeapProfileNodeCallFrame p),
+    ("selfSize" A..=) <$> Just (heapProfilerSamplingHeapProfileNodeSelfSize p),
+    ("id" A..=) <$> Just (heapProfilerSamplingHeapProfileNodeId p),
+    ("children" A..=) <$> Just (heapProfilerSamplingHeapProfileNodeChildren p)
+    ]
+
+-- | Type 'HeapProfiler.SamplingHeapProfileSample'.
+--   A single sample from a sampling profile.
+data HeapProfilerSamplingHeapProfileSample = HeapProfilerSamplingHeapProfileSample
+  {
+    -- | Allocation size in bytes attributed to the sample.
+    heapProfilerSamplingHeapProfileSampleSize :: Double,
+    -- | Id of the corresponding profile tree node.
+    heapProfilerSamplingHeapProfileSampleNodeId :: Int,
+    -- | Time-ordered sample ordinal number. It is unique across all profiles retrieved
+    --   between startSampling and stopSampling.
+    heapProfilerSamplingHeapProfileSampleOrdinal :: Double
+  }
+  deriving (Eq, Show)
+instance FromJSON HeapProfilerSamplingHeapProfileSample where
+  parseJSON = A.withObject "HeapProfilerSamplingHeapProfileSample" $ \o -> HeapProfilerSamplingHeapProfileSample
+    <$> o A..: "size"
+    <*> o A..: "nodeId"
+    <*> o A..: "ordinal"
+instance ToJSON HeapProfilerSamplingHeapProfileSample where
+  toJSON p = A.object $ catMaybes [
+    ("size" A..=) <$> Just (heapProfilerSamplingHeapProfileSampleSize p),
+    ("nodeId" A..=) <$> Just (heapProfilerSamplingHeapProfileSampleNodeId p),
+    ("ordinal" A..=) <$> Just (heapProfilerSamplingHeapProfileSampleOrdinal p)
+    ]
+
+-- | Type 'HeapProfiler.SamplingHeapProfile'.
+--   Sampling profile.
+data HeapProfilerSamplingHeapProfile = HeapProfilerSamplingHeapProfile
+  {
+    heapProfilerSamplingHeapProfileHead :: HeapProfilerSamplingHeapProfileNode,
+    heapProfilerSamplingHeapProfileSamples :: [HeapProfilerSamplingHeapProfileSample]
+  }
+  deriving (Eq, Show)
+instance FromJSON HeapProfilerSamplingHeapProfile where
+  parseJSON = A.withObject "HeapProfilerSamplingHeapProfile" $ \o -> HeapProfilerSamplingHeapProfile
+    <$> o A..: "head"
+    <*> o A..: "samples"
+instance ToJSON HeapProfilerSamplingHeapProfile where
+  toJSON p = A.object $ catMaybes [
+    ("head" A..=) <$> Just (heapProfilerSamplingHeapProfileHead p),
+    ("samples" A..=) <$> Just (heapProfilerSamplingHeapProfileSamples p)
+    ]
+
+-- | Type of the 'HeapProfiler.addHeapSnapshotChunk' event.
+data HeapProfilerAddHeapSnapshotChunk = HeapProfilerAddHeapSnapshotChunk
+  {
+    heapProfilerAddHeapSnapshotChunkChunk :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON HeapProfilerAddHeapSnapshotChunk where
+  parseJSON = A.withObject "HeapProfilerAddHeapSnapshotChunk" $ \o -> HeapProfilerAddHeapSnapshotChunk
+    <$> o A..: "chunk"
+instance Event HeapProfilerAddHeapSnapshotChunk where
+  eventName _ = "HeapProfiler.addHeapSnapshotChunk"
+
+-- | Type of the 'HeapProfiler.heapStatsUpdate' event.
+data HeapProfilerHeapStatsUpdate = HeapProfilerHeapStatsUpdate
+  {
+    -- | An array of triplets. Each triplet describes a fragment. The first integer is the fragment
+    --   index, the second integer is a total count of objects for the fragment, the third integer is
+    --   a total size of the objects for the fragment.
+    heapProfilerHeapStatsUpdateStatsUpdate :: [Int]
+  }
+  deriving (Eq, Show)
+instance FromJSON HeapProfilerHeapStatsUpdate where
+  parseJSON = A.withObject "HeapProfilerHeapStatsUpdate" $ \o -> HeapProfilerHeapStatsUpdate
+    <$> o A..: "statsUpdate"
+instance Event HeapProfilerHeapStatsUpdate where
+  eventName _ = "HeapProfiler.heapStatsUpdate"
+
+-- | Type of the 'HeapProfiler.lastSeenObjectId' event.
+data HeapProfilerLastSeenObjectId = HeapProfilerLastSeenObjectId
+  {
+    heapProfilerLastSeenObjectIdLastSeenObjectId :: Int,
+    heapProfilerLastSeenObjectIdTimestamp :: Double
+  }
+  deriving (Eq, Show)
+instance FromJSON HeapProfilerLastSeenObjectId where
+  parseJSON = A.withObject "HeapProfilerLastSeenObjectId" $ \o -> HeapProfilerLastSeenObjectId
+    <$> o A..: "lastSeenObjectId"
+    <*> o A..: "timestamp"
+instance Event HeapProfilerLastSeenObjectId where
+  eventName _ = "HeapProfiler.lastSeenObjectId"
+
+-- | Type of the 'HeapProfiler.reportHeapSnapshotProgress' event.
+data HeapProfilerReportHeapSnapshotProgress = HeapProfilerReportHeapSnapshotProgress
+  {
+    heapProfilerReportHeapSnapshotProgressDone :: Int,
+    heapProfilerReportHeapSnapshotProgressTotal :: Int,
+    heapProfilerReportHeapSnapshotProgressFinished :: Maybe Bool
+  }
+  deriving (Eq, Show)
+instance FromJSON HeapProfilerReportHeapSnapshotProgress where
+  parseJSON = A.withObject "HeapProfilerReportHeapSnapshotProgress" $ \o -> HeapProfilerReportHeapSnapshotProgress
+    <$> o A..: "done"
+    <*> o A..: "total"
+    <*> o A..:? "finished"
+instance Event HeapProfilerReportHeapSnapshotProgress where
+  eventName _ = "HeapProfiler.reportHeapSnapshotProgress"
+
+-- | Type of the 'HeapProfiler.resetProfiles' event.
+data HeapProfilerResetProfiles = HeapProfilerResetProfiles
+  deriving (Eq, Show, Read)
+instance FromJSON HeapProfilerResetProfiles where
+  parseJSON _ = pure HeapProfilerResetProfiles
+instance Event HeapProfilerResetProfiles where
+  eventName _ = "HeapProfiler.resetProfiles"
+
+-- | Enables console to refer to the node with given id via $x (see Command Line API for more details
+--   $x functions).
+
+-- | Parameters of the 'HeapProfiler.addInspectedHeapObject' command.
+data PHeapProfilerAddInspectedHeapObject = PHeapProfilerAddInspectedHeapObject
+  {
+    -- | Heap snapshot object id to be accessible by means of $x command line API.
+    pHeapProfilerAddInspectedHeapObjectHeapObjectId :: HeapProfilerHeapSnapshotObjectId
+  }
+  deriving (Eq, Show)
+pHeapProfilerAddInspectedHeapObject
+  {-
+  -- | Heap snapshot object id to be accessible by means of $x command line API.
+  -}
+  :: HeapProfilerHeapSnapshotObjectId
+  -> PHeapProfilerAddInspectedHeapObject
+pHeapProfilerAddInspectedHeapObject
+  arg_pHeapProfilerAddInspectedHeapObjectHeapObjectId
+  = PHeapProfilerAddInspectedHeapObject
+    arg_pHeapProfilerAddInspectedHeapObjectHeapObjectId
+instance ToJSON PHeapProfilerAddInspectedHeapObject where
+  toJSON p = A.object $ catMaybes [
+    ("heapObjectId" A..=) <$> Just (pHeapProfilerAddInspectedHeapObjectHeapObjectId p)
+    ]
+instance Command PHeapProfilerAddInspectedHeapObject where
+  type CommandResponse PHeapProfilerAddInspectedHeapObject = ()
+  commandName _ = "HeapProfiler.addInspectedHeapObject"
+  fromJSON = const . A.Success . const ()
+
+
+-- | Parameters of the 'HeapProfiler.collectGarbage' command.
+data PHeapProfilerCollectGarbage = PHeapProfilerCollectGarbage
+  deriving (Eq, Show)
+pHeapProfilerCollectGarbage
+  :: PHeapProfilerCollectGarbage
+pHeapProfilerCollectGarbage
+  = PHeapProfilerCollectGarbage
+instance ToJSON PHeapProfilerCollectGarbage where
+  toJSON _ = A.Null
+instance Command PHeapProfilerCollectGarbage where
+  type CommandResponse PHeapProfilerCollectGarbage = ()
+  commandName _ = "HeapProfiler.collectGarbage"
+  fromJSON = const . A.Success . const ()
+
+
+-- | Parameters of the 'HeapProfiler.disable' command.
+data PHeapProfilerDisable = PHeapProfilerDisable
+  deriving (Eq, Show)
+pHeapProfilerDisable
+  :: PHeapProfilerDisable
+pHeapProfilerDisable
+  = PHeapProfilerDisable
+instance ToJSON PHeapProfilerDisable where
+  toJSON _ = A.Null
+instance Command PHeapProfilerDisable where
+  type CommandResponse PHeapProfilerDisable = ()
+  commandName _ = "HeapProfiler.disable"
+  fromJSON = const . A.Success . const ()
+
+
+-- | Parameters of the 'HeapProfiler.enable' command.
+data PHeapProfilerEnable = PHeapProfilerEnable
+  deriving (Eq, Show)
+pHeapProfilerEnable
+  :: PHeapProfilerEnable
+pHeapProfilerEnable
+  = PHeapProfilerEnable
+instance ToJSON PHeapProfilerEnable where
+  toJSON _ = A.Null
+instance Command PHeapProfilerEnable where
+  type CommandResponse PHeapProfilerEnable = ()
+  commandName _ = "HeapProfiler.enable"
+  fromJSON = const . A.Success . const ()
+
+
+-- | Parameters of the 'HeapProfiler.getHeapObjectId' command.
+data PHeapProfilerGetHeapObjectId = PHeapProfilerGetHeapObjectId
+  {
+    -- | Identifier of the object to get heap object id for.
+    pHeapProfilerGetHeapObjectIdObjectId :: Runtime.RuntimeRemoteObjectId
+  }
+  deriving (Eq, Show)
+pHeapProfilerGetHeapObjectId
+  {-
+  -- | Identifier of the object to get heap object id for.
+  -}
+  :: Runtime.RuntimeRemoteObjectId
+  -> PHeapProfilerGetHeapObjectId
+pHeapProfilerGetHeapObjectId
+  arg_pHeapProfilerGetHeapObjectIdObjectId
+  = PHeapProfilerGetHeapObjectId
+    arg_pHeapProfilerGetHeapObjectIdObjectId
+instance ToJSON PHeapProfilerGetHeapObjectId where
+  toJSON p = A.object $ catMaybes [
+    ("objectId" A..=) <$> Just (pHeapProfilerGetHeapObjectIdObjectId p)
+    ]
+data HeapProfilerGetHeapObjectId = HeapProfilerGetHeapObjectId
+  {
+    -- | Id of the heap snapshot object corresponding to the passed remote object id.
+    heapProfilerGetHeapObjectIdHeapSnapshotObjectId :: HeapProfilerHeapSnapshotObjectId
+  }
+  deriving (Eq, Show)
+instance FromJSON HeapProfilerGetHeapObjectId where
+  parseJSON = A.withObject "HeapProfilerGetHeapObjectId" $ \o -> HeapProfilerGetHeapObjectId
+    <$> o A..: "heapSnapshotObjectId"
+instance Command PHeapProfilerGetHeapObjectId where
+  type CommandResponse PHeapProfilerGetHeapObjectId = HeapProfilerGetHeapObjectId
+  commandName _ = "HeapProfiler.getHeapObjectId"
+
+
+-- | Parameters of the 'HeapProfiler.getObjectByHeapObjectId' command.
+data PHeapProfilerGetObjectByHeapObjectId = PHeapProfilerGetObjectByHeapObjectId
+  {
+    pHeapProfilerGetObjectByHeapObjectIdObjectId :: HeapProfilerHeapSnapshotObjectId,
+    -- | Symbolic group name that can be used to release multiple objects.
+    pHeapProfilerGetObjectByHeapObjectIdObjectGroup :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+pHeapProfilerGetObjectByHeapObjectId
+  :: HeapProfilerHeapSnapshotObjectId
+  -> PHeapProfilerGetObjectByHeapObjectId
+pHeapProfilerGetObjectByHeapObjectId
+  arg_pHeapProfilerGetObjectByHeapObjectIdObjectId
+  = PHeapProfilerGetObjectByHeapObjectId
+    arg_pHeapProfilerGetObjectByHeapObjectIdObjectId
+    Nothing
+instance ToJSON PHeapProfilerGetObjectByHeapObjectId where
+  toJSON p = A.object $ catMaybes [
+    ("objectId" A..=) <$> Just (pHeapProfilerGetObjectByHeapObjectIdObjectId p),
+    ("objectGroup" A..=) <$> (pHeapProfilerGetObjectByHeapObjectIdObjectGroup p)
+    ]
+data HeapProfilerGetObjectByHeapObjectId = HeapProfilerGetObjectByHeapObjectId
+  {
+    -- | Evaluation result.
+    heapProfilerGetObjectByHeapObjectIdResult :: Runtime.RuntimeRemoteObject
+  }
+  deriving (Eq, Show)
+instance FromJSON HeapProfilerGetObjectByHeapObjectId where
+  parseJSON = A.withObject "HeapProfilerGetObjectByHeapObjectId" $ \o -> HeapProfilerGetObjectByHeapObjectId
+    <$> o A..: "result"
+instance Command PHeapProfilerGetObjectByHeapObjectId where
+  type CommandResponse PHeapProfilerGetObjectByHeapObjectId = HeapProfilerGetObjectByHeapObjectId
+  commandName _ = "HeapProfiler.getObjectByHeapObjectId"
+
+
+-- | Parameters of the 'HeapProfiler.getSamplingProfile' command.
+data PHeapProfilerGetSamplingProfile = PHeapProfilerGetSamplingProfile
+  deriving (Eq, Show)
+pHeapProfilerGetSamplingProfile
+  :: PHeapProfilerGetSamplingProfile
+pHeapProfilerGetSamplingProfile
+  = PHeapProfilerGetSamplingProfile
+instance ToJSON PHeapProfilerGetSamplingProfile where
+  toJSON _ = A.Null
+data HeapProfilerGetSamplingProfile = HeapProfilerGetSamplingProfile
+  {
+    -- | Return the sampling profile being collected.
+    heapProfilerGetSamplingProfileProfile :: HeapProfilerSamplingHeapProfile
+  }
+  deriving (Eq, Show)
+instance FromJSON HeapProfilerGetSamplingProfile where
+  parseJSON = A.withObject "HeapProfilerGetSamplingProfile" $ \o -> HeapProfilerGetSamplingProfile
+    <$> o A..: "profile"
+instance Command PHeapProfilerGetSamplingProfile where
+  type CommandResponse PHeapProfilerGetSamplingProfile = HeapProfilerGetSamplingProfile
+  commandName _ = "HeapProfiler.getSamplingProfile"
+
+
+-- | Parameters of the 'HeapProfiler.startSampling' command.
+data PHeapProfilerStartSampling = PHeapProfilerStartSampling
+  {
+    -- | Average sample interval in bytes. Poisson distribution is used for the intervals. The
+    --   default value is 32768 bytes.
+    pHeapProfilerStartSamplingSamplingInterval :: Maybe Double,
+    -- | By default, the sampling heap profiler reports only objects which are
+    --   still alive when the profile is returned via getSamplingProfile or
+    --   stopSampling, which is useful for determining what functions contribute
+    --   the most to steady-state memory usage. This flag instructs the sampling
+    --   heap profiler to also include information about objects discarded by
+    --   major GC, which will show which functions cause large temporary memory
+    --   usage or long GC pauses.
+    pHeapProfilerStartSamplingIncludeObjectsCollectedByMajorGC :: Maybe Bool,
+    -- | By default, the sampling heap profiler reports only objects which are
+    --   still alive when the profile is returned via getSamplingProfile or
+    --   stopSampling, which is useful for determining what functions contribute
+    --   the most to steady-state memory usage. This flag instructs the sampling
+    --   heap profiler to also include information about objects discarded by
+    --   minor GC, which is useful when tuning a latency-sensitive application
+    --   for minimal GC activity.
+    pHeapProfilerStartSamplingIncludeObjectsCollectedByMinorGC :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pHeapProfilerStartSampling
+  :: PHeapProfilerStartSampling
+pHeapProfilerStartSampling
+  = PHeapProfilerStartSampling
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PHeapProfilerStartSampling where
+  toJSON p = A.object $ catMaybes [
+    ("samplingInterval" A..=) <$> (pHeapProfilerStartSamplingSamplingInterval p),
+    ("includeObjectsCollectedByMajorGC" A..=) <$> (pHeapProfilerStartSamplingIncludeObjectsCollectedByMajorGC p),
+    ("includeObjectsCollectedByMinorGC" A..=) <$> (pHeapProfilerStartSamplingIncludeObjectsCollectedByMinorGC p)
+    ]
+instance Command PHeapProfilerStartSampling where
+  type CommandResponse PHeapProfilerStartSampling = ()
+  commandName _ = "HeapProfiler.startSampling"
+  fromJSON = const . A.Success . const ()
+
+
+-- | Parameters of the 'HeapProfiler.startTrackingHeapObjects' command.
+data PHeapProfilerStartTrackingHeapObjects = PHeapProfilerStartTrackingHeapObjects
+  {
+    pHeapProfilerStartTrackingHeapObjectsTrackAllocations :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pHeapProfilerStartTrackingHeapObjects
+  :: PHeapProfilerStartTrackingHeapObjects
+pHeapProfilerStartTrackingHeapObjects
+  = PHeapProfilerStartTrackingHeapObjects
+    Nothing
+instance ToJSON PHeapProfilerStartTrackingHeapObjects where
+  toJSON p = A.object $ catMaybes [
+    ("trackAllocations" A..=) <$> (pHeapProfilerStartTrackingHeapObjectsTrackAllocations p)
+    ]
+instance Command PHeapProfilerStartTrackingHeapObjects where
+  type CommandResponse PHeapProfilerStartTrackingHeapObjects = ()
+  commandName _ = "HeapProfiler.startTrackingHeapObjects"
+  fromJSON = const . A.Success . const ()
+
+
+-- | Parameters of the 'HeapProfiler.stopSampling' command.
+data PHeapProfilerStopSampling = PHeapProfilerStopSampling
+  deriving (Eq, Show)
+pHeapProfilerStopSampling
+  :: PHeapProfilerStopSampling
+pHeapProfilerStopSampling
+  = PHeapProfilerStopSampling
+instance ToJSON PHeapProfilerStopSampling where
+  toJSON _ = A.Null
+data HeapProfilerStopSampling = HeapProfilerStopSampling
+  {
+    -- | Recorded sampling heap profile.
+    heapProfilerStopSamplingProfile :: HeapProfilerSamplingHeapProfile
+  }
+  deriving (Eq, Show)
+instance FromJSON HeapProfilerStopSampling where
+  parseJSON = A.withObject "HeapProfilerStopSampling" $ \o -> HeapProfilerStopSampling
+    <$> o A..: "profile"
+instance Command PHeapProfilerStopSampling where
+  type CommandResponse PHeapProfilerStopSampling = HeapProfilerStopSampling
+  commandName _ = "HeapProfiler.stopSampling"
+
+
+-- | Parameters of the 'HeapProfiler.stopTrackingHeapObjects' command.
+data PHeapProfilerStopTrackingHeapObjects = PHeapProfilerStopTrackingHeapObjects
+  {
+    -- | If true 'reportHeapSnapshotProgress' events will be generated while snapshot is being taken
+    --   when the tracking is stopped.
+    pHeapProfilerStopTrackingHeapObjectsReportProgress :: Maybe Bool,
+    -- | If true, numerical values are included in the snapshot
+    pHeapProfilerStopTrackingHeapObjectsCaptureNumericValue :: Maybe Bool,
+    -- | If true, exposes internals of the snapshot.
+    pHeapProfilerStopTrackingHeapObjectsExposeInternals :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pHeapProfilerStopTrackingHeapObjects
+  :: PHeapProfilerStopTrackingHeapObjects
+pHeapProfilerStopTrackingHeapObjects
+  = PHeapProfilerStopTrackingHeapObjects
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PHeapProfilerStopTrackingHeapObjects where
+  toJSON p = A.object $ catMaybes [
+    ("reportProgress" A..=) <$> (pHeapProfilerStopTrackingHeapObjectsReportProgress p),
+    ("captureNumericValue" A..=) <$> (pHeapProfilerStopTrackingHeapObjectsCaptureNumericValue p),
+    ("exposeInternals" A..=) <$> (pHeapProfilerStopTrackingHeapObjectsExposeInternals p)
+    ]
+instance Command PHeapProfilerStopTrackingHeapObjects where
+  type CommandResponse PHeapProfilerStopTrackingHeapObjects = ()
+  commandName _ = "HeapProfiler.stopTrackingHeapObjects"
+  fromJSON = const . A.Success . const ()
+
+
+-- | Parameters of the 'HeapProfiler.takeHeapSnapshot' command.
+data PHeapProfilerTakeHeapSnapshot = PHeapProfilerTakeHeapSnapshot
+  {
+    -- | If true 'reportHeapSnapshotProgress' events will be generated while snapshot is being taken.
+    pHeapProfilerTakeHeapSnapshotReportProgress :: Maybe Bool,
+    -- | If true, numerical values are included in the snapshot
+    pHeapProfilerTakeHeapSnapshotCaptureNumericValue :: Maybe Bool,
+    -- | If true, exposes internals of the snapshot.
+    pHeapProfilerTakeHeapSnapshotExposeInternals :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pHeapProfilerTakeHeapSnapshot
+  :: PHeapProfilerTakeHeapSnapshot
+pHeapProfilerTakeHeapSnapshot
+  = PHeapProfilerTakeHeapSnapshot
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PHeapProfilerTakeHeapSnapshot where
+  toJSON p = A.object $ catMaybes [
+    ("reportProgress" A..=) <$> (pHeapProfilerTakeHeapSnapshotReportProgress p),
+    ("captureNumericValue" A..=) <$> (pHeapProfilerTakeHeapSnapshotCaptureNumericValue p),
+    ("exposeInternals" A..=) <$> (pHeapProfilerTakeHeapSnapshotExposeInternals p)
+    ]
+instance Command PHeapProfilerTakeHeapSnapshot where
+  type CommandResponse PHeapProfilerTakeHeapSnapshot = ()
+  commandName _ = "HeapProfiler.takeHeapSnapshot"
+  fromJSON = const . A.Success . const ()
+
diff --git a/src/CDP/Domains/IO.hs b/src/CDP/Domains/IO.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains/IO.hs
@@ -0,0 +1,171 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+
+
+{- |
+= IO
+
+Input/Output operations for streams produced by DevTools.
+-}
+
+
+module CDP.Domains.IO (module CDP.Domains.IO) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+
+import CDP.Domains.Runtime as Runtime
+
+
+-- | Type 'IO.StreamHandle'.
+--   This is either obtained from another method or specified as `blob:&lt;uuid&gt;` where
+--   `&lt;uuid&gt` is an UUID of a Blob.
+type IOStreamHandle = T.Text
+
+-- | Close the stream, discard any temporary backing storage.
+
+-- | Parameters of the 'IO.close' command.
+data PIOClose = PIOClose
+  {
+    -- | Handle of the stream to close.
+    pIOCloseHandle :: IOStreamHandle
+  }
+  deriving (Eq, Show)
+pIOClose
+  {-
+  -- | Handle of the stream to close.
+  -}
+  :: IOStreamHandle
+  -> PIOClose
+pIOClose
+  arg_pIOCloseHandle
+  = PIOClose
+    arg_pIOCloseHandle
+instance ToJSON PIOClose where
+  toJSON p = A.object $ catMaybes [
+    ("handle" A..=) <$> Just (pIOCloseHandle p)
+    ]
+instance Command PIOClose where
+  type CommandResponse PIOClose = ()
+  commandName _ = "IO.close"
+  fromJSON = const . A.Success . const ()
+
+-- | Read a chunk of the stream
+
+-- | Parameters of the 'IO.read' command.
+data PIORead = PIORead
+  {
+    -- | Handle of the stream to read.
+    pIOReadHandle :: IOStreamHandle,
+    -- | Seek to the specified offset before reading (if not specificed, proceed with offset
+    --   following the last read). Some types of streams may only support sequential reads.
+    pIOReadOffset :: Maybe Int,
+    -- | Maximum number of bytes to read (left upon the agent discretion if not specified).
+    pIOReadSize :: Maybe Int
+  }
+  deriving (Eq, Show)
+pIORead
+  {-
+  -- | Handle of the stream to read.
+  -}
+  :: IOStreamHandle
+  -> PIORead
+pIORead
+  arg_pIOReadHandle
+  = PIORead
+    arg_pIOReadHandle
+    Nothing
+    Nothing
+instance ToJSON PIORead where
+  toJSON p = A.object $ catMaybes [
+    ("handle" A..=) <$> Just (pIOReadHandle p),
+    ("offset" A..=) <$> (pIOReadOffset p),
+    ("size" A..=) <$> (pIOReadSize p)
+    ]
+data IORead = IORead
+  {
+    -- | Set if the data is base64-encoded
+    iOReadBase64Encoded :: Maybe Bool,
+    -- | Data that were read.
+    iOReadData :: T.Text,
+    -- | Set if the end-of-file condition occurred while reading.
+    iOReadEof :: Bool
+  }
+  deriving (Eq, Show)
+instance FromJSON IORead where
+  parseJSON = A.withObject "IORead" $ \o -> IORead
+    <$> o A..:? "base64Encoded"
+    <*> o A..: "data"
+    <*> o A..: "eof"
+instance Command PIORead where
+  type CommandResponse PIORead = IORead
+  commandName _ = "IO.read"
+
+-- | Return UUID of Blob object specified by a remote object id.
+
+-- | Parameters of the 'IO.resolveBlob' command.
+data PIOResolveBlob = PIOResolveBlob
+  {
+    -- | Object id of a Blob object wrapper.
+    pIOResolveBlobObjectId :: Runtime.RuntimeRemoteObjectId
+  }
+  deriving (Eq, Show)
+pIOResolveBlob
+  {-
+  -- | Object id of a Blob object wrapper.
+  -}
+  :: Runtime.RuntimeRemoteObjectId
+  -> PIOResolveBlob
+pIOResolveBlob
+  arg_pIOResolveBlobObjectId
+  = PIOResolveBlob
+    arg_pIOResolveBlobObjectId
+instance ToJSON PIOResolveBlob where
+  toJSON p = A.object $ catMaybes [
+    ("objectId" A..=) <$> Just (pIOResolveBlobObjectId p)
+    ]
+data IOResolveBlob = IOResolveBlob
+  {
+    -- | UUID of the specified Blob.
+    iOResolveBlobUuid :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON IOResolveBlob where
+  parseJSON = A.withObject "IOResolveBlob" $ \o -> IOResolveBlob
+    <$> o A..: "uuid"
+instance Command PIOResolveBlob where
+  type CommandResponse PIOResolveBlob = IOResolveBlob
+  commandName _ = "IO.resolveBlob"
+
diff --git a/src/CDP/Domains/IndexedDB.hs b/src/CDP/Domains/IndexedDB.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains/IndexedDB.hs
@@ -0,0 +1,657 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+
+
+{- |
+= IndexedDB
+
+-}
+
+
+module CDP.Domains.IndexedDB (module CDP.Domains.IndexedDB) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+
+import CDP.Domains.Runtime as Runtime
+
+
+-- | Type 'IndexedDB.DatabaseWithObjectStores'.
+--   Database with an array of object stores.
+data IndexedDBDatabaseWithObjectStores = IndexedDBDatabaseWithObjectStores
+  {
+    -- | Database name.
+    indexedDBDatabaseWithObjectStoresName :: T.Text,
+    -- | Database version (type is not 'integer', as the standard
+    --   requires the version number to be 'unsigned long long')
+    indexedDBDatabaseWithObjectStoresVersion :: Double,
+    -- | Object stores in this database.
+    indexedDBDatabaseWithObjectStoresObjectStores :: [IndexedDBObjectStore]
+  }
+  deriving (Eq, Show)
+instance FromJSON IndexedDBDatabaseWithObjectStores where
+  parseJSON = A.withObject "IndexedDBDatabaseWithObjectStores" $ \o -> IndexedDBDatabaseWithObjectStores
+    <$> o A..: "name"
+    <*> o A..: "version"
+    <*> o A..: "objectStores"
+instance ToJSON IndexedDBDatabaseWithObjectStores where
+  toJSON p = A.object $ catMaybes [
+    ("name" A..=) <$> Just (indexedDBDatabaseWithObjectStoresName p),
+    ("version" A..=) <$> Just (indexedDBDatabaseWithObjectStoresVersion p),
+    ("objectStores" A..=) <$> Just (indexedDBDatabaseWithObjectStoresObjectStores p)
+    ]
+
+-- | Type 'IndexedDB.ObjectStore'.
+--   Object store.
+data IndexedDBObjectStore = IndexedDBObjectStore
+  {
+    -- | Object store name.
+    indexedDBObjectStoreName :: T.Text,
+    -- | Object store key path.
+    indexedDBObjectStoreKeyPath :: IndexedDBKeyPath,
+    -- | If true, object store has auto increment flag set.
+    indexedDBObjectStoreAutoIncrement :: Bool,
+    -- | Indexes in this object store.
+    indexedDBObjectStoreIndexes :: [IndexedDBObjectStoreIndex]
+  }
+  deriving (Eq, Show)
+instance FromJSON IndexedDBObjectStore where
+  parseJSON = A.withObject "IndexedDBObjectStore" $ \o -> IndexedDBObjectStore
+    <$> o A..: "name"
+    <*> o A..: "keyPath"
+    <*> o A..: "autoIncrement"
+    <*> o A..: "indexes"
+instance ToJSON IndexedDBObjectStore where
+  toJSON p = A.object $ catMaybes [
+    ("name" A..=) <$> Just (indexedDBObjectStoreName p),
+    ("keyPath" A..=) <$> Just (indexedDBObjectStoreKeyPath p),
+    ("autoIncrement" A..=) <$> Just (indexedDBObjectStoreAutoIncrement p),
+    ("indexes" A..=) <$> Just (indexedDBObjectStoreIndexes p)
+    ]
+
+-- | Type 'IndexedDB.ObjectStoreIndex'.
+--   Object store index.
+data IndexedDBObjectStoreIndex = IndexedDBObjectStoreIndex
+  {
+    -- | Index name.
+    indexedDBObjectStoreIndexName :: T.Text,
+    -- | Index key path.
+    indexedDBObjectStoreIndexKeyPath :: IndexedDBKeyPath,
+    -- | If true, index is unique.
+    indexedDBObjectStoreIndexUnique :: Bool,
+    -- | If true, index allows multiple entries for a key.
+    indexedDBObjectStoreIndexMultiEntry :: Bool
+  }
+  deriving (Eq, Show)
+instance FromJSON IndexedDBObjectStoreIndex where
+  parseJSON = A.withObject "IndexedDBObjectStoreIndex" $ \o -> IndexedDBObjectStoreIndex
+    <$> o A..: "name"
+    <*> o A..: "keyPath"
+    <*> o A..: "unique"
+    <*> o A..: "multiEntry"
+instance ToJSON IndexedDBObjectStoreIndex where
+  toJSON p = A.object $ catMaybes [
+    ("name" A..=) <$> Just (indexedDBObjectStoreIndexName p),
+    ("keyPath" A..=) <$> Just (indexedDBObjectStoreIndexKeyPath p),
+    ("unique" A..=) <$> Just (indexedDBObjectStoreIndexUnique p),
+    ("multiEntry" A..=) <$> Just (indexedDBObjectStoreIndexMultiEntry p)
+    ]
+
+-- | Type 'IndexedDB.Key'.
+--   Key.
+data IndexedDBKeyType = IndexedDBKeyTypeNumber | IndexedDBKeyTypeString | IndexedDBKeyTypeDate | IndexedDBKeyTypeArray
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON IndexedDBKeyType where
+  parseJSON = A.withText "IndexedDBKeyType" $ \v -> case v of
+    "number" -> pure IndexedDBKeyTypeNumber
+    "string" -> pure IndexedDBKeyTypeString
+    "date" -> pure IndexedDBKeyTypeDate
+    "array" -> pure IndexedDBKeyTypeArray
+    "_" -> fail "failed to parse IndexedDBKeyType"
+instance ToJSON IndexedDBKeyType where
+  toJSON v = A.String $ case v of
+    IndexedDBKeyTypeNumber -> "number"
+    IndexedDBKeyTypeString -> "string"
+    IndexedDBKeyTypeDate -> "date"
+    IndexedDBKeyTypeArray -> "array"
+data IndexedDBKey = IndexedDBKey
+  {
+    -- | Key type.
+    indexedDBKeyType :: IndexedDBKeyType,
+    -- | Number value.
+    indexedDBKeyNumber :: Maybe Double,
+    -- | String value.
+    indexedDBKeyString :: Maybe T.Text,
+    -- | Date value.
+    indexedDBKeyDate :: Maybe Double,
+    -- | Array value.
+    indexedDBKeyArray :: Maybe [IndexedDBKey]
+  }
+  deriving (Eq, Show)
+instance FromJSON IndexedDBKey where
+  parseJSON = A.withObject "IndexedDBKey" $ \o -> IndexedDBKey
+    <$> o A..: "type"
+    <*> o A..:? "number"
+    <*> o A..:? "string"
+    <*> o A..:? "date"
+    <*> o A..:? "array"
+instance ToJSON IndexedDBKey where
+  toJSON p = A.object $ catMaybes [
+    ("type" A..=) <$> Just (indexedDBKeyType p),
+    ("number" A..=) <$> (indexedDBKeyNumber p),
+    ("string" A..=) <$> (indexedDBKeyString p),
+    ("date" A..=) <$> (indexedDBKeyDate p),
+    ("array" A..=) <$> (indexedDBKeyArray p)
+    ]
+
+-- | Type 'IndexedDB.KeyRange'.
+--   Key range.
+data IndexedDBKeyRange = IndexedDBKeyRange
+  {
+    -- | Lower bound.
+    indexedDBKeyRangeLower :: Maybe IndexedDBKey,
+    -- | Upper bound.
+    indexedDBKeyRangeUpper :: Maybe IndexedDBKey,
+    -- | If true lower bound is open.
+    indexedDBKeyRangeLowerOpen :: Bool,
+    -- | If true upper bound is open.
+    indexedDBKeyRangeUpperOpen :: Bool
+  }
+  deriving (Eq, Show)
+instance FromJSON IndexedDBKeyRange where
+  parseJSON = A.withObject "IndexedDBKeyRange" $ \o -> IndexedDBKeyRange
+    <$> o A..:? "lower"
+    <*> o A..:? "upper"
+    <*> o A..: "lowerOpen"
+    <*> o A..: "upperOpen"
+instance ToJSON IndexedDBKeyRange where
+  toJSON p = A.object $ catMaybes [
+    ("lower" A..=) <$> (indexedDBKeyRangeLower p),
+    ("upper" A..=) <$> (indexedDBKeyRangeUpper p),
+    ("lowerOpen" A..=) <$> Just (indexedDBKeyRangeLowerOpen p),
+    ("upperOpen" A..=) <$> Just (indexedDBKeyRangeUpperOpen p)
+    ]
+
+-- | Type 'IndexedDB.DataEntry'.
+--   Data entry.
+data IndexedDBDataEntry = IndexedDBDataEntry
+  {
+    -- | Key object.
+    indexedDBDataEntryKey :: Runtime.RuntimeRemoteObject,
+    -- | Primary key object.
+    indexedDBDataEntryPrimaryKey :: Runtime.RuntimeRemoteObject,
+    -- | Value object.
+    indexedDBDataEntryValue :: Runtime.RuntimeRemoteObject
+  }
+  deriving (Eq, Show)
+instance FromJSON IndexedDBDataEntry where
+  parseJSON = A.withObject "IndexedDBDataEntry" $ \o -> IndexedDBDataEntry
+    <$> o A..: "key"
+    <*> o A..: "primaryKey"
+    <*> o A..: "value"
+instance ToJSON IndexedDBDataEntry where
+  toJSON p = A.object $ catMaybes [
+    ("key" A..=) <$> Just (indexedDBDataEntryKey p),
+    ("primaryKey" A..=) <$> Just (indexedDBDataEntryPrimaryKey p),
+    ("value" A..=) <$> Just (indexedDBDataEntryValue p)
+    ]
+
+-- | Type 'IndexedDB.KeyPath'.
+--   Key path.
+data IndexedDBKeyPathType = IndexedDBKeyPathTypeNull | IndexedDBKeyPathTypeString | IndexedDBKeyPathTypeArray
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON IndexedDBKeyPathType where
+  parseJSON = A.withText "IndexedDBKeyPathType" $ \v -> case v of
+    "null" -> pure IndexedDBKeyPathTypeNull
+    "string" -> pure IndexedDBKeyPathTypeString
+    "array" -> pure IndexedDBKeyPathTypeArray
+    "_" -> fail "failed to parse IndexedDBKeyPathType"
+instance ToJSON IndexedDBKeyPathType where
+  toJSON v = A.String $ case v of
+    IndexedDBKeyPathTypeNull -> "null"
+    IndexedDBKeyPathTypeString -> "string"
+    IndexedDBKeyPathTypeArray -> "array"
+data IndexedDBKeyPath = IndexedDBKeyPath
+  {
+    -- | Key path type.
+    indexedDBKeyPathType :: IndexedDBKeyPathType,
+    -- | String value.
+    indexedDBKeyPathString :: Maybe T.Text,
+    -- | Array value.
+    indexedDBKeyPathArray :: Maybe [T.Text]
+  }
+  deriving (Eq, Show)
+instance FromJSON IndexedDBKeyPath where
+  parseJSON = A.withObject "IndexedDBKeyPath" $ \o -> IndexedDBKeyPath
+    <$> o A..: "type"
+    <*> o A..:? "string"
+    <*> o A..:? "array"
+instance ToJSON IndexedDBKeyPath where
+  toJSON p = A.object $ catMaybes [
+    ("type" A..=) <$> Just (indexedDBKeyPathType p),
+    ("string" A..=) <$> (indexedDBKeyPathString p),
+    ("array" A..=) <$> (indexedDBKeyPathArray p)
+    ]
+
+-- | Clears all entries from an object store.
+
+-- | Parameters of the 'IndexedDB.clearObjectStore' command.
+data PIndexedDBClearObjectStore = PIndexedDBClearObjectStore
+  {
+    -- | At least and at most one of securityOrigin, storageKey must be specified.
+    --   Security origin.
+    pIndexedDBClearObjectStoreSecurityOrigin :: Maybe T.Text,
+    -- | Storage key.
+    pIndexedDBClearObjectStoreStorageKey :: Maybe T.Text,
+    -- | Database name.
+    pIndexedDBClearObjectStoreDatabaseName :: T.Text,
+    -- | Object store name.
+    pIndexedDBClearObjectStoreObjectStoreName :: T.Text
+  }
+  deriving (Eq, Show)
+pIndexedDBClearObjectStore
+  {-
+  -- | Database name.
+  -}
+  :: T.Text
+  {-
+  -- | Object store name.
+  -}
+  -> T.Text
+  -> PIndexedDBClearObjectStore
+pIndexedDBClearObjectStore
+  arg_pIndexedDBClearObjectStoreDatabaseName
+  arg_pIndexedDBClearObjectStoreObjectStoreName
+  = PIndexedDBClearObjectStore
+    Nothing
+    Nothing
+    arg_pIndexedDBClearObjectStoreDatabaseName
+    arg_pIndexedDBClearObjectStoreObjectStoreName
+instance ToJSON PIndexedDBClearObjectStore where
+  toJSON p = A.object $ catMaybes [
+    ("securityOrigin" A..=) <$> (pIndexedDBClearObjectStoreSecurityOrigin p),
+    ("storageKey" A..=) <$> (pIndexedDBClearObjectStoreStorageKey p),
+    ("databaseName" A..=) <$> Just (pIndexedDBClearObjectStoreDatabaseName p),
+    ("objectStoreName" A..=) <$> Just (pIndexedDBClearObjectStoreObjectStoreName p)
+    ]
+instance Command PIndexedDBClearObjectStore where
+  type CommandResponse PIndexedDBClearObjectStore = ()
+  commandName _ = "IndexedDB.clearObjectStore"
+  fromJSON = const . A.Success . const ()
+
+-- | Deletes a database.
+
+-- | Parameters of the 'IndexedDB.deleteDatabase' command.
+data PIndexedDBDeleteDatabase = PIndexedDBDeleteDatabase
+  {
+    -- | At least and at most one of securityOrigin, storageKey must be specified.
+    --   Security origin.
+    pIndexedDBDeleteDatabaseSecurityOrigin :: Maybe T.Text,
+    -- | Storage key.
+    pIndexedDBDeleteDatabaseStorageKey :: Maybe T.Text,
+    -- | Database name.
+    pIndexedDBDeleteDatabaseDatabaseName :: T.Text
+  }
+  deriving (Eq, Show)
+pIndexedDBDeleteDatabase
+  {-
+  -- | Database name.
+  -}
+  :: T.Text
+  -> PIndexedDBDeleteDatabase
+pIndexedDBDeleteDatabase
+  arg_pIndexedDBDeleteDatabaseDatabaseName
+  = PIndexedDBDeleteDatabase
+    Nothing
+    Nothing
+    arg_pIndexedDBDeleteDatabaseDatabaseName
+instance ToJSON PIndexedDBDeleteDatabase where
+  toJSON p = A.object $ catMaybes [
+    ("securityOrigin" A..=) <$> (pIndexedDBDeleteDatabaseSecurityOrigin p),
+    ("storageKey" A..=) <$> (pIndexedDBDeleteDatabaseStorageKey p),
+    ("databaseName" A..=) <$> Just (pIndexedDBDeleteDatabaseDatabaseName p)
+    ]
+instance Command PIndexedDBDeleteDatabase where
+  type CommandResponse PIndexedDBDeleteDatabase = ()
+  commandName _ = "IndexedDB.deleteDatabase"
+  fromJSON = const . A.Success . const ()
+
+-- | Delete a range of entries from an object store
+
+-- | Parameters of the 'IndexedDB.deleteObjectStoreEntries' command.
+data PIndexedDBDeleteObjectStoreEntries = PIndexedDBDeleteObjectStoreEntries
+  {
+    -- | At least and at most one of securityOrigin, storageKey must be specified.
+    --   Security origin.
+    pIndexedDBDeleteObjectStoreEntriesSecurityOrigin :: Maybe T.Text,
+    -- | Storage key.
+    pIndexedDBDeleteObjectStoreEntriesStorageKey :: Maybe T.Text,
+    pIndexedDBDeleteObjectStoreEntriesDatabaseName :: T.Text,
+    pIndexedDBDeleteObjectStoreEntriesObjectStoreName :: T.Text,
+    -- | Range of entry keys to delete
+    pIndexedDBDeleteObjectStoreEntriesKeyRange :: IndexedDBKeyRange
+  }
+  deriving (Eq, Show)
+pIndexedDBDeleteObjectStoreEntries
+  :: T.Text
+  -> T.Text
+  {-
+  -- | Range of entry keys to delete
+  -}
+  -> IndexedDBKeyRange
+  -> PIndexedDBDeleteObjectStoreEntries
+pIndexedDBDeleteObjectStoreEntries
+  arg_pIndexedDBDeleteObjectStoreEntriesDatabaseName
+  arg_pIndexedDBDeleteObjectStoreEntriesObjectStoreName
+  arg_pIndexedDBDeleteObjectStoreEntriesKeyRange
+  = PIndexedDBDeleteObjectStoreEntries
+    Nothing
+    Nothing
+    arg_pIndexedDBDeleteObjectStoreEntriesDatabaseName
+    arg_pIndexedDBDeleteObjectStoreEntriesObjectStoreName
+    arg_pIndexedDBDeleteObjectStoreEntriesKeyRange
+instance ToJSON PIndexedDBDeleteObjectStoreEntries where
+  toJSON p = A.object $ catMaybes [
+    ("securityOrigin" A..=) <$> (pIndexedDBDeleteObjectStoreEntriesSecurityOrigin p),
+    ("storageKey" A..=) <$> (pIndexedDBDeleteObjectStoreEntriesStorageKey p),
+    ("databaseName" A..=) <$> Just (pIndexedDBDeleteObjectStoreEntriesDatabaseName p),
+    ("objectStoreName" A..=) <$> Just (pIndexedDBDeleteObjectStoreEntriesObjectStoreName p),
+    ("keyRange" A..=) <$> Just (pIndexedDBDeleteObjectStoreEntriesKeyRange p)
+    ]
+instance Command PIndexedDBDeleteObjectStoreEntries where
+  type CommandResponse PIndexedDBDeleteObjectStoreEntries = ()
+  commandName _ = "IndexedDB.deleteObjectStoreEntries"
+  fromJSON = const . A.Success . const ()
+
+-- | Disables events from backend.
+
+-- | Parameters of the 'IndexedDB.disable' command.
+data PIndexedDBDisable = PIndexedDBDisable
+  deriving (Eq, Show)
+pIndexedDBDisable
+  :: PIndexedDBDisable
+pIndexedDBDisable
+  = PIndexedDBDisable
+instance ToJSON PIndexedDBDisable where
+  toJSON _ = A.Null
+instance Command PIndexedDBDisable where
+  type CommandResponse PIndexedDBDisable = ()
+  commandName _ = "IndexedDB.disable"
+  fromJSON = const . A.Success . const ()
+
+-- | Enables events from backend.
+
+-- | Parameters of the 'IndexedDB.enable' command.
+data PIndexedDBEnable = PIndexedDBEnable
+  deriving (Eq, Show)
+pIndexedDBEnable
+  :: PIndexedDBEnable
+pIndexedDBEnable
+  = PIndexedDBEnable
+instance ToJSON PIndexedDBEnable where
+  toJSON _ = A.Null
+instance Command PIndexedDBEnable where
+  type CommandResponse PIndexedDBEnable = ()
+  commandName _ = "IndexedDB.enable"
+  fromJSON = const . A.Success . const ()
+
+-- | Requests data from object store or index.
+
+-- | Parameters of the 'IndexedDB.requestData' command.
+data PIndexedDBRequestData = PIndexedDBRequestData
+  {
+    -- | At least and at most one of securityOrigin, storageKey must be specified.
+    --   Security origin.
+    pIndexedDBRequestDataSecurityOrigin :: Maybe T.Text,
+    -- | Storage key.
+    pIndexedDBRequestDataStorageKey :: Maybe T.Text,
+    -- | Database name.
+    pIndexedDBRequestDataDatabaseName :: T.Text,
+    -- | Object store name.
+    pIndexedDBRequestDataObjectStoreName :: T.Text,
+    -- | Index name, empty string for object store data requests.
+    pIndexedDBRequestDataIndexName :: T.Text,
+    -- | Number of records to skip.
+    pIndexedDBRequestDataSkipCount :: Int,
+    -- | Number of records to fetch.
+    pIndexedDBRequestDataPageSize :: Int,
+    -- | Key range.
+    pIndexedDBRequestDataKeyRange :: Maybe IndexedDBKeyRange
+  }
+  deriving (Eq, Show)
+pIndexedDBRequestData
+  {-
+  -- | Database name.
+  -}
+  :: T.Text
+  {-
+  -- | Object store name.
+  -}
+  -> T.Text
+  {-
+  -- | Index name, empty string for object store data requests.
+  -}
+  -> T.Text
+  {-
+  -- | Number of records to skip.
+  -}
+  -> Int
+  {-
+  -- | Number of records to fetch.
+  -}
+  -> Int
+  -> PIndexedDBRequestData
+pIndexedDBRequestData
+  arg_pIndexedDBRequestDataDatabaseName
+  arg_pIndexedDBRequestDataObjectStoreName
+  arg_pIndexedDBRequestDataIndexName
+  arg_pIndexedDBRequestDataSkipCount
+  arg_pIndexedDBRequestDataPageSize
+  = PIndexedDBRequestData
+    Nothing
+    Nothing
+    arg_pIndexedDBRequestDataDatabaseName
+    arg_pIndexedDBRequestDataObjectStoreName
+    arg_pIndexedDBRequestDataIndexName
+    arg_pIndexedDBRequestDataSkipCount
+    arg_pIndexedDBRequestDataPageSize
+    Nothing
+instance ToJSON PIndexedDBRequestData where
+  toJSON p = A.object $ catMaybes [
+    ("securityOrigin" A..=) <$> (pIndexedDBRequestDataSecurityOrigin p),
+    ("storageKey" A..=) <$> (pIndexedDBRequestDataStorageKey p),
+    ("databaseName" A..=) <$> Just (pIndexedDBRequestDataDatabaseName p),
+    ("objectStoreName" A..=) <$> Just (pIndexedDBRequestDataObjectStoreName p),
+    ("indexName" A..=) <$> Just (pIndexedDBRequestDataIndexName p),
+    ("skipCount" A..=) <$> Just (pIndexedDBRequestDataSkipCount p),
+    ("pageSize" A..=) <$> Just (pIndexedDBRequestDataPageSize p),
+    ("keyRange" A..=) <$> (pIndexedDBRequestDataKeyRange p)
+    ]
+data IndexedDBRequestData = IndexedDBRequestData
+  {
+    -- | Array of object store data entries.
+    indexedDBRequestDataObjectStoreDataEntries :: [IndexedDBDataEntry],
+    -- | If true, there are more entries to fetch in the given range.
+    indexedDBRequestDataHasMore :: Bool
+  }
+  deriving (Eq, Show)
+instance FromJSON IndexedDBRequestData where
+  parseJSON = A.withObject "IndexedDBRequestData" $ \o -> IndexedDBRequestData
+    <$> o A..: "objectStoreDataEntries"
+    <*> o A..: "hasMore"
+instance Command PIndexedDBRequestData where
+  type CommandResponse PIndexedDBRequestData = IndexedDBRequestData
+  commandName _ = "IndexedDB.requestData"
+
+-- | Gets metadata of an object store
+
+-- | Parameters of the 'IndexedDB.getMetadata' command.
+data PIndexedDBGetMetadata = PIndexedDBGetMetadata
+  {
+    -- | At least and at most one of securityOrigin, storageKey must be specified.
+    --   Security origin.
+    pIndexedDBGetMetadataSecurityOrigin :: Maybe T.Text,
+    -- | Storage key.
+    pIndexedDBGetMetadataStorageKey :: Maybe T.Text,
+    -- | Database name.
+    pIndexedDBGetMetadataDatabaseName :: T.Text,
+    -- | Object store name.
+    pIndexedDBGetMetadataObjectStoreName :: T.Text
+  }
+  deriving (Eq, Show)
+pIndexedDBGetMetadata
+  {-
+  -- | Database name.
+  -}
+  :: T.Text
+  {-
+  -- | Object store name.
+  -}
+  -> T.Text
+  -> PIndexedDBGetMetadata
+pIndexedDBGetMetadata
+  arg_pIndexedDBGetMetadataDatabaseName
+  arg_pIndexedDBGetMetadataObjectStoreName
+  = PIndexedDBGetMetadata
+    Nothing
+    Nothing
+    arg_pIndexedDBGetMetadataDatabaseName
+    arg_pIndexedDBGetMetadataObjectStoreName
+instance ToJSON PIndexedDBGetMetadata where
+  toJSON p = A.object $ catMaybes [
+    ("securityOrigin" A..=) <$> (pIndexedDBGetMetadataSecurityOrigin p),
+    ("storageKey" A..=) <$> (pIndexedDBGetMetadataStorageKey p),
+    ("databaseName" A..=) <$> Just (pIndexedDBGetMetadataDatabaseName p),
+    ("objectStoreName" A..=) <$> Just (pIndexedDBGetMetadataObjectStoreName p)
+    ]
+data IndexedDBGetMetadata = IndexedDBGetMetadata
+  {
+    -- | the entries count
+    indexedDBGetMetadataEntriesCount :: Double,
+    -- | the current value of key generator, to become the next inserted
+    --   key into the object store. Valid if objectStore.autoIncrement
+    --   is true.
+    indexedDBGetMetadataKeyGeneratorValue :: Double
+  }
+  deriving (Eq, Show)
+instance FromJSON IndexedDBGetMetadata where
+  parseJSON = A.withObject "IndexedDBGetMetadata" $ \o -> IndexedDBGetMetadata
+    <$> o A..: "entriesCount"
+    <*> o A..: "keyGeneratorValue"
+instance Command PIndexedDBGetMetadata where
+  type CommandResponse PIndexedDBGetMetadata = IndexedDBGetMetadata
+  commandName _ = "IndexedDB.getMetadata"
+
+-- | Requests database with given name in given frame.
+
+-- | Parameters of the 'IndexedDB.requestDatabase' command.
+data PIndexedDBRequestDatabase = PIndexedDBRequestDatabase
+  {
+    -- | At least and at most one of securityOrigin, storageKey must be specified.
+    --   Security origin.
+    pIndexedDBRequestDatabaseSecurityOrigin :: Maybe T.Text,
+    -- | Storage key.
+    pIndexedDBRequestDatabaseStorageKey :: Maybe T.Text,
+    -- | Database name.
+    pIndexedDBRequestDatabaseDatabaseName :: T.Text
+  }
+  deriving (Eq, Show)
+pIndexedDBRequestDatabase
+  {-
+  -- | Database name.
+  -}
+  :: T.Text
+  -> PIndexedDBRequestDatabase
+pIndexedDBRequestDatabase
+  arg_pIndexedDBRequestDatabaseDatabaseName
+  = PIndexedDBRequestDatabase
+    Nothing
+    Nothing
+    arg_pIndexedDBRequestDatabaseDatabaseName
+instance ToJSON PIndexedDBRequestDatabase where
+  toJSON p = A.object $ catMaybes [
+    ("securityOrigin" A..=) <$> (pIndexedDBRequestDatabaseSecurityOrigin p),
+    ("storageKey" A..=) <$> (pIndexedDBRequestDatabaseStorageKey p),
+    ("databaseName" A..=) <$> Just (pIndexedDBRequestDatabaseDatabaseName p)
+    ]
+data IndexedDBRequestDatabase = IndexedDBRequestDatabase
+  {
+    -- | Database with an array of object stores.
+    indexedDBRequestDatabaseDatabaseWithObjectStores :: IndexedDBDatabaseWithObjectStores
+  }
+  deriving (Eq, Show)
+instance FromJSON IndexedDBRequestDatabase where
+  parseJSON = A.withObject "IndexedDBRequestDatabase" $ \o -> IndexedDBRequestDatabase
+    <$> o A..: "databaseWithObjectStores"
+instance Command PIndexedDBRequestDatabase where
+  type CommandResponse PIndexedDBRequestDatabase = IndexedDBRequestDatabase
+  commandName _ = "IndexedDB.requestDatabase"
+
+-- | Requests database names for given security origin.
+
+-- | Parameters of the 'IndexedDB.requestDatabaseNames' command.
+data PIndexedDBRequestDatabaseNames = PIndexedDBRequestDatabaseNames
+  {
+    -- | At least and at most one of securityOrigin, storageKey must be specified.
+    --   Security origin.
+    pIndexedDBRequestDatabaseNamesSecurityOrigin :: Maybe T.Text,
+    -- | Storage key.
+    pIndexedDBRequestDatabaseNamesStorageKey :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+pIndexedDBRequestDatabaseNames
+  :: PIndexedDBRequestDatabaseNames
+pIndexedDBRequestDatabaseNames
+  = PIndexedDBRequestDatabaseNames
+    Nothing
+    Nothing
+instance ToJSON PIndexedDBRequestDatabaseNames where
+  toJSON p = A.object $ catMaybes [
+    ("securityOrigin" A..=) <$> (pIndexedDBRequestDatabaseNamesSecurityOrigin p),
+    ("storageKey" A..=) <$> (pIndexedDBRequestDatabaseNamesStorageKey p)
+    ]
+data IndexedDBRequestDatabaseNames = IndexedDBRequestDatabaseNames
+  {
+    -- | Database names for origin.
+    indexedDBRequestDatabaseNamesDatabaseNames :: [T.Text]
+  }
+  deriving (Eq, Show)
+instance FromJSON IndexedDBRequestDatabaseNames where
+  parseJSON = A.withObject "IndexedDBRequestDatabaseNames" $ \o -> IndexedDBRequestDatabaseNames
+    <$> o A..: "databaseNames"
+instance Command PIndexedDBRequestDatabaseNames where
+  type CommandResponse PIndexedDBRequestDatabaseNames = IndexedDBRequestDatabaseNames
+  commandName _ = "IndexedDB.requestDatabaseNames"
+
diff --git a/src/CDP/Domains/Input.hs b/src/CDP/Domains/Input.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains/Input.hs
@@ -0,0 +1,996 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+
+
+{- |
+= Input
+
+-}
+
+
+module CDP.Domains.Input (module CDP.Domains.Input) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+
+
+
+-- | Type 'Input.TouchPoint'.
+data InputTouchPoint = InputTouchPoint
+  {
+    -- | X coordinate of the event relative to the main frame's viewport in CSS pixels.
+    inputTouchPointX :: Double,
+    -- | Y coordinate of the event relative to the main frame's viewport in CSS pixels. 0 refers to
+    --   the top of the viewport and Y increases as it proceeds towards the bottom of the viewport.
+    inputTouchPointY :: Double,
+    -- | X radius of the touch area (default: 1.0).
+    inputTouchPointRadiusX :: Maybe Double,
+    -- | Y radius of the touch area (default: 1.0).
+    inputTouchPointRadiusY :: Maybe Double,
+    -- | Rotation angle (default: 0.0).
+    inputTouchPointRotationAngle :: Maybe Double,
+    -- | Force (default: 1.0).
+    inputTouchPointForce :: Maybe Double,
+    -- | The normalized tangential pressure, which has a range of [-1,1] (default: 0).
+    inputTouchPointTangentialPressure :: Maybe Double,
+    -- | The plane angle between the Y-Z plane and the plane containing both the stylus axis and the Y axis, in degrees of the range [-90,90], a positive tiltX is to the right (default: 0)
+    inputTouchPointTiltX :: Maybe Int,
+    -- | The plane angle between the X-Z plane and the plane containing both the stylus axis and the X axis, in degrees of the range [-90,90], a positive tiltY is towards the user (default: 0).
+    inputTouchPointTiltY :: Maybe Int,
+    -- | The clockwise rotation of a pen stylus around its own major axis, in degrees in the range [0,359] (default: 0).
+    inputTouchPointTwist :: Maybe Int,
+    -- | Identifier used to track touch sources between events, must be unique within an event.
+    inputTouchPointId :: Maybe Double
+  }
+  deriving (Eq, Show)
+instance FromJSON InputTouchPoint where
+  parseJSON = A.withObject "InputTouchPoint" $ \o -> InputTouchPoint
+    <$> o A..: "x"
+    <*> o A..: "y"
+    <*> o A..:? "radiusX"
+    <*> o A..:? "radiusY"
+    <*> o A..:? "rotationAngle"
+    <*> o A..:? "force"
+    <*> o A..:? "tangentialPressure"
+    <*> o A..:? "tiltX"
+    <*> o A..:? "tiltY"
+    <*> o A..:? "twist"
+    <*> o A..:? "id"
+instance ToJSON InputTouchPoint where
+  toJSON p = A.object $ catMaybes [
+    ("x" A..=) <$> Just (inputTouchPointX p),
+    ("y" A..=) <$> Just (inputTouchPointY p),
+    ("radiusX" A..=) <$> (inputTouchPointRadiusX p),
+    ("radiusY" A..=) <$> (inputTouchPointRadiusY p),
+    ("rotationAngle" A..=) <$> (inputTouchPointRotationAngle p),
+    ("force" A..=) <$> (inputTouchPointForce p),
+    ("tangentialPressure" A..=) <$> (inputTouchPointTangentialPressure p),
+    ("tiltX" A..=) <$> (inputTouchPointTiltX p),
+    ("tiltY" A..=) <$> (inputTouchPointTiltY p),
+    ("twist" A..=) <$> (inputTouchPointTwist p),
+    ("id" A..=) <$> (inputTouchPointId p)
+    ]
+
+-- | Type 'Input.GestureSourceType'.
+data InputGestureSourceType = InputGestureSourceTypeDefault | InputGestureSourceTypeTouch | InputGestureSourceTypeMouse
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON InputGestureSourceType where
+  parseJSON = A.withText "InputGestureSourceType" $ \v -> case v of
+    "default" -> pure InputGestureSourceTypeDefault
+    "touch" -> pure InputGestureSourceTypeTouch
+    "mouse" -> pure InputGestureSourceTypeMouse
+    "_" -> fail "failed to parse InputGestureSourceType"
+instance ToJSON InputGestureSourceType where
+  toJSON v = A.String $ case v of
+    InputGestureSourceTypeDefault -> "default"
+    InputGestureSourceTypeTouch -> "touch"
+    InputGestureSourceTypeMouse -> "mouse"
+
+-- | Type 'Input.MouseButton'.
+data InputMouseButton = InputMouseButtonNone | InputMouseButtonLeft | InputMouseButtonMiddle | InputMouseButtonRight | InputMouseButtonBack | InputMouseButtonForward
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON InputMouseButton where
+  parseJSON = A.withText "InputMouseButton" $ \v -> case v of
+    "none" -> pure InputMouseButtonNone
+    "left" -> pure InputMouseButtonLeft
+    "middle" -> pure InputMouseButtonMiddle
+    "right" -> pure InputMouseButtonRight
+    "back" -> pure InputMouseButtonBack
+    "forward" -> pure InputMouseButtonForward
+    "_" -> fail "failed to parse InputMouseButton"
+instance ToJSON InputMouseButton where
+  toJSON v = A.String $ case v of
+    InputMouseButtonNone -> "none"
+    InputMouseButtonLeft -> "left"
+    InputMouseButtonMiddle -> "middle"
+    InputMouseButtonRight -> "right"
+    InputMouseButtonBack -> "back"
+    InputMouseButtonForward -> "forward"
+
+-- | Type 'Input.TimeSinceEpoch'.
+--   UTC time in seconds, counted from January 1, 1970.
+type InputTimeSinceEpoch = Double
+
+-- | Type 'Input.DragDataItem'.
+data InputDragDataItem = InputDragDataItem
+  {
+    -- | Mime type of the dragged data.
+    inputDragDataItemMimeType :: T.Text,
+    -- | Depending of the value of `mimeType`, it contains the dragged link,
+    --   text, HTML markup or any other data.
+    inputDragDataItemData :: T.Text,
+    -- | Title associated with a link. Only valid when `mimeType` == "text/uri-list".
+    inputDragDataItemTitle :: Maybe T.Text,
+    -- | Stores the base URL for the contained markup. Only valid when `mimeType`
+    --   == "text/html".
+    inputDragDataItemBaseURL :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON InputDragDataItem where
+  parseJSON = A.withObject "InputDragDataItem" $ \o -> InputDragDataItem
+    <$> o A..: "mimeType"
+    <*> o A..: "data"
+    <*> o A..:? "title"
+    <*> o A..:? "baseURL"
+instance ToJSON InputDragDataItem where
+  toJSON p = A.object $ catMaybes [
+    ("mimeType" A..=) <$> Just (inputDragDataItemMimeType p),
+    ("data" A..=) <$> Just (inputDragDataItemData p),
+    ("title" A..=) <$> (inputDragDataItemTitle p),
+    ("baseURL" A..=) <$> (inputDragDataItemBaseURL p)
+    ]
+
+-- | Type 'Input.DragData'.
+data InputDragData = InputDragData
+  {
+    inputDragDataItems :: [InputDragDataItem],
+    -- | List of filenames that should be included when dropping
+    inputDragDataFiles :: Maybe [T.Text],
+    -- | Bit field representing allowed drag operations. Copy = 1, Link = 2, Move = 16
+    inputDragDataDragOperationsMask :: Int
+  }
+  deriving (Eq, Show)
+instance FromJSON InputDragData where
+  parseJSON = A.withObject "InputDragData" $ \o -> InputDragData
+    <$> o A..: "items"
+    <*> o A..:? "files"
+    <*> o A..: "dragOperationsMask"
+instance ToJSON InputDragData where
+  toJSON p = A.object $ catMaybes [
+    ("items" A..=) <$> Just (inputDragDataItems p),
+    ("files" A..=) <$> (inputDragDataFiles p),
+    ("dragOperationsMask" A..=) <$> Just (inputDragDataDragOperationsMask p)
+    ]
+
+-- | Type of the 'Input.dragIntercepted' event.
+data InputDragIntercepted = InputDragIntercepted
+  {
+    inputDragInterceptedData :: InputDragData
+  }
+  deriving (Eq, Show)
+instance FromJSON InputDragIntercepted where
+  parseJSON = A.withObject "InputDragIntercepted" $ \o -> InputDragIntercepted
+    <$> o A..: "data"
+instance Event InputDragIntercepted where
+  eventName _ = "Input.dragIntercepted"
+
+-- | Dispatches a drag event into the page.
+
+-- | Parameters of the 'Input.dispatchDragEvent' command.
+data PInputDispatchDragEventType = PInputDispatchDragEventTypeDragEnter | PInputDispatchDragEventTypeDragOver | PInputDispatchDragEventTypeDrop | PInputDispatchDragEventTypeDragCancel
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PInputDispatchDragEventType where
+  parseJSON = A.withText "PInputDispatchDragEventType" $ \v -> case v of
+    "dragEnter" -> pure PInputDispatchDragEventTypeDragEnter
+    "dragOver" -> pure PInputDispatchDragEventTypeDragOver
+    "drop" -> pure PInputDispatchDragEventTypeDrop
+    "dragCancel" -> pure PInputDispatchDragEventTypeDragCancel
+    "_" -> fail "failed to parse PInputDispatchDragEventType"
+instance ToJSON PInputDispatchDragEventType where
+  toJSON v = A.String $ case v of
+    PInputDispatchDragEventTypeDragEnter -> "dragEnter"
+    PInputDispatchDragEventTypeDragOver -> "dragOver"
+    PInputDispatchDragEventTypeDrop -> "drop"
+    PInputDispatchDragEventTypeDragCancel -> "dragCancel"
+data PInputDispatchDragEvent = PInputDispatchDragEvent
+  {
+    -- | Type of the drag event.
+    pInputDispatchDragEventType :: PInputDispatchDragEventType,
+    -- | X coordinate of the event relative to the main frame's viewport in CSS pixels.
+    pInputDispatchDragEventX :: Double,
+    -- | Y coordinate of the event relative to the main frame's viewport in CSS pixels. 0 refers to
+    --   the top of the viewport and Y increases as it proceeds towards the bottom of the viewport.
+    pInputDispatchDragEventY :: Double,
+    pInputDispatchDragEventData :: InputDragData,
+    -- | Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8
+    --   (default: 0).
+    pInputDispatchDragEventModifiers :: Maybe Int
+  }
+  deriving (Eq, Show)
+pInputDispatchDragEvent
+  {-
+  -- | Type of the drag event.
+  -}
+  :: PInputDispatchDragEventType
+  {-
+  -- | X coordinate of the event relative to the main frame's viewport in CSS pixels.
+  -}
+  -> Double
+  {-
+  -- | Y coordinate of the event relative to the main frame's viewport in CSS pixels. 0 refers to
+  --   the top of the viewport and Y increases as it proceeds towards the bottom of the viewport.
+  -}
+  -> Double
+  -> InputDragData
+  -> PInputDispatchDragEvent
+pInputDispatchDragEvent
+  arg_pInputDispatchDragEventType
+  arg_pInputDispatchDragEventX
+  arg_pInputDispatchDragEventY
+  arg_pInputDispatchDragEventData
+  = PInputDispatchDragEvent
+    arg_pInputDispatchDragEventType
+    arg_pInputDispatchDragEventX
+    arg_pInputDispatchDragEventY
+    arg_pInputDispatchDragEventData
+    Nothing
+instance ToJSON PInputDispatchDragEvent where
+  toJSON p = A.object $ catMaybes [
+    ("type" A..=) <$> Just (pInputDispatchDragEventType p),
+    ("x" A..=) <$> Just (pInputDispatchDragEventX p),
+    ("y" A..=) <$> Just (pInputDispatchDragEventY p),
+    ("data" A..=) <$> Just (pInputDispatchDragEventData p),
+    ("modifiers" A..=) <$> (pInputDispatchDragEventModifiers p)
+    ]
+instance Command PInputDispatchDragEvent where
+  type CommandResponse PInputDispatchDragEvent = ()
+  commandName _ = "Input.dispatchDragEvent"
+  fromJSON = const . A.Success . const ()
+
+-- | Dispatches a key event to the page.
+
+-- | Parameters of the 'Input.dispatchKeyEvent' command.
+data PInputDispatchKeyEventType = PInputDispatchKeyEventTypeKeyDown | PInputDispatchKeyEventTypeKeyUp | PInputDispatchKeyEventTypeRawKeyDown | PInputDispatchKeyEventTypeChar
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PInputDispatchKeyEventType where
+  parseJSON = A.withText "PInputDispatchKeyEventType" $ \v -> case v of
+    "keyDown" -> pure PInputDispatchKeyEventTypeKeyDown
+    "keyUp" -> pure PInputDispatchKeyEventTypeKeyUp
+    "rawKeyDown" -> pure PInputDispatchKeyEventTypeRawKeyDown
+    "char" -> pure PInputDispatchKeyEventTypeChar
+    "_" -> fail "failed to parse PInputDispatchKeyEventType"
+instance ToJSON PInputDispatchKeyEventType where
+  toJSON v = A.String $ case v of
+    PInputDispatchKeyEventTypeKeyDown -> "keyDown"
+    PInputDispatchKeyEventTypeKeyUp -> "keyUp"
+    PInputDispatchKeyEventTypeRawKeyDown -> "rawKeyDown"
+    PInputDispatchKeyEventTypeChar -> "char"
+data PInputDispatchKeyEvent = PInputDispatchKeyEvent
+  {
+    -- | Type of the key event.
+    pInputDispatchKeyEventType :: PInputDispatchKeyEventType,
+    -- | Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8
+    --   (default: 0).
+    pInputDispatchKeyEventModifiers :: Maybe Int,
+    -- | Time at which the event occurred.
+    pInputDispatchKeyEventTimestamp :: Maybe InputTimeSinceEpoch,
+    -- | Text as generated by processing a virtual key code with a keyboard layout. Not needed for
+    --   for `keyUp` and `rawKeyDown` events (default: "")
+    pInputDispatchKeyEventText :: Maybe T.Text,
+    -- | Text that would have been generated by the keyboard if no modifiers were pressed (except for
+    --   shift). Useful for shortcut (accelerator) key handling (default: "").
+    pInputDispatchKeyEventUnmodifiedText :: Maybe T.Text,
+    -- | Unique key identifier (e.g., 'U+0041') (default: "").
+    pInputDispatchKeyEventKeyIdentifier :: Maybe T.Text,
+    -- | Unique DOM defined string value for each physical key (e.g., 'KeyA') (default: "").
+    pInputDispatchKeyEventCode :: Maybe T.Text,
+    -- | Unique DOM defined string value describing the meaning of the key in the context of active
+    --   modifiers, keyboard layout, etc (e.g., 'AltGr') (default: "").
+    pInputDispatchKeyEventKey :: Maybe T.Text,
+    -- | Windows virtual key code (default: 0).
+    pInputDispatchKeyEventWindowsVirtualKeyCode :: Maybe Int,
+    -- | Native virtual key code (default: 0).
+    pInputDispatchKeyEventNativeVirtualKeyCode :: Maybe Int,
+    -- | Whether the event was generated from auto repeat (default: false).
+    pInputDispatchKeyEventAutoRepeat :: Maybe Bool,
+    -- | Whether the event was generated from the keypad (default: false).
+    pInputDispatchKeyEventIsKeypad :: Maybe Bool,
+    -- | Whether the event was a system key event (default: false).
+    pInputDispatchKeyEventIsSystemKey :: Maybe Bool,
+    -- | Whether the event was from the left or right side of the keyboard. 1=Left, 2=Right (default:
+    --   0).
+    pInputDispatchKeyEventLocation :: Maybe Int,
+    -- | Editing commands to send with the key event (e.g., 'selectAll') (default: []).
+    --   These are related to but not equal the command names used in `document.execCommand` and NSStandardKeyBindingResponding.
+    --   See https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/editing/commands/editor_command_names.h for valid command names.
+    pInputDispatchKeyEventCommands :: Maybe [T.Text]
+  }
+  deriving (Eq, Show)
+pInputDispatchKeyEvent
+  {-
+  -- | Type of the key event.
+  -}
+  :: PInputDispatchKeyEventType
+  -> PInputDispatchKeyEvent
+pInputDispatchKeyEvent
+  arg_pInputDispatchKeyEventType
+  = PInputDispatchKeyEvent
+    arg_pInputDispatchKeyEventType
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PInputDispatchKeyEvent where
+  toJSON p = A.object $ catMaybes [
+    ("type" A..=) <$> Just (pInputDispatchKeyEventType p),
+    ("modifiers" A..=) <$> (pInputDispatchKeyEventModifiers p),
+    ("timestamp" A..=) <$> (pInputDispatchKeyEventTimestamp p),
+    ("text" A..=) <$> (pInputDispatchKeyEventText p),
+    ("unmodifiedText" A..=) <$> (pInputDispatchKeyEventUnmodifiedText p),
+    ("keyIdentifier" A..=) <$> (pInputDispatchKeyEventKeyIdentifier p),
+    ("code" A..=) <$> (pInputDispatchKeyEventCode p),
+    ("key" A..=) <$> (pInputDispatchKeyEventKey p),
+    ("windowsVirtualKeyCode" A..=) <$> (pInputDispatchKeyEventWindowsVirtualKeyCode p),
+    ("nativeVirtualKeyCode" A..=) <$> (pInputDispatchKeyEventNativeVirtualKeyCode p),
+    ("autoRepeat" A..=) <$> (pInputDispatchKeyEventAutoRepeat p),
+    ("isKeypad" A..=) <$> (pInputDispatchKeyEventIsKeypad p),
+    ("isSystemKey" A..=) <$> (pInputDispatchKeyEventIsSystemKey p),
+    ("location" A..=) <$> (pInputDispatchKeyEventLocation p),
+    ("commands" A..=) <$> (pInputDispatchKeyEventCommands p)
+    ]
+instance Command PInputDispatchKeyEvent where
+  type CommandResponse PInputDispatchKeyEvent = ()
+  commandName _ = "Input.dispatchKeyEvent"
+  fromJSON = const . A.Success . const ()
+
+-- | This method emulates inserting text that doesn't come from a key press,
+--   for example an emoji keyboard or an IME.
+
+-- | Parameters of the 'Input.insertText' command.
+data PInputInsertText = PInputInsertText
+  {
+    -- | The text to insert.
+    pInputInsertTextText :: T.Text
+  }
+  deriving (Eq, Show)
+pInputInsertText
+  {-
+  -- | The text to insert.
+  -}
+  :: T.Text
+  -> PInputInsertText
+pInputInsertText
+  arg_pInputInsertTextText
+  = PInputInsertText
+    arg_pInputInsertTextText
+instance ToJSON PInputInsertText where
+  toJSON p = A.object $ catMaybes [
+    ("text" A..=) <$> Just (pInputInsertTextText p)
+    ]
+instance Command PInputInsertText where
+  type CommandResponse PInputInsertText = ()
+  commandName _ = "Input.insertText"
+  fromJSON = const . A.Success . const ()
+
+-- | This method sets the current candidate text for ime.
+--   Use imeCommitComposition to commit the final text.
+--   Use imeSetComposition with empty string as text to cancel composition.
+
+-- | Parameters of the 'Input.imeSetComposition' command.
+data PInputImeSetComposition = PInputImeSetComposition
+  {
+    -- | The text to insert
+    pInputImeSetCompositionText :: T.Text,
+    -- | selection start
+    pInputImeSetCompositionSelectionStart :: Int,
+    -- | selection end
+    pInputImeSetCompositionSelectionEnd :: Int,
+    -- | replacement start
+    pInputImeSetCompositionReplacementStart :: Maybe Int,
+    -- | replacement end
+    pInputImeSetCompositionReplacementEnd :: Maybe Int
+  }
+  deriving (Eq, Show)
+pInputImeSetComposition
+  {-
+  -- | The text to insert
+  -}
+  :: T.Text
+  {-
+  -- | selection start
+  -}
+  -> Int
+  {-
+  -- | selection end
+  -}
+  -> Int
+  -> PInputImeSetComposition
+pInputImeSetComposition
+  arg_pInputImeSetCompositionText
+  arg_pInputImeSetCompositionSelectionStart
+  arg_pInputImeSetCompositionSelectionEnd
+  = PInputImeSetComposition
+    arg_pInputImeSetCompositionText
+    arg_pInputImeSetCompositionSelectionStart
+    arg_pInputImeSetCompositionSelectionEnd
+    Nothing
+    Nothing
+instance ToJSON PInputImeSetComposition where
+  toJSON p = A.object $ catMaybes [
+    ("text" A..=) <$> Just (pInputImeSetCompositionText p),
+    ("selectionStart" A..=) <$> Just (pInputImeSetCompositionSelectionStart p),
+    ("selectionEnd" A..=) <$> Just (pInputImeSetCompositionSelectionEnd p),
+    ("replacementStart" A..=) <$> (pInputImeSetCompositionReplacementStart p),
+    ("replacementEnd" A..=) <$> (pInputImeSetCompositionReplacementEnd p)
+    ]
+instance Command PInputImeSetComposition where
+  type CommandResponse PInputImeSetComposition = ()
+  commandName _ = "Input.imeSetComposition"
+  fromJSON = const . A.Success . const ()
+
+-- | Dispatches a mouse event to the page.
+
+-- | Parameters of the 'Input.dispatchMouseEvent' command.
+data PInputDispatchMouseEventType = PInputDispatchMouseEventTypeMousePressed | PInputDispatchMouseEventTypeMouseReleased | PInputDispatchMouseEventTypeMouseMoved | PInputDispatchMouseEventTypeMouseWheel
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PInputDispatchMouseEventType where
+  parseJSON = A.withText "PInputDispatchMouseEventType" $ \v -> case v of
+    "mousePressed" -> pure PInputDispatchMouseEventTypeMousePressed
+    "mouseReleased" -> pure PInputDispatchMouseEventTypeMouseReleased
+    "mouseMoved" -> pure PInputDispatchMouseEventTypeMouseMoved
+    "mouseWheel" -> pure PInputDispatchMouseEventTypeMouseWheel
+    "_" -> fail "failed to parse PInputDispatchMouseEventType"
+instance ToJSON PInputDispatchMouseEventType where
+  toJSON v = A.String $ case v of
+    PInputDispatchMouseEventTypeMousePressed -> "mousePressed"
+    PInputDispatchMouseEventTypeMouseReleased -> "mouseReleased"
+    PInputDispatchMouseEventTypeMouseMoved -> "mouseMoved"
+    PInputDispatchMouseEventTypeMouseWheel -> "mouseWheel"
+data PInputDispatchMouseEventPointerType = PInputDispatchMouseEventPointerTypeMouse | PInputDispatchMouseEventPointerTypePen
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PInputDispatchMouseEventPointerType where
+  parseJSON = A.withText "PInputDispatchMouseEventPointerType" $ \v -> case v of
+    "mouse" -> pure PInputDispatchMouseEventPointerTypeMouse
+    "pen" -> pure PInputDispatchMouseEventPointerTypePen
+    "_" -> fail "failed to parse PInputDispatchMouseEventPointerType"
+instance ToJSON PInputDispatchMouseEventPointerType where
+  toJSON v = A.String $ case v of
+    PInputDispatchMouseEventPointerTypeMouse -> "mouse"
+    PInputDispatchMouseEventPointerTypePen -> "pen"
+data PInputDispatchMouseEvent = PInputDispatchMouseEvent
+  {
+    -- | Type of the mouse event.
+    pInputDispatchMouseEventType :: PInputDispatchMouseEventType,
+    -- | X coordinate of the event relative to the main frame's viewport in CSS pixels.
+    pInputDispatchMouseEventX :: Double,
+    -- | Y coordinate of the event relative to the main frame's viewport in CSS pixels. 0 refers to
+    --   the top of the viewport and Y increases as it proceeds towards the bottom of the viewport.
+    pInputDispatchMouseEventY :: Double,
+    -- | Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8
+    --   (default: 0).
+    pInputDispatchMouseEventModifiers :: Maybe Int,
+    -- | Time at which the event occurred.
+    pInputDispatchMouseEventTimestamp :: Maybe InputTimeSinceEpoch,
+    -- | Mouse button (default: "none").
+    pInputDispatchMouseEventButton :: Maybe InputMouseButton,
+    -- | A number indicating which buttons are pressed on the mouse when a mouse event is triggered.
+    --   Left=1, Right=2, Middle=4, Back=8, Forward=16, None=0.
+    pInputDispatchMouseEventButtons :: Maybe Int,
+    -- | Number of times the mouse button was clicked (default: 0).
+    pInputDispatchMouseEventClickCount :: Maybe Int,
+    -- | The normalized pressure, which has a range of [0,1] (default: 0).
+    pInputDispatchMouseEventForce :: Maybe Double,
+    -- | The normalized tangential pressure, which has a range of [-1,1] (default: 0).
+    pInputDispatchMouseEventTangentialPressure :: Maybe Double,
+    -- | The plane angle between the Y-Z plane and the plane containing both the stylus axis and the Y axis, in degrees of the range [-90,90], a positive tiltX is to the right (default: 0).
+    pInputDispatchMouseEventTiltX :: Maybe Int,
+    -- | The plane angle between the X-Z plane and the plane containing both the stylus axis and the X axis, in degrees of the range [-90,90], a positive tiltY is towards the user (default: 0).
+    pInputDispatchMouseEventTiltY :: Maybe Int,
+    -- | The clockwise rotation of a pen stylus around its own major axis, in degrees in the range [0,359] (default: 0).
+    pInputDispatchMouseEventTwist :: Maybe Int,
+    -- | X delta in CSS pixels for mouse wheel event (default: 0).
+    pInputDispatchMouseEventDeltaX :: Maybe Double,
+    -- | Y delta in CSS pixels for mouse wheel event (default: 0).
+    pInputDispatchMouseEventDeltaY :: Maybe Double,
+    -- | Pointer type (default: "mouse").
+    pInputDispatchMouseEventPointerType :: Maybe PInputDispatchMouseEventPointerType
+  }
+  deriving (Eq, Show)
+pInputDispatchMouseEvent
+  {-
+  -- | Type of the mouse event.
+  -}
+  :: PInputDispatchMouseEventType
+  {-
+  -- | X coordinate of the event relative to the main frame's viewport in CSS pixels.
+  -}
+  -> Double
+  {-
+  -- | Y coordinate of the event relative to the main frame's viewport in CSS pixels. 0 refers to
+  --   the top of the viewport and Y increases as it proceeds towards the bottom of the viewport.
+  -}
+  -> Double
+  -> PInputDispatchMouseEvent
+pInputDispatchMouseEvent
+  arg_pInputDispatchMouseEventType
+  arg_pInputDispatchMouseEventX
+  arg_pInputDispatchMouseEventY
+  = PInputDispatchMouseEvent
+    arg_pInputDispatchMouseEventType
+    arg_pInputDispatchMouseEventX
+    arg_pInputDispatchMouseEventY
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PInputDispatchMouseEvent where
+  toJSON p = A.object $ catMaybes [
+    ("type" A..=) <$> Just (pInputDispatchMouseEventType p),
+    ("x" A..=) <$> Just (pInputDispatchMouseEventX p),
+    ("y" A..=) <$> Just (pInputDispatchMouseEventY p),
+    ("modifiers" A..=) <$> (pInputDispatchMouseEventModifiers p),
+    ("timestamp" A..=) <$> (pInputDispatchMouseEventTimestamp p),
+    ("button" A..=) <$> (pInputDispatchMouseEventButton p),
+    ("buttons" A..=) <$> (pInputDispatchMouseEventButtons p),
+    ("clickCount" A..=) <$> (pInputDispatchMouseEventClickCount p),
+    ("force" A..=) <$> (pInputDispatchMouseEventForce p),
+    ("tangentialPressure" A..=) <$> (pInputDispatchMouseEventTangentialPressure p),
+    ("tiltX" A..=) <$> (pInputDispatchMouseEventTiltX p),
+    ("tiltY" A..=) <$> (pInputDispatchMouseEventTiltY p),
+    ("twist" A..=) <$> (pInputDispatchMouseEventTwist p),
+    ("deltaX" A..=) <$> (pInputDispatchMouseEventDeltaX p),
+    ("deltaY" A..=) <$> (pInputDispatchMouseEventDeltaY p),
+    ("pointerType" A..=) <$> (pInputDispatchMouseEventPointerType p)
+    ]
+instance Command PInputDispatchMouseEvent where
+  type CommandResponse PInputDispatchMouseEvent = ()
+  commandName _ = "Input.dispatchMouseEvent"
+  fromJSON = const . A.Success . const ()
+
+-- | Dispatches a touch event to the page.
+
+-- | Parameters of the 'Input.dispatchTouchEvent' command.
+data PInputDispatchTouchEventType = PInputDispatchTouchEventTypeTouchStart | PInputDispatchTouchEventTypeTouchEnd | PInputDispatchTouchEventTypeTouchMove | PInputDispatchTouchEventTypeTouchCancel
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PInputDispatchTouchEventType where
+  parseJSON = A.withText "PInputDispatchTouchEventType" $ \v -> case v of
+    "touchStart" -> pure PInputDispatchTouchEventTypeTouchStart
+    "touchEnd" -> pure PInputDispatchTouchEventTypeTouchEnd
+    "touchMove" -> pure PInputDispatchTouchEventTypeTouchMove
+    "touchCancel" -> pure PInputDispatchTouchEventTypeTouchCancel
+    "_" -> fail "failed to parse PInputDispatchTouchEventType"
+instance ToJSON PInputDispatchTouchEventType where
+  toJSON v = A.String $ case v of
+    PInputDispatchTouchEventTypeTouchStart -> "touchStart"
+    PInputDispatchTouchEventTypeTouchEnd -> "touchEnd"
+    PInputDispatchTouchEventTypeTouchMove -> "touchMove"
+    PInputDispatchTouchEventTypeTouchCancel -> "touchCancel"
+data PInputDispatchTouchEvent = PInputDispatchTouchEvent
+  {
+    -- | Type of the touch event. TouchEnd and TouchCancel must not contain any touch points, while
+    --   TouchStart and TouchMove must contains at least one.
+    pInputDispatchTouchEventType :: PInputDispatchTouchEventType,
+    -- | Active touch points on the touch device. One event per any changed point (compared to
+    --   previous touch event in a sequence) is generated, emulating pressing/moving/releasing points
+    --   one by one.
+    pInputDispatchTouchEventTouchPoints :: [InputTouchPoint],
+    -- | Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8
+    --   (default: 0).
+    pInputDispatchTouchEventModifiers :: Maybe Int,
+    -- | Time at which the event occurred.
+    pInputDispatchTouchEventTimestamp :: Maybe InputTimeSinceEpoch
+  }
+  deriving (Eq, Show)
+pInputDispatchTouchEvent
+  {-
+  -- | Type of the touch event. TouchEnd and TouchCancel must not contain any touch points, while
+  --   TouchStart and TouchMove must contains at least one.
+  -}
+  :: PInputDispatchTouchEventType
+  {-
+  -- | Active touch points on the touch device. One event per any changed point (compared to
+  --   previous touch event in a sequence) is generated, emulating pressing/moving/releasing points
+  --   one by one.
+  -}
+  -> [InputTouchPoint]
+  -> PInputDispatchTouchEvent
+pInputDispatchTouchEvent
+  arg_pInputDispatchTouchEventType
+  arg_pInputDispatchTouchEventTouchPoints
+  = PInputDispatchTouchEvent
+    arg_pInputDispatchTouchEventType
+    arg_pInputDispatchTouchEventTouchPoints
+    Nothing
+    Nothing
+instance ToJSON PInputDispatchTouchEvent where
+  toJSON p = A.object $ catMaybes [
+    ("type" A..=) <$> Just (pInputDispatchTouchEventType p),
+    ("touchPoints" A..=) <$> Just (pInputDispatchTouchEventTouchPoints p),
+    ("modifiers" A..=) <$> (pInputDispatchTouchEventModifiers p),
+    ("timestamp" A..=) <$> (pInputDispatchTouchEventTimestamp p)
+    ]
+instance Command PInputDispatchTouchEvent where
+  type CommandResponse PInputDispatchTouchEvent = ()
+  commandName _ = "Input.dispatchTouchEvent"
+  fromJSON = const . A.Success . const ()
+
+-- | Emulates touch event from the mouse event parameters.
+
+-- | Parameters of the 'Input.emulateTouchFromMouseEvent' command.
+data PInputEmulateTouchFromMouseEventType = PInputEmulateTouchFromMouseEventTypeMousePressed | PInputEmulateTouchFromMouseEventTypeMouseReleased | PInputEmulateTouchFromMouseEventTypeMouseMoved | PInputEmulateTouchFromMouseEventTypeMouseWheel
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PInputEmulateTouchFromMouseEventType where
+  parseJSON = A.withText "PInputEmulateTouchFromMouseEventType" $ \v -> case v of
+    "mousePressed" -> pure PInputEmulateTouchFromMouseEventTypeMousePressed
+    "mouseReleased" -> pure PInputEmulateTouchFromMouseEventTypeMouseReleased
+    "mouseMoved" -> pure PInputEmulateTouchFromMouseEventTypeMouseMoved
+    "mouseWheel" -> pure PInputEmulateTouchFromMouseEventTypeMouseWheel
+    "_" -> fail "failed to parse PInputEmulateTouchFromMouseEventType"
+instance ToJSON PInputEmulateTouchFromMouseEventType where
+  toJSON v = A.String $ case v of
+    PInputEmulateTouchFromMouseEventTypeMousePressed -> "mousePressed"
+    PInputEmulateTouchFromMouseEventTypeMouseReleased -> "mouseReleased"
+    PInputEmulateTouchFromMouseEventTypeMouseMoved -> "mouseMoved"
+    PInputEmulateTouchFromMouseEventTypeMouseWheel -> "mouseWheel"
+data PInputEmulateTouchFromMouseEvent = PInputEmulateTouchFromMouseEvent
+  {
+    -- | Type of the mouse event.
+    pInputEmulateTouchFromMouseEventType :: PInputEmulateTouchFromMouseEventType,
+    -- | X coordinate of the mouse pointer in DIP.
+    pInputEmulateTouchFromMouseEventX :: Int,
+    -- | Y coordinate of the mouse pointer in DIP.
+    pInputEmulateTouchFromMouseEventY :: Int,
+    -- | Mouse button. Only "none", "left", "right" are supported.
+    pInputEmulateTouchFromMouseEventButton :: InputMouseButton,
+    -- | Time at which the event occurred (default: current time).
+    pInputEmulateTouchFromMouseEventTimestamp :: Maybe InputTimeSinceEpoch,
+    -- | X delta in DIP for mouse wheel event (default: 0).
+    pInputEmulateTouchFromMouseEventDeltaX :: Maybe Double,
+    -- | Y delta in DIP for mouse wheel event (default: 0).
+    pInputEmulateTouchFromMouseEventDeltaY :: Maybe Double,
+    -- | Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8
+    --   (default: 0).
+    pInputEmulateTouchFromMouseEventModifiers :: Maybe Int,
+    -- | Number of times the mouse button was clicked (default: 0).
+    pInputEmulateTouchFromMouseEventClickCount :: Maybe Int
+  }
+  deriving (Eq, Show)
+pInputEmulateTouchFromMouseEvent
+  {-
+  -- | Type of the mouse event.
+  -}
+  :: PInputEmulateTouchFromMouseEventType
+  {-
+  -- | X coordinate of the mouse pointer in DIP.
+  -}
+  -> Int
+  {-
+  -- | Y coordinate of the mouse pointer in DIP.
+  -}
+  -> Int
+  {-
+  -- | Mouse button. Only "none", "left", "right" are supported.
+  -}
+  -> InputMouseButton
+  -> PInputEmulateTouchFromMouseEvent
+pInputEmulateTouchFromMouseEvent
+  arg_pInputEmulateTouchFromMouseEventType
+  arg_pInputEmulateTouchFromMouseEventX
+  arg_pInputEmulateTouchFromMouseEventY
+  arg_pInputEmulateTouchFromMouseEventButton
+  = PInputEmulateTouchFromMouseEvent
+    arg_pInputEmulateTouchFromMouseEventType
+    arg_pInputEmulateTouchFromMouseEventX
+    arg_pInputEmulateTouchFromMouseEventY
+    arg_pInputEmulateTouchFromMouseEventButton
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PInputEmulateTouchFromMouseEvent where
+  toJSON p = A.object $ catMaybes [
+    ("type" A..=) <$> Just (pInputEmulateTouchFromMouseEventType p),
+    ("x" A..=) <$> Just (pInputEmulateTouchFromMouseEventX p),
+    ("y" A..=) <$> Just (pInputEmulateTouchFromMouseEventY p),
+    ("button" A..=) <$> Just (pInputEmulateTouchFromMouseEventButton p),
+    ("timestamp" A..=) <$> (pInputEmulateTouchFromMouseEventTimestamp p),
+    ("deltaX" A..=) <$> (pInputEmulateTouchFromMouseEventDeltaX p),
+    ("deltaY" A..=) <$> (pInputEmulateTouchFromMouseEventDeltaY p),
+    ("modifiers" A..=) <$> (pInputEmulateTouchFromMouseEventModifiers p),
+    ("clickCount" A..=) <$> (pInputEmulateTouchFromMouseEventClickCount p)
+    ]
+instance Command PInputEmulateTouchFromMouseEvent where
+  type CommandResponse PInputEmulateTouchFromMouseEvent = ()
+  commandName _ = "Input.emulateTouchFromMouseEvent"
+  fromJSON = const . A.Success . const ()
+
+-- | Ignores input events (useful while auditing page).
+
+-- | Parameters of the 'Input.setIgnoreInputEvents' command.
+data PInputSetIgnoreInputEvents = PInputSetIgnoreInputEvents
+  {
+    -- | Ignores input events processing when set to true.
+    pInputSetIgnoreInputEventsIgnore :: Bool
+  }
+  deriving (Eq, Show)
+pInputSetIgnoreInputEvents
+  {-
+  -- | Ignores input events processing when set to true.
+  -}
+  :: Bool
+  -> PInputSetIgnoreInputEvents
+pInputSetIgnoreInputEvents
+  arg_pInputSetIgnoreInputEventsIgnore
+  = PInputSetIgnoreInputEvents
+    arg_pInputSetIgnoreInputEventsIgnore
+instance ToJSON PInputSetIgnoreInputEvents where
+  toJSON p = A.object $ catMaybes [
+    ("ignore" A..=) <$> Just (pInputSetIgnoreInputEventsIgnore p)
+    ]
+instance Command PInputSetIgnoreInputEvents where
+  type CommandResponse PInputSetIgnoreInputEvents = ()
+  commandName _ = "Input.setIgnoreInputEvents"
+  fromJSON = const . A.Success . const ()
+
+-- | Prevents default drag and drop behavior and instead emits `Input.dragIntercepted` events.
+--   Drag and drop behavior can be directly controlled via `Input.dispatchDragEvent`.
+
+-- | Parameters of the 'Input.setInterceptDrags' command.
+data PInputSetInterceptDrags = PInputSetInterceptDrags
+  {
+    pInputSetInterceptDragsEnabled :: Bool
+  }
+  deriving (Eq, Show)
+pInputSetInterceptDrags
+  :: Bool
+  -> PInputSetInterceptDrags
+pInputSetInterceptDrags
+  arg_pInputSetInterceptDragsEnabled
+  = PInputSetInterceptDrags
+    arg_pInputSetInterceptDragsEnabled
+instance ToJSON PInputSetInterceptDrags where
+  toJSON p = A.object $ catMaybes [
+    ("enabled" A..=) <$> Just (pInputSetInterceptDragsEnabled p)
+    ]
+instance Command PInputSetInterceptDrags where
+  type CommandResponse PInputSetInterceptDrags = ()
+  commandName _ = "Input.setInterceptDrags"
+  fromJSON = const . A.Success . const ()
+
+-- | Synthesizes a pinch gesture over a time period by issuing appropriate touch events.
+
+-- | Parameters of the 'Input.synthesizePinchGesture' command.
+data PInputSynthesizePinchGesture = PInputSynthesizePinchGesture
+  {
+    -- | X coordinate of the start of the gesture in CSS pixels.
+    pInputSynthesizePinchGestureX :: Double,
+    -- | Y coordinate of the start of the gesture in CSS pixels.
+    pInputSynthesizePinchGestureY :: Double,
+    -- | Relative scale factor after zooming (>1.0 zooms in, <1.0 zooms out).
+    pInputSynthesizePinchGestureScaleFactor :: Double,
+    -- | Relative pointer speed in pixels per second (default: 800).
+    pInputSynthesizePinchGestureRelativeSpeed :: Maybe Int,
+    -- | Which type of input events to be generated (default: 'default', which queries the platform
+    --   for the preferred input type).
+    pInputSynthesizePinchGestureGestureSourceType :: Maybe InputGestureSourceType
+  }
+  deriving (Eq, Show)
+pInputSynthesizePinchGesture
+  {-
+  -- | X coordinate of the start of the gesture in CSS pixels.
+  -}
+  :: Double
+  {-
+  -- | Y coordinate of the start of the gesture in CSS pixels.
+  -}
+  -> Double
+  {-
+  -- | Relative scale factor after zooming (>1.0 zooms in, <1.0 zooms out).
+  -}
+  -> Double
+  -> PInputSynthesizePinchGesture
+pInputSynthesizePinchGesture
+  arg_pInputSynthesizePinchGestureX
+  arg_pInputSynthesizePinchGestureY
+  arg_pInputSynthesizePinchGestureScaleFactor
+  = PInputSynthesizePinchGesture
+    arg_pInputSynthesizePinchGestureX
+    arg_pInputSynthesizePinchGestureY
+    arg_pInputSynthesizePinchGestureScaleFactor
+    Nothing
+    Nothing
+instance ToJSON PInputSynthesizePinchGesture where
+  toJSON p = A.object $ catMaybes [
+    ("x" A..=) <$> Just (pInputSynthesizePinchGestureX p),
+    ("y" A..=) <$> Just (pInputSynthesizePinchGestureY p),
+    ("scaleFactor" A..=) <$> Just (pInputSynthesizePinchGestureScaleFactor p),
+    ("relativeSpeed" A..=) <$> (pInputSynthesizePinchGestureRelativeSpeed p),
+    ("gestureSourceType" A..=) <$> (pInputSynthesizePinchGestureGestureSourceType p)
+    ]
+instance Command PInputSynthesizePinchGesture where
+  type CommandResponse PInputSynthesizePinchGesture = ()
+  commandName _ = "Input.synthesizePinchGesture"
+  fromJSON = const . A.Success . const ()
+
+-- | Synthesizes a scroll gesture over a time period by issuing appropriate touch events.
+
+-- | Parameters of the 'Input.synthesizeScrollGesture' command.
+data PInputSynthesizeScrollGesture = PInputSynthesizeScrollGesture
+  {
+    -- | X coordinate of the start of the gesture in CSS pixels.
+    pInputSynthesizeScrollGestureX :: Double,
+    -- | Y coordinate of the start of the gesture in CSS pixels.
+    pInputSynthesizeScrollGestureY :: Double,
+    -- | The distance to scroll along the X axis (positive to scroll left).
+    pInputSynthesizeScrollGestureXDistance :: Maybe Double,
+    -- | The distance to scroll along the Y axis (positive to scroll up).
+    pInputSynthesizeScrollGestureYDistance :: Maybe Double,
+    -- | The number of additional pixels to scroll back along the X axis, in addition to the given
+    --   distance.
+    pInputSynthesizeScrollGestureXOverscroll :: Maybe Double,
+    -- | The number of additional pixels to scroll back along the Y axis, in addition to the given
+    --   distance.
+    pInputSynthesizeScrollGestureYOverscroll :: Maybe Double,
+    -- | Prevent fling (default: true).
+    pInputSynthesizeScrollGesturePreventFling :: Maybe Bool,
+    -- | Swipe speed in pixels per second (default: 800).
+    pInputSynthesizeScrollGestureSpeed :: Maybe Int,
+    -- | Which type of input events to be generated (default: 'default', which queries the platform
+    --   for the preferred input type).
+    pInputSynthesizeScrollGestureGestureSourceType :: Maybe InputGestureSourceType,
+    -- | The number of times to repeat the gesture (default: 0).
+    pInputSynthesizeScrollGestureRepeatCount :: Maybe Int,
+    -- | The number of milliseconds delay between each repeat. (default: 250).
+    pInputSynthesizeScrollGestureRepeatDelayMs :: Maybe Int,
+    -- | The name of the interaction markers to generate, if not empty (default: "").
+    pInputSynthesizeScrollGestureInteractionMarkerName :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+pInputSynthesizeScrollGesture
+  {-
+  -- | X coordinate of the start of the gesture in CSS pixels.
+  -}
+  :: Double
+  {-
+  -- | Y coordinate of the start of the gesture in CSS pixels.
+  -}
+  -> Double
+  -> PInputSynthesizeScrollGesture
+pInputSynthesizeScrollGesture
+  arg_pInputSynthesizeScrollGestureX
+  arg_pInputSynthesizeScrollGestureY
+  = PInputSynthesizeScrollGesture
+    arg_pInputSynthesizeScrollGestureX
+    arg_pInputSynthesizeScrollGestureY
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PInputSynthesizeScrollGesture where
+  toJSON p = A.object $ catMaybes [
+    ("x" A..=) <$> Just (pInputSynthesizeScrollGestureX p),
+    ("y" A..=) <$> Just (pInputSynthesizeScrollGestureY p),
+    ("xDistance" A..=) <$> (pInputSynthesizeScrollGestureXDistance p),
+    ("yDistance" A..=) <$> (pInputSynthesizeScrollGestureYDistance p),
+    ("xOverscroll" A..=) <$> (pInputSynthesizeScrollGestureXOverscroll p),
+    ("yOverscroll" A..=) <$> (pInputSynthesizeScrollGestureYOverscroll p),
+    ("preventFling" A..=) <$> (pInputSynthesizeScrollGesturePreventFling p),
+    ("speed" A..=) <$> (pInputSynthesizeScrollGestureSpeed p),
+    ("gestureSourceType" A..=) <$> (pInputSynthesizeScrollGestureGestureSourceType p),
+    ("repeatCount" A..=) <$> (pInputSynthesizeScrollGestureRepeatCount p),
+    ("repeatDelayMs" A..=) <$> (pInputSynthesizeScrollGestureRepeatDelayMs p),
+    ("interactionMarkerName" A..=) <$> (pInputSynthesizeScrollGestureInteractionMarkerName p)
+    ]
+instance Command PInputSynthesizeScrollGesture where
+  type CommandResponse PInputSynthesizeScrollGesture = ()
+  commandName _ = "Input.synthesizeScrollGesture"
+  fromJSON = const . A.Success . const ()
+
+-- | Synthesizes a tap gesture over a time period by issuing appropriate touch events.
+
+-- | Parameters of the 'Input.synthesizeTapGesture' command.
+data PInputSynthesizeTapGesture = PInputSynthesizeTapGesture
+  {
+    -- | X coordinate of the start of the gesture in CSS pixels.
+    pInputSynthesizeTapGestureX :: Double,
+    -- | Y coordinate of the start of the gesture in CSS pixels.
+    pInputSynthesizeTapGestureY :: Double,
+    -- | Duration between touchdown and touchup events in ms (default: 50).
+    pInputSynthesizeTapGestureDuration :: Maybe Int,
+    -- | Number of times to perform the tap (e.g. 2 for double tap, default: 1).
+    pInputSynthesizeTapGestureTapCount :: Maybe Int,
+    -- | Which type of input events to be generated (default: 'default', which queries the platform
+    --   for the preferred input type).
+    pInputSynthesizeTapGestureGestureSourceType :: Maybe InputGestureSourceType
+  }
+  deriving (Eq, Show)
+pInputSynthesizeTapGesture
+  {-
+  -- | X coordinate of the start of the gesture in CSS pixels.
+  -}
+  :: Double
+  {-
+  -- | Y coordinate of the start of the gesture in CSS pixels.
+  -}
+  -> Double
+  -> PInputSynthesizeTapGesture
+pInputSynthesizeTapGesture
+  arg_pInputSynthesizeTapGestureX
+  arg_pInputSynthesizeTapGestureY
+  = PInputSynthesizeTapGesture
+    arg_pInputSynthesizeTapGestureX
+    arg_pInputSynthesizeTapGestureY
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PInputSynthesizeTapGesture where
+  toJSON p = A.object $ catMaybes [
+    ("x" A..=) <$> Just (pInputSynthesizeTapGestureX p),
+    ("y" A..=) <$> Just (pInputSynthesizeTapGestureY p),
+    ("duration" A..=) <$> (pInputSynthesizeTapGestureDuration p),
+    ("tapCount" A..=) <$> (pInputSynthesizeTapGestureTapCount p),
+    ("gestureSourceType" A..=) <$> (pInputSynthesizeTapGestureGestureSourceType p)
+    ]
+instance Command PInputSynthesizeTapGesture where
+  type CommandResponse PInputSynthesizeTapGesture = ()
+  commandName _ = "Input.synthesizeTapGesture"
+  fromJSON = const . A.Success . const ()
+
diff --git a/src/CDP/Domains/Inspector.hs b/src/CDP/Domains/Inspector.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains/Inspector.hs
@@ -0,0 +1,110 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+
+
+{- |
+= Inspector
+
+-}
+
+
+module CDP.Domains.Inspector (module CDP.Domains.Inspector) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+
+
+
+-- | Type of the 'Inspector.detached' event.
+data InspectorDetached = InspectorDetached
+  {
+    -- | The reason why connection has been terminated.
+    inspectorDetachedReason :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON InspectorDetached where
+  parseJSON = A.withObject "InspectorDetached" $ \o -> InspectorDetached
+    <$> o A..: "reason"
+instance Event InspectorDetached where
+  eventName _ = "Inspector.detached"
+
+-- | Type of the 'Inspector.targetCrashed' event.
+data InspectorTargetCrashed = InspectorTargetCrashed
+  deriving (Eq, Show, Read)
+instance FromJSON InspectorTargetCrashed where
+  parseJSON _ = pure InspectorTargetCrashed
+instance Event InspectorTargetCrashed where
+  eventName _ = "Inspector.targetCrashed"
+
+-- | Type of the 'Inspector.targetReloadedAfterCrash' event.
+data InspectorTargetReloadedAfterCrash = InspectorTargetReloadedAfterCrash
+  deriving (Eq, Show, Read)
+instance FromJSON InspectorTargetReloadedAfterCrash where
+  parseJSON _ = pure InspectorTargetReloadedAfterCrash
+instance Event InspectorTargetReloadedAfterCrash where
+  eventName _ = "Inspector.targetReloadedAfterCrash"
+
+-- | Disables inspector domain notifications.
+
+-- | Parameters of the 'Inspector.disable' command.
+data PInspectorDisable = PInspectorDisable
+  deriving (Eq, Show)
+pInspectorDisable
+  :: PInspectorDisable
+pInspectorDisable
+  = PInspectorDisable
+instance ToJSON PInspectorDisable where
+  toJSON _ = A.Null
+instance Command PInspectorDisable where
+  type CommandResponse PInspectorDisable = ()
+  commandName _ = "Inspector.disable"
+  fromJSON = const . A.Success . const ()
+
+-- | Enables inspector domain notifications.
+
+-- | Parameters of the 'Inspector.enable' command.
+data PInspectorEnable = PInspectorEnable
+  deriving (Eq, Show)
+pInspectorEnable
+  :: PInspectorEnable
+pInspectorEnable
+  = PInspectorEnable
+instance ToJSON PInspectorEnable where
+  toJSON _ = A.Null
+instance Command PInspectorEnable where
+  type CommandResponse PInspectorEnable = ()
+  commandName _ = "Inspector.enable"
+  fromJSON = const . A.Success . const ()
+
diff --git a/src/CDP/Domains/LayerTree.hs b/src/CDP/Domains/LayerTree.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains/LayerTree.hs
@@ -0,0 +1,552 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+
+
+{- |
+= LayerTree
+
+-}
+
+
+module CDP.Domains.LayerTree (module CDP.Domains.LayerTree) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+
+import CDP.Domains.DOMPageNetworkEmulationSecurity as DOMPageNetworkEmulationSecurity
+
+
+-- | Type 'LayerTree.LayerId'.
+--   Unique Layer identifier.
+type LayerTreeLayerId = T.Text
+
+-- | Type 'LayerTree.SnapshotId'.
+--   Unique snapshot identifier.
+type LayerTreeSnapshotId = T.Text
+
+-- | Type 'LayerTree.ScrollRect'.
+--   Rectangle where scrolling happens on the main thread.
+data LayerTreeScrollRectType = LayerTreeScrollRectTypeRepaintsOnScroll | LayerTreeScrollRectTypeTouchEventHandler | LayerTreeScrollRectTypeWheelEventHandler
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON LayerTreeScrollRectType where
+  parseJSON = A.withText "LayerTreeScrollRectType" $ \v -> case v of
+    "RepaintsOnScroll" -> pure LayerTreeScrollRectTypeRepaintsOnScroll
+    "TouchEventHandler" -> pure LayerTreeScrollRectTypeTouchEventHandler
+    "WheelEventHandler" -> pure LayerTreeScrollRectTypeWheelEventHandler
+    "_" -> fail "failed to parse LayerTreeScrollRectType"
+instance ToJSON LayerTreeScrollRectType where
+  toJSON v = A.String $ case v of
+    LayerTreeScrollRectTypeRepaintsOnScroll -> "RepaintsOnScroll"
+    LayerTreeScrollRectTypeTouchEventHandler -> "TouchEventHandler"
+    LayerTreeScrollRectTypeWheelEventHandler -> "WheelEventHandler"
+data LayerTreeScrollRect = LayerTreeScrollRect
+  {
+    -- | Rectangle itself.
+    layerTreeScrollRectRect :: DOMPageNetworkEmulationSecurity.DOMRect,
+    -- | Reason for rectangle to force scrolling on the main thread
+    layerTreeScrollRectType :: LayerTreeScrollRectType
+  }
+  deriving (Eq, Show)
+instance FromJSON LayerTreeScrollRect where
+  parseJSON = A.withObject "LayerTreeScrollRect" $ \o -> LayerTreeScrollRect
+    <$> o A..: "rect"
+    <*> o A..: "type"
+instance ToJSON LayerTreeScrollRect where
+  toJSON p = A.object $ catMaybes [
+    ("rect" A..=) <$> Just (layerTreeScrollRectRect p),
+    ("type" A..=) <$> Just (layerTreeScrollRectType p)
+    ]
+
+-- | Type 'LayerTree.StickyPositionConstraint'.
+--   Sticky position constraints.
+data LayerTreeStickyPositionConstraint = LayerTreeStickyPositionConstraint
+  {
+    -- | Layout rectangle of the sticky element before being shifted
+    layerTreeStickyPositionConstraintStickyBoxRect :: DOMPageNetworkEmulationSecurity.DOMRect,
+    -- | Layout rectangle of the containing block of the sticky element
+    layerTreeStickyPositionConstraintContainingBlockRect :: DOMPageNetworkEmulationSecurity.DOMRect,
+    -- | The nearest sticky layer that shifts the sticky box
+    layerTreeStickyPositionConstraintNearestLayerShiftingStickyBox :: Maybe LayerTreeLayerId,
+    -- | The nearest sticky layer that shifts the containing block
+    layerTreeStickyPositionConstraintNearestLayerShiftingContainingBlock :: Maybe LayerTreeLayerId
+  }
+  deriving (Eq, Show)
+instance FromJSON LayerTreeStickyPositionConstraint where
+  parseJSON = A.withObject "LayerTreeStickyPositionConstraint" $ \o -> LayerTreeStickyPositionConstraint
+    <$> o A..: "stickyBoxRect"
+    <*> o A..: "containingBlockRect"
+    <*> o A..:? "nearestLayerShiftingStickyBox"
+    <*> o A..:? "nearestLayerShiftingContainingBlock"
+instance ToJSON LayerTreeStickyPositionConstraint where
+  toJSON p = A.object $ catMaybes [
+    ("stickyBoxRect" A..=) <$> Just (layerTreeStickyPositionConstraintStickyBoxRect p),
+    ("containingBlockRect" A..=) <$> Just (layerTreeStickyPositionConstraintContainingBlockRect p),
+    ("nearestLayerShiftingStickyBox" A..=) <$> (layerTreeStickyPositionConstraintNearestLayerShiftingStickyBox p),
+    ("nearestLayerShiftingContainingBlock" A..=) <$> (layerTreeStickyPositionConstraintNearestLayerShiftingContainingBlock p)
+    ]
+
+-- | Type 'LayerTree.PictureTile'.
+--   Serialized fragment of layer picture along with its offset within the layer.
+data LayerTreePictureTile = LayerTreePictureTile
+  {
+    -- | Offset from owning layer left boundary
+    layerTreePictureTileX :: Double,
+    -- | Offset from owning layer top boundary
+    layerTreePictureTileY :: Double,
+    -- | Base64-encoded snapshot data. (Encoded as a base64 string when passed over JSON)
+    layerTreePictureTilePicture :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON LayerTreePictureTile where
+  parseJSON = A.withObject "LayerTreePictureTile" $ \o -> LayerTreePictureTile
+    <$> o A..: "x"
+    <*> o A..: "y"
+    <*> o A..: "picture"
+instance ToJSON LayerTreePictureTile where
+  toJSON p = A.object $ catMaybes [
+    ("x" A..=) <$> Just (layerTreePictureTileX p),
+    ("y" A..=) <$> Just (layerTreePictureTileY p),
+    ("picture" A..=) <$> Just (layerTreePictureTilePicture p)
+    ]
+
+-- | Type 'LayerTree.Layer'.
+--   Information about a compositing layer.
+data LayerTreeLayer = LayerTreeLayer
+  {
+    -- | The unique id for this layer.
+    layerTreeLayerLayerId :: LayerTreeLayerId,
+    -- | The id of parent (not present for root).
+    layerTreeLayerParentLayerId :: Maybe LayerTreeLayerId,
+    -- | The backend id for the node associated with this layer.
+    layerTreeLayerBackendNodeId :: Maybe DOMPageNetworkEmulationSecurity.DOMBackendNodeId,
+    -- | Offset from parent layer, X coordinate.
+    layerTreeLayerOffsetX :: Double,
+    -- | Offset from parent layer, Y coordinate.
+    layerTreeLayerOffsetY :: Double,
+    -- | Layer width.
+    layerTreeLayerWidth :: Double,
+    -- | Layer height.
+    layerTreeLayerHeight :: Double,
+    -- | Transformation matrix for layer, default is identity matrix
+    layerTreeLayerTransform :: Maybe [Double],
+    -- | Transform anchor point X, absent if no transform specified
+    layerTreeLayerAnchorX :: Maybe Double,
+    -- | Transform anchor point Y, absent if no transform specified
+    layerTreeLayerAnchorY :: Maybe Double,
+    -- | Transform anchor point Z, absent if no transform specified
+    layerTreeLayerAnchorZ :: Maybe Double,
+    -- | Indicates how many time this layer has painted.
+    layerTreeLayerPaintCount :: Int,
+    -- | Indicates whether this layer hosts any content, rather than being used for
+    --   transform/scrolling purposes only.
+    layerTreeLayerDrawsContent :: Bool,
+    -- | Set if layer is not visible.
+    layerTreeLayerInvisible :: Maybe Bool,
+    -- | Rectangles scrolling on main thread only.
+    layerTreeLayerScrollRects :: Maybe [LayerTreeScrollRect],
+    -- | Sticky position constraint information
+    layerTreeLayerStickyPositionConstraint :: Maybe LayerTreeStickyPositionConstraint
+  }
+  deriving (Eq, Show)
+instance FromJSON LayerTreeLayer where
+  parseJSON = A.withObject "LayerTreeLayer" $ \o -> LayerTreeLayer
+    <$> o A..: "layerId"
+    <*> o A..:? "parentLayerId"
+    <*> o A..:? "backendNodeId"
+    <*> o A..: "offsetX"
+    <*> o A..: "offsetY"
+    <*> o A..: "width"
+    <*> o A..: "height"
+    <*> o A..:? "transform"
+    <*> o A..:? "anchorX"
+    <*> o A..:? "anchorY"
+    <*> o A..:? "anchorZ"
+    <*> o A..: "paintCount"
+    <*> o A..: "drawsContent"
+    <*> o A..:? "invisible"
+    <*> o A..:? "scrollRects"
+    <*> o A..:? "stickyPositionConstraint"
+instance ToJSON LayerTreeLayer where
+  toJSON p = A.object $ catMaybes [
+    ("layerId" A..=) <$> Just (layerTreeLayerLayerId p),
+    ("parentLayerId" A..=) <$> (layerTreeLayerParentLayerId p),
+    ("backendNodeId" A..=) <$> (layerTreeLayerBackendNodeId p),
+    ("offsetX" A..=) <$> Just (layerTreeLayerOffsetX p),
+    ("offsetY" A..=) <$> Just (layerTreeLayerOffsetY p),
+    ("width" A..=) <$> Just (layerTreeLayerWidth p),
+    ("height" A..=) <$> Just (layerTreeLayerHeight p),
+    ("transform" A..=) <$> (layerTreeLayerTransform p),
+    ("anchorX" A..=) <$> (layerTreeLayerAnchorX p),
+    ("anchorY" A..=) <$> (layerTreeLayerAnchorY p),
+    ("anchorZ" A..=) <$> (layerTreeLayerAnchorZ p),
+    ("paintCount" A..=) <$> Just (layerTreeLayerPaintCount p),
+    ("drawsContent" A..=) <$> Just (layerTreeLayerDrawsContent p),
+    ("invisible" A..=) <$> (layerTreeLayerInvisible p),
+    ("scrollRects" A..=) <$> (layerTreeLayerScrollRects p),
+    ("stickyPositionConstraint" A..=) <$> (layerTreeLayerStickyPositionConstraint p)
+    ]
+
+-- | Type 'LayerTree.PaintProfile'.
+--   Array of timings, one per paint step.
+type LayerTreePaintProfile = [Double]
+
+-- | Type of the 'LayerTree.layerPainted' event.
+data LayerTreeLayerPainted = LayerTreeLayerPainted
+  {
+    -- | The id of the painted layer.
+    layerTreeLayerPaintedLayerId :: LayerTreeLayerId,
+    -- | Clip rectangle.
+    layerTreeLayerPaintedClip :: DOMPageNetworkEmulationSecurity.DOMRect
+  }
+  deriving (Eq, Show)
+instance FromJSON LayerTreeLayerPainted where
+  parseJSON = A.withObject "LayerTreeLayerPainted" $ \o -> LayerTreeLayerPainted
+    <$> o A..: "layerId"
+    <*> o A..: "clip"
+instance Event LayerTreeLayerPainted where
+  eventName _ = "LayerTree.layerPainted"
+
+-- | Type of the 'LayerTree.layerTreeDidChange' event.
+data LayerTreeLayerTreeDidChange = LayerTreeLayerTreeDidChange
+  {
+    -- | Layer tree, absent if not in the comspositing mode.
+    layerTreeLayerTreeDidChangeLayers :: Maybe [LayerTreeLayer]
+  }
+  deriving (Eq, Show)
+instance FromJSON LayerTreeLayerTreeDidChange where
+  parseJSON = A.withObject "LayerTreeLayerTreeDidChange" $ \o -> LayerTreeLayerTreeDidChange
+    <$> o A..:? "layers"
+instance Event LayerTreeLayerTreeDidChange where
+  eventName _ = "LayerTree.layerTreeDidChange"
+
+-- | Provides the reasons why the given layer was composited.
+
+-- | Parameters of the 'LayerTree.compositingReasons' command.
+data PLayerTreeCompositingReasons = PLayerTreeCompositingReasons
+  {
+    -- | The id of the layer for which we want to get the reasons it was composited.
+    pLayerTreeCompositingReasonsLayerId :: LayerTreeLayerId
+  }
+  deriving (Eq, Show)
+pLayerTreeCompositingReasons
+  {-
+  -- | The id of the layer for which we want to get the reasons it was composited.
+  -}
+  :: LayerTreeLayerId
+  -> PLayerTreeCompositingReasons
+pLayerTreeCompositingReasons
+  arg_pLayerTreeCompositingReasonsLayerId
+  = PLayerTreeCompositingReasons
+    arg_pLayerTreeCompositingReasonsLayerId
+instance ToJSON PLayerTreeCompositingReasons where
+  toJSON p = A.object $ catMaybes [
+    ("layerId" A..=) <$> Just (pLayerTreeCompositingReasonsLayerId p)
+    ]
+data LayerTreeCompositingReasons = LayerTreeCompositingReasons
+  {
+    -- | A list of strings specifying reason IDs for the given layer to become composited.
+    layerTreeCompositingReasonsCompositingReasonIds :: [T.Text]
+  }
+  deriving (Eq, Show)
+instance FromJSON LayerTreeCompositingReasons where
+  parseJSON = A.withObject "LayerTreeCompositingReasons" $ \o -> LayerTreeCompositingReasons
+    <$> o A..: "compositingReasonIds"
+instance Command PLayerTreeCompositingReasons where
+  type CommandResponse PLayerTreeCompositingReasons = LayerTreeCompositingReasons
+  commandName _ = "LayerTree.compositingReasons"
+
+-- | Disables compositing tree inspection.
+
+-- | Parameters of the 'LayerTree.disable' command.
+data PLayerTreeDisable = PLayerTreeDisable
+  deriving (Eq, Show)
+pLayerTreeDisable
+  :: PLayerTreeDisable
+pLayerTreeDisable
+  = PLayerTreeDisable
+instance ToJSON PLayerTreeDisable where
+  toJSON _ = A.Null
+instance Command PLayerTreeDisable where
+  type CommandResponse PLayerTreeDisable = ()
+  commandName _ = "LayerTree.disable"
+  fromJSON = const . A.Success . const ()
+
+-- | Enables compositing tree inspection.
+
+-- | Parameters of the 'LayerTree.enable' command.
+data PLayerTreeEnable = PLayerTreeEnable
+  deriving (Eq, Show)
+pLayerTreeEnable
+  :: PLayerTreeEnable
+pLayerTreeEnable
+  = PLayerTreeEnable
+instance ToJSON PLayerTreeEnable where
+  toJSON _ = A.Null
+instance Command PLayerTreeEnable where
+  type CommandResponse PLayerTreeEnable = ()
+  commandName _ = "LayerTree.enable"
+  fromJSON = const . A.Success . const ()
+
+-- | Returns the snapshot identifier.
+
+-- | Parameters of the 'LayerTree.loadSnapshot' command.
+data PLayerTreeLoadSnapshot = PLayerTreeLoadSnapshot
+  {
+    -- | An array of tiles composing the snapshot.
+    pLayerTreeLoadSnapshotTiles :: [LayerTreePictureTile]
+  }
+  deriving (Eq, Show)
+pLayerTreeLoadSnapshot
+  {-
+  -- | An array of tiles composing the snapshot.
+  -}
+  :: [LayerTreePictureTile]
+  -> PLayerTreeLoadSnapshot
+pLayerTreeLoadSnapshot
+  arg_pLayerTreeLoadSnapshotTiles
+  = PLayerTreeLoadSnapshot
+    arg_pLayerTreeLoadSnapshotTiles
+instance ToJSON PLayerTreeLoadSnapshot where
+  toJSON p = A.object $ catMaybes [
+    ("tiles" A..=) <$> Just (pLayerTreeLoadSnapshotTiles p)
+    ]
+data LayerTreeLoadSnapshot = LayerTreeLoadSnapshot
+  {
+    -- | The id of the snapshot.
+    layerTreeLoadSnapshotSnapshotId :: LayerTreeSnapshotId
+  }
+  deriving (Eq, Show)
+instance FromJSON LayerTreeLoadSnapshot where
+  parseJSON = A.withObject "LayerTreeLoadSnapshot" $ \o -> LayerTreeLoadSnapshot
+    <$> o A..: "snapshotId"
+instance Command PLayerTreeLoadSnapshot where
+  type CommandResponse PLayerTreeLoadSnapshot = LayerTreeLoadSnapshot
+  commandName _ = "LayerTree.loadSnapshot"
+
+-- | Returns the layer snapshot identifier.
+
+-- | Parameters of the 'LayerTree.makeSnapshot' command.
+data PLayerTreeMakeSnapshot = PLayerTreeMakeSnapshot
+  {
+    -- | The id of the layer.
+    pLayerTreeMakeSnapshotLayerId :: LayerTreeLayerId
+  }
+  deriving (Eq, Show)
+pLayerTreeMakeSnapshot
+  {-
+  -- | The id of the layer.
+  -}
+  :: LayerTreeLayerId
+  -> PLayerTreeMakeSnapshot
+pLayerTreeMakeSnapshot
+  arg_pLayerTreeMakeSnapshotLayerId
+  = PLayerTreeMakeSnapshot
+    arg_pLayerTreeMakeSnapshotLayerId
+instance ToJSON PLayerTreeMakeSnapshot where
+  toJSON p = A.object $ catMaybes [
+    ("layerId" A..=) <$> Just (pLayerTreeMakeSnapshotLayerId p)
+    ]
+data LayerTreeMakeSnapshot = LayerTreeMakeSnapshot
+  {
+    -- | The id of the layer snapshot.
+    layerTreeMakeSnapshotSnapshotId :: LayerTreeSnapshotId
+  }
+  deriving (Eq, Show)
+instance FromJSON LayerTreeMakeSnapshot where
+  parseJSON = A.withObject "LayerTreeMakeSnapshot" $ \o -> LayerTreeMakeSnapshot
+    <$> o A..: "snapshotId"
+instance Command PLayerTreeMakeSnapshot where
+  type CommandResponse PLayerTreeMakeSnapshot = LayerTreeMakeSnapshot
+  commandName _ = "LayerTree.makeSnapshot"
+
+
+-- | Parameters of the 'LayerTree.profileSnapshot' command.
+data PLayerTreeProfileSnapshot = PLayerTreeProfileSnapshot
+  {
+    -- | The id of the layer snapshot.
+    pLayerTreeProfileSnapshotSnapshotId :: LayerTreeSnapshotId,
+    -- | The maximum number of times to replay the snapshot (1, if not specified).
+    pLayerTreeProfileSnapshotMinRepeatCount :: Maybe Int,
+    -- | The minimum duration (in seconds) to replay the snapshot.
+    pLayerTreeProfileSnapshotMinDuration :: Maybe Double,
+    -- | The clip rectangle to apply when replaying the snapshot.
+    pLayerTreeProfileSnapshotClipRect :: Maybe DOMPageNetworkEmulationSecurity.DOMRect
+  }
+  deriving (Eq, Show)
+pLayerTreeProfileSnapshot
+  {-
+  -- | The id of the layer snapshot.
+  -}
+  :: LayerTreeSnapshotId
+  -> PLayerTreeProfileSnapshot
+pLayerTreeProfileSnapshot
+  arg_pLayerTreeProfileSnapshotSnapshotId
+  = PLayerTreeProfileSnapshot
+    arg_pLayerTreeProfileSnapshotSnapshotId
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PLayerTreeProfileSnapshot where
+  toJSON p = A.object $ catMaybes [
+    ("snapshotId" A..=) <$> Just (pLayerTreeProfileSnapshotSnapshotId p),
+    ("minRepeatCount" A..=) <$> (pLayerTreeProfileSnapshotMinRepeatCount p),
+    ("minDuration" A..=) <$> (pLayerTreeProfileSnapshotMinDuration p),
+    ("clipRect" A..=) <$> (pLayerTreeProfileSnapshotClipRect p)
+    ]
+data LayerTreeProfileSnapshot = LayerTreeProfileSnapshot
+  {
+    -- | The array of paint profiles, one per run.
+    layerTreeProfileSnapshotTimings :: [LayerTreePaintProfile]
+  }
+  deriving (Eq, Show)
+instance FromJSON LayerTreeProfileSnapshot where
+  parseJSON = A.withObject "LayerTreeProfileSnapshot" $ \o -> LayerTreeProfileSnapshot
+    <$> o A..: "timings"
+instance Command PLayerTreeProfileSnapshot where
+  type CommandResponse PLayerTreeProfileSnapshot = LayerTreeProfileSnapshot
+  commandName _ = "LayerTree.profileSnapshot"
+
+-- | Releases layer snapshot captured by the back-end.
+
+-- | Parameters of the 'LayerTree.releaseSnapshot' command.
+data PLayerTreeReleaseSnapshot = PLayerTreeReleaseSnapshot
+  {
+    -- | The id of the layer snapshot.
+    pLayerTreeReleaseSnapshotSnapshotId :: LayerTreeSnapshotId
+  }
+  deriving (Eq, Show)
+pLayerTreeReleaseSnapshot
+  {-
+  -- | The id of the layer snapshot.
+  -}
+  :: LayerTreeSnapshotId
+  -> PLayerTreeReleaseSnapshot
+pLayerTreeReleaseSnapshot
+  arg_pLayerTreeReleaseSnapshotSnapshotId
+  = PLayerTreeReleaseSnapshot
+    arg_pLayerTreeReleaseSnapshotSnapshotId
+instance ToJSON PLayerTreeReleaseSnapshot where
+  toJSON p = A.object $ catMaybes [
+    ("snapshotId" A..=) <$> Just (pLayerTreeReleaseSnapshotSnapshotId p)
+    ]
+instance Command PLayerTreeReleaseSnapshot where
+  type CommandResponse PLayerTreeReleaseSnapshot = ()
+  commandName _ = "LayerTree.releaseSnapshot"
+  fromJSON = const . A.Success . const ()
+
+-- | Replays the layer snapshot and returns the resulting bitmap.
+
+-- | Parameters of the 'LayerTree.replaySnapshot' command.
+data PLayerTreeReplaySnapshot = PLayerTreeReplaySnapshot
+  {
+    -- | The id of the layer snapshot.
+    pLayerTreeReplaySnapshotSnapshotId :: LayerTreeSnapshotId,
+    -- | The first step to replay from (replay from the very start if not specified).
+    pLayerTreeReplaySnapshotFromStep :: Maybe Int,
+    -- | The last step to replay to (replay till the end if not specified).
+    pLayerTreeReplaySnapshotToStep :: Maybe Int,
+    -- | The scale to apply while replaying (defaults to 1).
+    pLayerTreeReplaySnapshotScale :: Maybe Double
+  }
+  deriving (Eq, Show)
+pLayerTreeReplaySnapshot
+  {-
+  -- | The id of the layer snapshot.
+  -}
+  :: LayerTreeSnapshotId
+  -> PLayerTreeReplaySnapshot
+pLayerTreeReplaySnapshot
+  arg_pLayerTreeReplaySnapshotSnapshotId
+  = PLayerTreeReplaySnapshot
+    arg_pLayerTreeReplaySnapshotSnapshotId
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PLayerTreeReplaySnapshot where
+  toJSON p = A.object $ catMaybes [
+    ("snapshotId" A..=) <$> Just (pLayerTreeReplaySnapshotSnapshotId p),
+    ("fromStep" A..=) <$> (pLayerTreeReplaySnapshotFromStep p),
+    ("toStep" A..=) <$> (pLayerTreeReplaySnapshotToStep p),
+    ("scale" A..=) <$> (pLayerTreeReplaySnapshotScale p)
+    ]
+data LayerTreeReplaySnapshot = LayerTreeReplaySnapshot
+  {
+    -- | A data: URL for resulting image.
+    layerTreeReplaySnapshotDataURL :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON LayerTreeReplaySnapshot where
+  parseJSON = A.withObject "LayerTreeReplaySnapshot" $ \o -> LayerTreeReplaySnapshot
+    <$> o A..: "dataURL"
+instance Command PLayerTreeReplaySnapshot where
+  type CommandResponse PLayerTreeReplaySnapshot = LayerTreeReplaySnapshot
+  commandName _ = "LayerTree.replaySnapshot"
+
+-- | Replays the layer snapshot and returns canvas log.
+
+-- | Parameters of the 'LayerTree.snapshotCommandLog' command.
+data PLayerTreeSnapshotCommandLog = PLayerTreeSnapshotCommandLog
+  {
+    -- | The id of the layer snapshot.
+    pLayerTreeSnapshotCommandLogSnapshotId :: LayerTreeSnapshotId
+  }
+  deriving (Eq, Show)
+pLayerTreeSnapshotCommandLog
+  {-
+  -- | The id of the layer snapshot.
+  -}
+  :: LayerTreeSnapshotId
+  -> PLayerTreeSnapshotCommandLog
+pLayerTreeSnapshotCommandLog
+  arg_pLayerTreeSnapshotCommandLogSnapshotId
+  = PLayerTreeSnapshotCommandLog
+    arg_pLayerTreeSnapshotCommandLogSnapshotId
+instance ToJSON PLayerTreeSnapshotCommandLog where
+  toJSON p = A.object $ catMaybes [
+    ("snapshotId" A..=) <$> Just (pLayerTreeSnapshotCommandLogSnapshotId p)
+    ]
+data LayerTreeSnapshotCommandLog = LayerTreeSnapshotCommandLog
+  {
+    -- | The array of canvas function calls.
+    layerTreeSnapshotCommandLogCommandLog :: [[(T.Text, T.Text)]]
+  }
+  deriving (Eq, Show)
+instance FromJSON LayerTreeSnapshotCommandLog where
+  parseJSON = A.withObject "LayerTreeSnapshotCommandLog" $ \o -> LayerTreeSnapshotCommandLog
+    <$> o A..: "commandLog"
+instance Command PLayerTreeSnapshotCommandLog where
+  type CommandResponse PLayerTreeSnapshotCommandLog = LayerTreeSnapshotCommandLog
+  commandName _ = "LayerTree.snapshotCommandLog"
+
diff --git a/src/CDP/Domains/Log.hs b/src/CDP/Domains/Log.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains/Log.hs
@@ -0,0 +1,311 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+
+
+{- |
+= Log
+
+Provides access to log entries.
+-}
+
+
+module CDP.Domains.Log (module CDP.Domains.Log) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+
+import CDP.Domains.DOMPageNetworkEmulationSecurity as DOMPageNetworkEmulationSecurity
+import CDP.Domains.Runtime as Runtime
+
+
+-- | Type 'Log.LogEntry'.
+--   Log entry.
+data LogLogEntrySource = LogLogEntrySourceXml | LogLogEntrySourceJavascript | LogLogEntrySourceNetwork | LogLogEntrySourceStorage | LogLogEntrySourceAppcache | LogLogEntrySourceRendering | LogLogEntrySourceSecurity | LogLogEntrySourceDeprecation | LogLogEntrySourceWorker | LogLogEntrySourceViolation | LogLogEntrySourceIntervention | LogLogEntrySourceRecommendation | LogLogEntrySourceOther
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON LogLogEntrySource where
+  parseJSON = A.withText "LogLogEntrySource" $ \v -> case v of
+    "xml" -> pure LogLogEntrySourceXml
+    "javascript" -> pure LogLogEntrySourceJavascript
+    "network" -> pure LogLogEntrySourceNetwork
+    "storage" -> pure LogLogEntrySourceStorage
+    "appcache" -> pure LogLogEntrySourceAppcache
+    "rendering" -> pure LogLogEntrySourceRendering
+    "security" -> pure LogLogEntrySourceSecurity
+    "deprecation" -> pure LogLogEntrySourceDeprecation
+    "worker" -> pure LogLogEntrySourceWorker
+    "violation" -> pure LogLogEntrySourceViolation
+    "intervention" -> pure LogLogEntrySourceIntervention
+    "recommendation" -> pure LogLogEntrySourceRecommendation
+    "other" -> pure LogLogEntrySourceOther
+    "_" -> fail "failed to parse LogLogEntrySource"
+instance ToJSON LogLogEntrySource where
+  toJSON v = A.String $ case v of
+    LogLogEntrySourceXml -> "xml"
+    LogLogEntrySourceJavascript -> "javascript"
+    LogLogEntrySourceNetwork -> "network"
+    LogLogEntrySourceStorage -> "storage"
+    LogLogEntrySourceAppcache -> "appcache"
+    LogLogEntrySourceRendering -> "rendering"
+    LogLogEntrySourceSecurity -> "security"
+    LogLogEntrySourceDeprecation -> "deprecation"
+    LogLogEntrySourceWorker -> "worker"
+    LogLogEntrySourceViolation -> "violation"
+    LogLogEntrySourceIntervention -> "intervention"
+    LogLogEntrySourceRecommendation -> "recommendation"
+    LogLogEntrySourceOther -> "other"
+data LogLogEntryLevel = LogLogEntryLevelVerbose | LogLogEntryLevelInfo | LogLogEntryLevelWarning | LogLogEntryLevelError
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON LogLogEntryLevel where
+  parseJSON = A.withText "LogLogEntryLevel" $ \v -> case v of
+    "verbose" -> pure LogLogEntryLevelVerbose
+    "info" -> pure LogLogEntryLevelInfo
+    "warning" -> pure LogLogEntryLevelWarning
+    "error" -> pure LogLogEntryLevelError
+    "_" -> fail "failed to parse LogLogEntryLevel"
+instance ToJSON LogLogEntryLevel where
+  toJSON v = A.String $ case v of
+    LogLogEntryLevelVerbose -> "verbose"
+    LogLogEntryLevelInfo -> "info"
+    LogLogEntryLevelWarning -> "warning"
+    LogLogEntryLevelError -> "error"
+data LogLogEntryCategory = LogLogEntryCategoryCors
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON LogLogEntryCategory where
+  parseJSON = A.withText "LogLogEntryCategory" $ \v -> case v of
+    "cors" -> pure LogLogEntryCategoryCors
+    "_" -> fail "failed to parse LogLogEntryCategory"
+instance ToJSON LogLogEntryCategory where
+  toJSON v = A.String $ case v of
+    LogLogEntryCategoryCors -> "cors"
+data LogLogEntry = LogLogEntry
+  {
+    -- | Log entry source.
+    logLogEntrySource :: LogLogEntrySource,
+    -- | Log entry severity.
+    logLogEntryLevel :: LogLogEntryLevel,
+    -- | Logged text.
+    logLogEntryText :: T.Text,
+    logLogEntryCategory :: Maybe LogLogEntryCategory,
+    -- | Timestamp when this entry was added.
+    logLogEntryTimestamp :: Runtime.RuntimeTimestamp,
+    -- | URL of the resource if known.
+    logLogEntryUrl :: Maybe T.Text,
+    -- | Line number in the resource.
+    logLogEntryLineNumber :: Maybe Int,
+    -- | JavaScript stack trace.
+    logLogEntryStackTrace :: Maybe Runtime.RuntimeStackTrace,
+    -- | Identifier of the network request associated with this entry.
+    logLogEntryNetworkRequestId :: Maybe DOMPageNetworkEmulationSecurity.NetworkRequestId,
+    -- | Identifier of the worker associated with this entry.
+    logLogEntryWorkerId :: Maybe T.Text,
+    -- | Call arguments.
+    logLogEntryArgs :: Maybe [Runtime.RuntimeRemoteObject]
+  }
+  deriving (Eq, Show)
+instance FromJSON LogLogEntry where
+  parseJSON = A.withObject "LogLogEntry" $ \o -> LogLogEntry
+    <$> o A..: "source"
+    <*> o A..: "level"
+    <*> o A..: "text"
+    <*> o A..:? "category"
+    <*> o A..: "timestamp"
+    <*> o A..:? "url"
+    <*> o A..:? "lineNumber"
+    <*> o A..:? "stackTrace"
+    <*> o A..:? "networkRequestId"
+    <*> o A..:? "workerId"
+    <*> o A..:? "args"
+instance ToJSON LogLogEntry where
+  toJSON p = A.object $ catMaybes [
+    ("source" A..=) <$> Just (logLogEntrySource p),
+    ("level" A..=) <$> Just (logLogEntryLevel p),
+    ("text" A..=) <$> Just (logLogEntryText p),
+    ("category" A..=) <$> (logLogEntryCategory p),
+    ("timestamp" A..=) <$> Just (logLogEntryTimestamp p),
+    ("url" A..=) <$> (logLogEntryUrl p),
+    ("lineNumber" A..=) <$> (logLogEntryLineNumber p),
+    ("stackTrace" A..=) <$> (logLogEntryStackTrace p),
+    ("networkRequestId" A..=) <$> (logLogEntryNetworkRequestId p),
+    ("workerId" A..=) <$> (logLogEntryWorkerId p),
+    ("args" A..=) <$> (logLogEntryArgs p)
+    ]
+
+-- | Type 'Log.ViolationSetting'.
+--   Violation configuration setting.
+data LogViolationSettingName = LogViolationSettingNameLongTask | LogViolationSettingNameLongLayout | LogViolationSettingNameBlockedEvent | LogViolationSettingNameBlockedParser | LogViolationSettingNameDiscouragedAPIUse | LogViolationSettingNameHandler | LogViolationSettingNameRecurringHandler
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON LogViolationSettingName where
+  parseJSON = A.withText "LogViolationSettingName" $ \v -> case v of
+    "longTask" -> pure LogViolationSettingNameLongTask
+    "longLayout" -> pure LogViolationSettingNameLongLayout
+    "blockedEvent" -> pure LogViolationSettingNameBlockedEvent
+    "blockedParser" -> pure LogViolationSettingNameBlockedParser
+    "discouragedAPIUse" -> pure LogViolationSettingNameDiscouragedAPIUse
+    "handler" -> pure LogViolationSettingNameHandler
+    "recurringHandler" -> pure LogViolationSettingNameRecurringHandler
+    "_" -> fail "failed to parse LogViolationSettingName"
+instance ToJSON LogViolationSettingName where
+  toJSON v = A.String $ case v of
+    LogViolationSettingNameLongTask -> "longTask"
+    LogViolationSettingNameLongLayout -> "longLayout"
+    LogViolationSettingNameBlockedEvent -> "blockedEvent"
+    LogViolationSettingNameBlockedParser -> "blockedParser"
+    LogViolationSettingNameDiscouragedAPIUse -> "discouragedAPIUse"
+    LogViolationSettingNameHandler -> "handler"
+    LogViolationSettingNameRecurringHandler -> "recurringHandler"
+data LogViolationSetting = LogViolationSetting
+  {
+    -- | Violation type.
+    logViolationSettingName :: LogViolationSettingName,
+    -- | Time threshold to trigger upon.
+    logViolationSettingThreshold :: Double
+  }
+  deriving (Eq, Show)
+instance FromJSON LogViolationSetting where
+  parseJSON = A.withObject "LogViolationSetting" $ \o -> LogViolationSetting
+    <$> o A..: "name"
+    <*> o A..: "threshold"
+instance ToJSON LogViolationSetting where
+  toJSON p = A.object $ catMaybes [
+    ("name" A..=) <$> Just (logViolationSettingName p),
+    ("threshold" A..=) <$> Just (logViolationSettingThreshold p)
+    ]
+
+-- | Type of the 'Log.entryAdded' event.
+data LogEntryAdded = LogEntryAdded
+  {
+    -- | The entry.
+    logEntryAddedEntry :: LogLogEntry
+  }
+  deriving (Eq, Show)
+instance FromJSON LogEntryAdded where
+  parseJSON = A.withObject "LogEntryAdded" $ \o -> LogEntryAdded
+    <$> o A..: "entry"
+instance Event LogEntryAdded where
+  eventName _ = "Log.entryAdded"
+
+-- | Clears the log.
+
+-- | Parameters of the 'Log.clear' command.
+data PLogClear = PLogClear
+  deriving (Eq, Show)
+pLogClear
+  :: PLogClear
+pLogClear
+  = PLogClear
+instance ToJSON PLogClear where
+  toJSON _ = A.Null
+instance Command PLogClear where
+  type CommandResponse PLogClear = ()
+  commandName _ = "Log.clear"
+  fromJSON = const . A.Success . const ()
+
+-- | Disables log domain, prevents further log entries from being reported to the client.
+
+-- | Parameters of the 'Log.disable' command.
+data PLogDisable = PLogDisable
+  deriving (Eq, Show)
+pLogDisable
+  :: PLogDisable
+pLogDisable
+  = PLogDisable
+instance ToJSON PLogDisable where
+  toJSON _ = A.Null
+instance Command PLogDisable where
+  type CommandResponse PLogDisable = ()
+  commandName _ = "Log.disable"
+  fromJSON = const . A.Success . const ()
+
+-- | Enables log domain, sends the entries collected so far to the client by means of the
+--   `entryAdded` notification.
+
+-- | Parameters of the 'Log.enable' command.
+data PLogEnable = PLogEnable
+  deriving (Eq, Show)
+pLogEnable
+  :: PLogEnable
+pLogEnable
+  = PLogEnable
+instance ToJSON PLogEnable where
+  toJSON _ = A.Null
+instance Command PLogEnable where
+  type CommandResponse PLogEnable = ()
+  commandName _ = "Log.enable"
+  fromJSON = const . A.Success . const ()
+
+-- | start violation reporting.
+
+-- | Parameters of the 'Log.startViolationsReport' command.
+data PLogStartViolationsReport = PLogStartViolationsReport
+  {
+    -- | Configuration for violations.
+    pLogStartViolationsReportConfig :: [LogViolationSetting]
+  }
+  deriving (Eq, Show)
+pLogStartViolationsReport
+  {-
+  -- | Configuration for violations.
+  -}
+  :: [LogViolationSetting]
+  -> PLogStartViolationsReport
+pLogStartViolationsReport
+  arg_pLogStartViolationsReportConfig
+  = PLogStartViolationsReport
+    arg_pLogStartViolationsReportConfig
+instance ToJSON PLogStartViolationsReport where
+  toJSON p = A.object $ catMaybes [
+    ("config" A..=) <$> Just (pLogStartViolationsReportConfig p)
+    ]
+instance Command PLogStartViolationsReport where
+  type CommandResponse PLogStartViolationsReport = ()
+  commandName _ = "Log.startViolationsReport"
+  fromJSON = const . A.Success . const ()
+
+-- | Stop violation reporting.
+
+-- | Parameters of the 'Log.stopViolationsReport' command.
+data PLogStopViolationsReport = PLogStopViolationsReport
+  deriving (Eq, Show)
+pLogStopViolationsReport
+  :: PLogStopViolationsReport
+pLogStopViolationsReport
+  = PLogStopViolationsReport
+instance ToJSON PLogStopViolationsReport where
+  toJSON _ = A.Null
+instance Command PLogStopViolationsReport where
+  type CommandResponse PLogStopViolationsReport = ()
+  commandName _ = "Log.stopViolationsReport"
+  fromJSON = const . A.Success . const ()
+
diff --git a/src/CDP/Domains/Media.hs b/src/CDP/Domains/Media.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains/Media.hs
@@ -0,0 +1,288 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+
+
+{- |
+= Media
+
+This domain allows detailed inspection of media elements
+-}
+
+
+module CDP.Domains.Media (module CDP.Domains.Media) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+
+
+
+-- | Type 'Media.PlayerId'.
+--   Players will get an ID that is unique within the agent context.
+type MediaPlayerId = T.Text
+
+-- | Type 'Media.Timestamp'.
+type MediaTimestamp = Double
+
+-- | Type 'Media.PlayerMessage'.
+--   Have one type per entry in MediaLogRecord::Type
+--   Corresponds to kMessage
+data MediaPlayerMessageLevel = MediaPlayerMessageLevelError | MediaPlayerMessageLevelWarning | MediaPlayerMessageLevelInfo | MediaPlayerMessageLevelDebug
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON MediaPlayerMessageLevel where
+  parseJSON = A.withText "MediaPlayerMessageLevel" $ \v -> case v of
+    "error" -> pure MediaPlayerMessageLevelError
+    "warning" -> pure MediaPlayerMessageLevelWarning
+    "info" -> pure MediaPlayerMessageLevelInfo
+    "debug" -> pure MediaPlayerMessageLevelDebug
+    "_" -> fail "failed to parse MediaPlayerMessageLevel"
+instance ToJSON MediaPlayerMessageLevel where
+  toJSON v = A.String $ case v of
+    MediaPlayerMessageLevelError -> "error"
+    MediaPlayerMessageLevelWarning -> "warning"
+    MediaPlayerMessageLevelInfo -> "info"
+    MediaPlayerMessageLevelDebug -> "debug"
+data MediaPlayerMessage = MediaPlayerMessage
+  {
+    -- | Keep in sync with MediaLogMessageLevel
+    --   We are currently keeping the message level 'error' separate from the
+    --   PlayerError type because right now they represent different things,
+    --   this one being a DVLOG(ERROR) style log message that gets printed
+    --   based on what log level is selected in the UI, and the other is a
+    --   representation of a media::PipelineStatus object. Soon however we're
+    --   going to be moving away from using PipelineStatus for errors and
+    --   introducing a new error type which should hopefully let us integrate
+    --   the error log level into the PlayerError type.
+    mediaPlayerMessageLevel :: MediaPlayerMessageLevel,
+    mediaPlayerMessageMessage :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON MediaPlayerMessage where
+  parseJSON = A.withObject "MediaPlayerMessage" $ \o -> MediaPlayerMessage
+    <$> o A..: "level"
+    <*> o A..: "message"
+instance ToJSON MediaPlayerMessage where
+  toJSON p = A.object $ catMaybes [
+    ("level" A..=) <$> Just (mediaPlayerMessageLevel p),
+    ("message" A..=) <$> Just (mediaPlayerMessageMessage p)
+    ]
+
+-- | Type 'Media.PlayerProperty'.
+--   Corresponds to kMediaPropertyChange
+data MediaPlayerProperty = MediaPlayerProperty
+  {
+    mediaPlayerPropertyName :: T.Text,
+    mediaPlayerPropertyValue :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON MediaPlayerProperty where
+  parseJSON = A.withObject "MediaPlayerProperty" $ \o -> MediaPlayerProperty
+    <$> o A..: "name"
+    <*> o A..: "value"
+instance ToJSON MediaPlayerProperty where
+  toJSON p = A.object $ catMaybes [
+    ("name" A..=) <$> Just (mediaPlayerPropertyName p),
+    ("value" A..=) <$> Just (mediaPlayerPropertyValue p)
+    ]
+
+-- | Type 'Media.PlayerEvent'.
+--   Corresponds to kMediaEventTriggered
+data MediaPlayerEvent = MediaPlayerEvent
+  {
+    mediaPlayerEventTimestamp :: MediaTimestamp,
+    mediaPlayerEventValue :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON MediaPlayerEvent where
+  parseJSON = A.withObject "MediaPlayerEvent" $ \o -> MediaPlayerEvent
+    <$> o A..: "timestamp"
+    <*> o A..: "value"
+instance ToJSON MediaPlayerEvent where
+  toJSON p = A.object $ catMaybes [
+    ("timestamp" A..=) <$> Just (mediaPlayerEventTimestamp p),
+    ("value" A..=) <$> Just (mediaPlayerEventValue p)
+    ]
+
+-- | Type 'Media.PlayerErrorSourceLocation'.
+--   Represents logged source line numbers reported in an error.
+--   NOTE: file and line are from chromium c++ implementation code, not js.
+data MediaPlayerErrorSourceLocation = MediaPlayerErrorSourceLocation
+  {
+    mediaPlayerErrorSourceLocationFile :: T.Text,
+    mediaPlayerErrorSourceLocationLine :: Int
+  }
+  deriving (Eq, Show)
+instance FromJSON MediaPlayerErrorSourceLocation where
+  parseJSON = A.withObject "MediaPlayerErrorSourceLocation" $ \o -> MediaPlayerErrorSourceLocation
+    <$> o A..: "file"
+    <*> o A..: "line"
+instance ToJSON MediaPlayerErrorSourceLocation where
+  toJSON p = A.object $ catMaybes [
+    ("file" A..=) <$> Just (mediaPlayerErrorSourceLocationFile p),
+    ("line" A..=) <$> Just (mediaPlayerErrorSourceLocationLine p)
+    ]
+
+-- | Type 'Media.PlayerError'.
+--   Corresponds to kMediaError
+data MediaPlayerError = MediaPlayerError
+  {
+    mediaPlayerErrorErrorType :: T.Text,
+    -- | Code is the numeric enum entry for a specific set of error codes, such
+    --   as PipelineStatusCodes in media/base/pipeline_status.h
+    mediaPlayerErrorCode :: Int,
+    -- | A trace of where this error was caused / where it passed through.
+    mediaPlayerErrorStack :: [MediaPlayerErrorSourceLocation],
+    -- | Errors potentially have a root cause error, ie, a DecoderError might be
+    --   caused by an WindowsError
+    mediaPlayerErrorCause :: [MediaPlayerError],
+    -- | Extra data attached to an error, such as an HRESULT, Video Codec, etc.
+    mediaPlayerErrorData :: [(T.Text, T.Text)]
+  }
+  deriving (Eq, Show)
+instance FromJSON MediaPlayerError where
+  parseJSON = A.withObject "MediaPlayerError" $ \o -> MediaPlayerError
+    <$> o A..: "errorType"
+    <*> o A..: "code"
+    <*> o A..: "stack"
+    <*> o A..: "cause"
+    <*> o A..: "data"
+instance ToJSON MediaPlayerError where
+  toJSON p = A.object $ catMaybes [
+    ("errorType" A..=) <$> Just (mediaPlayerErrorErrorType p),
+    ("code" A..=) <$> Just (mediaPlayerErrorCode p),
+    ("stack" A..=) <$> Just (mediaPlayerErrorStack p),
+    ("cause" A..=) <$> Just (mediaPlayerErrorCause p),
+    ("data" A..=) <$> Just (mediaPlayerErrorData p)
+    ]
+
+-- | Type of the 'Media.playerPropertiesChanged' event.
+data MediaPlayerPropertiesChanged = MediaPlayerPropertiesChanged
+  {
+    mediaPlayerPropertiesChangedPlayerId :: MediaPlayerId,
+    mediaPlayerPropertiesChangedProperties :: [MediaPlayerProperty]
+  }
+  deriving (Eq, Show)
+instance FromJSON MediaPlayerPropertiesChanged where
+  parseJSON = A.withObject "MediaPlayerPropertiesChanged" $ \o -> MediaPlayerPropertiesChanged
+    <$> o A..: "playerId"
+    <*> o A..: "properties"
+instance Event MediaPlayerPropertiesChanged where
+  eventName _ = "Media.playerPropertiesChanged"
+
+-- | Type of the 'Media.playerEventsAdded' event.
+data MediaPlayerEventsAdded = MediaPlayerEventsAdded
+  {
+    mediaPlayerEventsAddedPlayerId :: MediaPlayerId,
+    mediaPlayerEventsAddedEvents :: [MediaPlayerEvent]
+  }
+  deriving (Eq, Show)
+instance FromJSON MediaPlayerEventsAdded where
+  parseJSON = A.withObject "MediaPlayerEventsAdded" $ \o -> MediaPlayerEventsAdded
+    <$> o A..: "playerId"
+    <*> o A..: "events"
+instance Event MediaPlayerEventsAdded where
+  eventName _ = "Media.playerEventsAdded"
+
+-- | Type of the 'Media.playerMessagesLogged' event.
+data MediaPlayerMessagesLogged = MediaPlayerMessagesLogged
+  {
+    mediaPlayerMessagesLoggedPlayerId :: MediaPlayerId,
+    mediaPlayerMessagesLoggedMessages :: [MediaPlayerMessage]
+  }
+  deriving (Eq, Show)
+instance FromJSON MediaPlayerMessagesLogged where
+  parseJSON = A.withObject "MediaPlayerMessagesLogged" $ \o -> MediaPlayerMessagesLogged
+    <$> o A..: "playerId"
+    <*> o A..: "messages"
+instance Event MediaPlayerMessagesLogged where
+  eventName _ = "Media.playerMessagesLogged"
+
+-- | Type of the 'Media.playerErrorsRaised' event.
+data MediaPlayerErrorsRaised = MediaPlayerErrorsRaised
+  {
+    mediaPlayerErrorsRaisedPlayerId :: MediaPlayerId,
+    mediaPlayerErrorsRaisedErrors :: [MediaPlayerError]
+  }
+  deriving (Eq, Show)
+instance FromJSON MediaPlayerErrorsRaised where
+  parseJSON = A.withObject "MediaPlayerErrorsRaised" $ \o -> MediaPlayerErrorsRaised
+    <$> o A..: "playerId"
+    <*> o A..: "errors"
+instance Event MediaPlayerErrorsRaised where
+  eventName _ = "Media.playerErrorsRaised"
+
+-- | Type of the 'Media.playersCreated' event.
+data MediaPlayersCreated = MediaPlayersCreated
+  {
+    mediaPlayersCreatedPlayers :: [MediaPlayerId]
+  }
+  deriving (Eq, Show)
+instance FromJSON MediaPlayersCreated where
+  parseJSON = A.withObject "MediaPlayersCreated" $ \o -> MediaPlayersCreated
+    <$> o A..: "players"
+instance Event MediaPlayersCreated where
+  eventName _ = "Media.playersCreated"
+
+-- | Enables the Media domain
+
+-- | Parameters of the 'Media.enable' command.
+data PMediaEnable = PMediaEnable
+  deriving (Eq, Show)
+pMediaEnable
+  :: PMediaEnable
+pMediaEnable
+  = PMediaEnable
+instance ToJSON PMediaEnable where
+  toJSON _ = A.Null
+instance Command PMediaEnable where
+  type CommandResponse PMediaEnable = ()
+  commandName _ = "Media.enable"
+  fromJSON = const . A.Success . const ()
+
+-- | Disables the Media domain.
+
+-- | Parameters of the 'Media.disable' command.
+data PMediaDisable = PMediaDisable
+  deriving (Eq, Show)
+pMediaDisable
+  :: PMediaDisable
+pMediaDisable
+  = PMediaDisable
+instance ToJSON PMediaDisable where
+  toJSON _ = A.Null
+instance Command PMediaDisable where
+  type CommandResponse PMediaDisable = ()
+  commandName _ = "Media.disable"
+  fromJSON = const . A.Success . const ()
+
diff --git a/src/CDP/Domains/Memory.hs b/src/CDP/Domains/Memory.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains/Memory.hs
@@ -0,0 +1,362 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+
+
+{- |
+= Memory
+
+-}
+
+
+module CDP.Domains.Memory (module CDP.Domains.Memory) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+
+
+
+-- | Type 'Memory.PressureLevel'.
+--   Memory pressure level.
+data MemoryPressureLevel = MemoryPressureLevelModerate | MemoryPressureLevelCritical
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON MemoryPressureLevel where
+  parseJSON = A.withText "MemoryPressureLevel" $ \v -> case v of
+    "moderate" -> pure MemoryPressureLevelModerate
+    "critical" -> pure MemoryPressureLevelCritical
+    "_" -> fail "failed to parse MemoryPressureLevel"
+instance ToJSON MemoryPressureLevel where
+  toJSON v = A.String $ case v of
+    MemoryPressureLevelModerate -> "moderate"
+    MemoryPressureLevelCritical -> "critical"
+
+-- | Type 'Memory.SamplingProfileNode'.
+--   Heap profile sample.
+data MemorySamplingProfileNode = MemorySamplingProfileNode
+  {
+    -- | Size of the sampled allocation.
+    memorySamplingProfileNodeSize :: Double,
+    -- | Total bytes attributed to this sample.
+    memorySamplingProfileNodeTotal :: Double,
+    -- | Execution stack at the point of allocation.
+    memorySamplingProfileNodeStack :: [T.Text]
+  }
+  deriving (Eq, Show)
+instance FromJSON MemorySamplingProfileNode where
+  parseJSON = A.withObject "MemorySamplingProfileNode" $ \o -> MemorySamplingProfileNode
+    <$> o A..: "size"
+    <*> o A..: "total"
+    <*> o A..: "stack"
+instance ToJSON MemorySamplingProfileNode where
+  toJSON p = A.object $ catMaybes [
+    ("size" A..=) <$> Just (memorySamplingProfileNodeSize p),
+    ("total" A..=) <$> Just (memorySamplingProfileNodeTotal p),
+    ("stack" A..=) <$> Just (memorySamplingProfileNodeStack p)
+    ]
+
+-- | Type 'Memory.SamplingProfile'.
+--   Array of heap profile samples.
+data MemorySamplingProfile = MemorySamplingProfile
+  {
+    memorySamplingProfileSamples :: [MemorySamplingProfileNode],
+    memorySamplingProfileModules :: [MemoryModule]
+  }
+  deriving (Eq, Show)
+instance FromJSON MemorySamplingProfile where
+  parseJSON = A.withObject "MemorySamplingProfile" $ \o -> MemorySamplingProfile
+    <$> o A..: "samples"
+    <*> o A..: "modules"
+instance ToJSON MemorySamplingProfile where
+  toJSON p = A.object $ catMaybes [
+    ("samples" A..=) <$> Just (memorySamplingProfileSamples p),
+    ("modules" A..=) <$> Just (memorySamplingProfileModules p)
+    ]
+
+-- | Type 'Memory.Module'.
+--   Executable module information
+data MemoryModule = MemoryModule
+  {
+    -- | Name of the module.
+    memoryModuleName :: T.Text,
+    -- | UUID of the module.
+    memoryModuleUuid :: T.Text,
+    -- | Base address where the module is loaded into memory. Encoded as a decimal
+    --   or hexadecimal (0x prefixed) string.
+    memoryModuleBaseAddress :: T.Text,
+    -- | Size of the module in bytes.
+    memoryModuleSize :: Double
+  }
+  deriving (Eq, Show)
+instance FromJSON MemoryModule where
+  parseJSON = A.withObject "MemoryModule" $ \o -> MemoryModule
+    <$> o A..: "name"
+    <*> o A..: "uuid"
+    <*> o A..: "baseAddress"
+    <*> o A..: "size"
+instance ToJSON MemoryModule where
+  toJSON p = A.object $ catMaybes [
+    ("name" A..=) <$> Just (memoryModuleName p),
+    ("uuid" A..=) <$> Just (memoryModuleUuid p),
+    ("baseAddress" A..=) <$> Just (memoryModuleBaseAddress p),
+    ("size" A..=) <$> Just (memoryModuleSize p)
+    ]
+
+
+-- | Parameters of the 'Memory.getDOMCounters' command.
+data PMemoryGetDOMCounters = PMemoryGetDOMCounters
+  deriving (Eq, Show)
+pMemoryGetDOMCounters
+  :: PMemoryGetDOMCounters
+pMemoryGetDOMCounters
+  = PMemoryGetDOMCounters
+instance ToJSON PMemoryGetDOMCounters where
+  toJSON _ = A.Null
+data MemoryGetDOMCounters = MemoryGetDOMCounters
+  {
+    memoryGetDOMCountersDocuments :: Int,
+    memoryGetDOMCountersNodes :: Int,
+    memoryGetDOMCountersJsEventListeners :: Int
+  }
+  deriving (Eq, Show)
+instance FromJSON MemoryGetDOMCounters where
+  parseJSON = A.withObject "MemoryGetDOMCounters" $ \o -> MemoryGetDOMCounters
+    <$> o A..: "documents"
+    <*> o A..: "nodes"
+    <*> o A..: "jsEventListeners"
+instance Command PMemoryGetDOMCounters where
+  type CommandResponse PMemoryGetDOMCounters = MemoryGetDOMCounters
+  commandName _ = "Memory.getDOMCounters"
+
+
+-- | Parameters of the 'Memory.prepareForLeakDetection' command.
+data PMemoryPrepareForLeakDetection = PMemoryPrepareForLeakDetection
+  deriving (Eq, Show)
+pMemoryPrepareForLeakDetection
+  :: PMemoryPrepareForLeakDetection
+pMemoryPrepareForLeakDetection
+  = PMemoryPrepareForLeakDetection
+instance ToJSON PMemoryPrepareForLeakDetection where
+  toJSON _ = A.Null
+instance Command PMemoryPrepareForLeakDetection where
+  type CommandResponse PMemoryPrepareForLeakDetection = ()
+  commandName _ = "Memory.prepareForLeakDetection"
+  fromJSON = const . A.Success . const ()
+
+-- | Simulate OomIntervention by purging V8 memory.
+
+-- | Parameters of the 'Memory.forciblyPurgeJavaScriptMemory' command.
+data PMemoryForciblyPurgeJavaScriptMemory = PMemoryForciblyPurgeJavaScriptMemory
+  deriving (Eq, Show)
+pMemoryForciblyPurgeJavaScriptMemory
+  :: PMemoryForciblyPurgeJavaScriptMemory
+pMemoryForciblyPurgeJavaScriptMemory
+  = PMemoryForciblyPurgeJavaScriptMemory
+instance ToJSON PMemoryForciblyPurgeJavaScriptMemory where
+  toJSON _ = A.Null
+instance Command PMemoryForciblyPurgeJavaScriptMemory where
+  type CommandResponse PMemoryForciblyPurgeJavaScriptMemory = ()
+  commandName _ = "Memory.forciblyPurgeJavaScriptMemory"
+  fromJSON = const . A.Success . const ()
+
+-- | Enable/disable suppressing memory pressure notifications in all processes.
+
+-- | Parameters of the 'Memory.setPressureNotificationsSuppressed' command.
+data PMemorySetPressureNotificationsSuppressed = PMemorySetPressureNotificationsSuppressed
+  {
+    -- | If true, memory pressure notifications will be suppressed.
+    pMemorySetPressureNotificationsSuppressedSuppressed :: Bool
+  }
+  deriving (Eq, Show)
+pMemorySetPressureNotificationsSuppressed
+  {-
+  -- | If true, memory pressure notifications will be suppressed.
+  -}
+  :: Bool
+  -> PMemorySetPressureNotificationsSuppressed
+pMemorySetPressureNotificationsSuppressed
+  arg_pMemorySetPressureNotificationsSuppressedSuppressed
+  = PMemorySetPressureNotificationsSuppressed
+    arg_pMemorySetPressureNotificationsSuppressedSuppressed
+instance ToJSON PMemorySetPressureNotificationsSuppressed where
+  toJSON p = A.object $ catMaybes [
+    ("suppressed" A..=) <$> Just (pMemorySetPressureNotificationsSuppressedSuppressed p)
+    ]
+instance Command PMemorySetPressureNotificationsSuppressed where
+  type CommandResponse PMemorySetPressureNotificationsSuppressed = ()
+  commandName _ = "Memory.setPressureNotificationsSuppressed"
+  fromJSON = const . A.Success . const ()
+
+-- | Simulate a memory pressure notification in all processes.
+
+-- | Parameters of the 'Memory.simulatePressureNotification' command.
+data PMemorySimulatePressureNotification = PMemorySimulatePressureNotification
+  {
+    -- | Memory pressure level of the notification.
+    pMemorySimulatePressureNotificationLevel :: MemoryPressureLevel
+  }
+  deriving (Eq, Show)
+pMemorySimulatePressureNotification
+  {-
+  -- | Memory pressure level of the notification.
+  -}
+  :: MemoryPressureLevel
+  -> PMemorySimulatePressureNotification
+pMemorySimulatePressureNotification
+  arg_pMemorySimulatePressureNotificationLevel
+  = PMemorySimulatePressureNotification
+    arg_pMemorySimulatePressureNotificationLevel
+instance ToJSON PMemorySimulatePressureNotification where
+  toJSON p = A.object $ catMaybes [
+    ("level" A..=) <$> Just (pMemorySimulatePressureNotificationLevel p)
+    ]
+instance Command PMemorySimulatePressureNotification where
+  type CommandResponse PMemorySimulatePressureNotification = ()
+  commandName _ = "Memory.simulatePressureNotification"
+  fromJSON = const . A.Success . const ()
+
+-- | Start collecting native memory profile.
+
+-- | Parameters of the 'Memory.startSampling' command.
+data PMemoryStartSampling = PMemoryStartSampling
+  {
+    -- | Average number of bytes between samples.
+    pMemoryStartSamplingSamplingInterval :: Maybe Int,
+    -- | Do not randomize intervals between samples.
+    pMemoryStartSamplingSuppressRandomness :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pMemoryStartSampling
+  :: PMemoryStartSampling
+pMemoryStartSampling
+  = PMemoryStartSampling
+    Nothing
+    Nothing
+instance ToJSON PMemoryStartSampling where
+  toJSON p = A.object $ catMaybes [
+    ("samplingInterval" A..=) <$> (pMemoryStartSamplingSamplingInterval p),
+    ("suppressRandomness" A..=) <$> (pMemoryStartSamplingSuppressRandomness p)
+    ]
+instance Command PMemoryStartSampling where
+  type CommandResponse PMemoryStartSampling = ()
+  commandName _ = "Memory.startSampling"
+  fromJSON = const . A.Success . const ()
+
+-- | Stop collecting native memory profile.
+
+-- | Parameters of the 'Memory.stopSampling' command.
+data PMemoryStopSampling = PMemoryStopSampling
+  deriving (Eq, Show)
+pMemoryStopSampling
+  :: PMemoryStopSampling
+pMemoryStopSampling
+  = PMemoryStopSampling
+instance ToJSON PMemoryStopSampling where
+  toJSON _ = A.Null
+instance Command PMemoryStopSampling where
+  type CommandResponse PMemoryStopSampling = ()
+  commandName _ = "Memory.stopSampling"
+  fromJSON = const . A.Success . const ()
+
+-- | Retrieve native memory allocations profile
+--   collected since renderer process startup.
+
+-- | Parameters of the 'Memory.getAllTimeSamplingProfile' command.
+data PMemoryGetAllTimeSamplingProfile = PMemoryGetAllTimeSamplingProfile
+  deriving (Eq, Show)
+pMemoryGetAllTimeSamplingProfile
+  :: PMemoryGetAllTimeSamplingProfile
+pMemoryGetAllTimeSamplingProfile
+  = PMemoryGetAllTimeSamplingProfile
+instance ToJSON PMemoryGetAllTimeSamplingProfile where
+  toJSON _ = A.Null
+data MemoryGetAllTimeSamplingProfile = MemoryGetAllTimeSamplingProfile
+  {
+    memoryGetAllTimeSamplingProfileProfile :: MemorySamplingProfile
+  }
+  deriving (Eq, Show)
+instance FromJSON MemoryGetAllTimeSamplingProfile where
+  parseJSON = A.withObject "MemoryGetAllTimeSamplingProfile" $ \o -> MemoryGetAllTimeSamplingProfile
+    <$> o A..: "profile"
+instance Command PMemoryGetAllTimeSamplingProfile where
+  type CommandResponse PMemoryGetAllTimeSamplingProfile = MemoryGetAllTimeSamplingProfile
+  commandName _ = "Memory.getAllTimeSamplingProfile"
+
+-- | Retrieve native memory allocations profile
+--   collected since browser process startup.
+
+-- | Parameters of the 'Memory.getBrowserSamplingProfile' command.
+data PMemoryGetBrowserSamplingProfile = PMemoryGetBrowserSamplingProfile
+  deriving (Eq, Show)
+pMemoryGetBrowserSamplingProfile
+  :: PMemoryGetBrowserSamplingProfile
+pMemoryGetBrowserSamplingProfile
+  = PMemoryGetBrowserSamplingProfile
+instance ToJSON PMemoryGetBrowserSamplingProfile where
+  toJSON _ = A.Null
+data MemoryGetBrowserSamplingProfile = MemoryGetBrowserSamplingProfile
+  {
+    memoryGetBrowserSamplingProfileProfile :: MemorySamplingProfile
+  }
+  deriving (Eq, Show)
+instance FromJSON MemoryGetBrowserSamplingProfile where
+  parseJSON = A.withObject "MemoryGetBrowserSamplingProfile" $ \o -> MemoryGetBrowserSamplingProfile
+    <$> o A..: "profile"
+instance Command PMemoryGetBrowserSamplingProfile where
+  type CommandResponse PMemoryGetBrowserSamplingProfile = MemoryGetBrowserSamplingProfile
+  commandName _ = "Memory.getBrowserSamplingProfile"
+
+-- | Retrieve native memory allocations profile collected since last
+--   `startSampling` call.
+
+-- | Parameters of the 'Memory.getSamplingProfile' command.
+data PMemoryGetSamplingProfile = PMemoryGetSamplingProfile
+  deriving (Eq, Show)
+pMemoryGetSamplingProfile
+  :: PMemoryGetSamplingProfile
+pMemoryGetSamplingProfile
+  = PMemoryGetSamplingProfile
+instance ToJSON PMemoryGetSamplingProfile where
+  toJSON _ = A.Null
+data MemoryGetSamplingProfile = MemoryGetSamplingProfile
+  {
+    memoryGetSamplingProfileProfile :: MemorySamplingProfile
+  }
+  deriving (Eq, Show)
+instance FromJSON MemoryGetSamplingProfile where
+  parseJSON = A.withObject "MemoryGetSamplingProfile" $ \o -> MemoryGetSamplingProfile
+    <$> o A..: "profile"
+instance Command PMemoryGetSamplingProfile where
+  type CommandResponse PMemoryGetSamplingProfile = MemoryGetSamplingProfile
+  commandName _ = "Memory.getSamplingProfile"
+
diff --git a/src/CDP/Domains/Overlay.hs b/src/CDP/Domains/Overlay.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains/Overlay.hs
@@ -0,0 +1,1442 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+
+
+{- |
+= Overlay
+
+This domain provides various functionality related to drawing atop the inspected page.
+-}
+
+
+module CDP.Domains.Overlay (module CDP.Domains.Overlay) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+
+import CDP.Domains.DOMPageNetworkEmulationSecurity as DOMPageNetworkEmulationSecurity
+import CDP.Domains.Runtime as Runtime
+
+
+-- | Type 'Overlay.SourceOrderConfig'.
+--   Configuration data for drawing the source order of an elements children.
+data OverlaySourceOrderConfig = OverlaySourceOrderConfig
+  {
+    -- | the color to outline the givent element in.
+    overlaySourceOrderConfigParentOutlineColor :: DOMPageNetworkEmulationSecurity.DOMRGBA,
+    -- | the color to outline the child elements in.
+    overlaySourceOrderConfigChildOutlineColor :: DOMPageNetworkEmulationSecurity.DOMRGBA
+  }
+  deriving (Eq, Show)
+instance FromJSON OverlaySourceOrderConfig where
+  parseJSON = A.withObject "OverlaySourceOrderConfig" $ \o -> OverlaySourceOrderConfig
+    <$> o A..: "parentOutlineColor"
+    <*> o A..: "childOutlineColor"
+instance ToJSON OverlaySourceOrderConfig where
+  toJSON p = A.object $ catMaybes [
+    ("parentOutlineColor" A..=) <$> Just (overlaySourceOrderConfigParentOutlineColor p),
+    ("childOutlineColor" A..=) <$> Just (overlaySourceOrderConfigChildOutlineColor p)
+    ]
+
+-- | Type 'Overlay.GridHighlightConfig'.
+--   Configuration data for the highlighting of Grid elements.
+data OverlayGridHighlightConfig = OverlayGridHighlightConfig
+  {
+    -- | Whether the extension lines from grid cells to the rulers should be shown (default: false).
+    overlayGridHighlightConfigShowGridExtensionLines :: Maybe Bool,
+    -- | Show Positive line number labels (default: false).
+    overlayGridHighlightConfigShowPositiveLineNumbers :: Maybe Bool,
+    -- | Show Negative line number labels (default: false).
+    overlayGridHighlightConfigShowNegativeLineNumbers :: Maybe Bool,
+    -- | Show area name labels (default: false).
+    overlayGridHighlightConfigShowAreaNames :: Maybe Bool,
+    -- | Show line name labels (default: false).
+    overlayGridHighlightConfigShowLineNames :: Maybe Bool,
+    -- | Show track size labels (default: false).
+    overlayGridHighlightConfigShowTrackSizes :: Maybe Bool,
+    -- | The grid container border highlight color (default: transparent).
+    overlayGridHighlightConfigGridBorderColor :: Maybe DOMPageNetworkEmulationSecurity.DOMRGBA,
+    -- | The row line color (default: transparent).
+    overlayGridHighlightConfigRowLineColor :: Maybe DOMPageNetworkEmulationSecurity.DOMRGBA,
+    -- | The column line color (default: transparent).
+    overlayGridHighlightConfigColumnLineColor :: Maybe DOMPageNetworkEmulationSecurity.DOMRGBA,
+    -- | Whether the grid border is dashed (default: false).
+    overlayGridHighlightConfigGridBorderDash :: Maybe Bool,
+    -- | Whether row lines are dashed (default: false).
+    overlayGridHighlightConfigRowLineDash :: Maybe Bool,
+    -- | Whether column lines are dashed (default: false).
+    overlayGridHighlightConfigColumnLineDash :: Maybe Bool,
+    -- | The row gap highlight fill color (default: transparent).
+    overlayGridHighlightConfigRowGapColor :: Maybe DOMPageNetworkEmulationSecurity.DOMRGBA,
+    -- | The row gap hatching fill color (default: transparent).
+    overlayGridHighlightConfigRowHatchColor :: Maybe DOMPageNetworkEmulationSecurity.DOMRGBA,
+    -- | The column gap highlight fill color (default: transparent).
+    overlayGridHighlightConfigColumnGapColor :: Maybe DOMPageNetworkEmulationSecurity.DOMRGBA,
+    -- | The column gap hatching fill color (default: transparent).
+    overlayGridHighlightConfigColumnHatchColor :: Maybe DOMPageNetworkEmulationSecurity.DOMRGBA,
+    -- | The named grid areas border color (Default: transparent).
+    overlayGridHighlightConfigAreaBorderColor :: Maybe DOMPageNetworkEmulationSecurity.DOMRGBA,
+    -- | The grid container background color (Default: transparent).
+    overlayGridHighlightConfigGridBackgroundColor :: Maybe DOMPageNetworkEmulationSecurity.DOMRGBA
+  }
+  deriving (Eq, Show)
+instance FromJSON OverlayGridHighlightConfig where
+  parseJSON = A.withObject "OverlayGridHighlightConfig" $ \o -> OverlayGridHighlightConfig
+    <$> o A..:? "showGridExtensionLines"
+    <*> o A..:? "showPositiveLineNumbers"
+    <*> o A..:? "showNegativeLineNumbers"
+    <*> o A..:? "showAreaNames"
+    <*> o A..:? "showLineNames"
+    <*> o A..:? "showTrackSizes"
+    <*> o A..:? "gridBorderColor"
+    <*> o A..:? "rowLineColor"
+    <*> o A..:? "columnLineColor"
+    <*> o A..:? "gridBorderDash"
+    <*> o A..:? "rowLineDash"
+    <*> o A..:? "columnLineDash"
+    <*> o A..:? "rowGapColor"
+    <*> o A..:? "rowHatchColor"
+    <*> o A..:? "columnGapColor"
+    <*> o A..:? "columnHatchColor"
+    <*> o A..:? "areaBorderColor"
+    <*> o A..:? "gridBackgroundColor"
+instance ToJSON OverlayGridHighlightConfig where
+  toJSON p = A.object $ catMaybes [
+    ("showGridExtensionLines" A..=) <$> (overlayGridHighlightConfigShowGridExtensionLines p),
+    ("showPositiveLineNumbers" A..=) <$> (overlayGridHighlightConfigShowPositiveLineNumbers p),
+    ("showNegativeLineNumbers" A..=) <$> (overlayGridHighlightConfigShowNegativeLineNumbers p),
+    ("showAreaNames" A..=) <$> (overlayGridHighlightConfigShowAreaNames p),
+    ("showLineNames" A..=) <$> (overlayGridHighlightConfigShowLineNames p),
+    ("showTrackSizes" A..=) <$> (overlayGridHighlightConfigShowTrackSizes p),
+    ("gridBorderColor" A..=) <$> (overlayGridHighlightConfigGridBorderColor p),
+    ("rowLineColor" A..=) <$> (overlayGridHighlightConfigRowLineColor p),
+    ("columnLineColor" A..=) <$> (overlayGridHighlightConfigColumnLineColor p),
+    ("gridBorderDash" A..=) <$> (overlayGridHighlightConfigGridBorderDash p),
+    ("rowLineDash" A..=) <$> (overlayGridHighlightConfigRowLineDash p),
+    ("columnLineDash" A..=) <$> (overlayGridHighlightConfigColumnLineDash p),
+    ("rowGapColor" A..=) <$> (overlayGridHighlightConfigRowGapColor p),
+    ("rowHatchColor" A..=) <$> (overlayGridHighlightConfigRowHatchColor p),
+    ("columnGapColor" A..=) <$> (overlayGridHighlightConfigColumnGapColor p),
+    ("columnHatchColor" A..=) <$> (overlayGridHighlightConfigColumnHatchColor p),
+    ("areaBorderColor" A..=) <$> (overlayGridHighlightConfigAreaBorderColor p),
+    ("gridBackgroundColor" A..=) <$> (overlayGridHighlightConfigGridBackgroundColor p)
+    ]
+
+-- | Type 'Overlay.FlexContainerHighlightConfig'.
+--   Configuration data for the highlighting of Flex container elements.
+data OverlayFlexContainerHighlightConfig = OverlayFlexContainerHighlightConfig
+  {
+    -- | The style of the container border
+    overlayFlexContainerHighlightConfigContainerBorder :: Maybe OverlayLineStyle,
+    -- | The style of the separator between lines
+    overlayFlexContainerHighlightConfigLineSeparator :: Maybe OverlayLineStyle,
+    -- | The style of the separator between items
+    overlayFlexContainerHighlightConfigItemSeparator :: Maybe OverlayLineStyle,
+    -- | Style of content-distribution space on the main axis (justify-content).
+    overlayFlexContainerHighlightConfigMainDistributedSpace :: Maybe OverlayBoxStyle,
+    -- | Style of content-distribution space on the cross axis (align-content).
+    overlayFlexContainerHighlightConfigCrossDistributedSpace :: Maybe OverlayBoxStyle,
+    -- | Style of empty space caused by row gaps (gap/row-gap).
+    overlayFlexContainerHighlightConfigRowGapSpace :: Maybe OverlayBoxStyle,
+    -- | Style of empty space caused by columns gaps (gap/column-gap).
+    overlayFlexContainerHighlightConfigColumnGapSpace :: Maybe OverlayBoxStyle,
+    -- | Style of the self-alignment line (align-items).
+    overlayFlexContainerHighlightConfigCrossAlignment :: Maybe OverlayLineStyle
+  }
+  deriving (Eq, Show)
+instance FromJSON OverlayFlexContainerHighlightConfig where
+  parseJSON = A.withObject "OverlayFlexContainerHighlightConfig" $ \o -> OverlayFlexContainerHighlightConfig
+    <$> o A..:? "containerBorder"
+    <*> o A..:? "lineSeparator"
+    <*> o A..:? "itemSeparator"
+    <*> o A..:? "mainDistributedSpace"
+    <*> o A..:? "crossDistributedSpace"
+    <*> o A..:? "rowGapSpace"
+    <*> o A..:? "columnGapSpace"
+    <*> o A..:? "crossAlignment"
+instance ToJSON OverlayFlexContainerHighlightConfig where
+  toJSON p = A.object $ catMaybes [
+    ("containerBorder" A..=) <$> (overlayFlexContainerHighlightConfigContainerBorder p),
+    ("lineSeparator" A..=) <$> (overlayFlexContainerHighlightConfigLineSeparator p),
+    ("itemSeparator" A..=) <$> (overlayFlexContainerHighlightConfigItemSeparator p),
+    ("mainDistributedSpace" A..=) <$> (overlayFlexContainerHighlightConfigMainDistributedSpace p),
+    ("crossDistributedSpace" A..=) <$> (overlayFlexContainerHighlightConfigCrossDistributedSpace p),
+    ("rowGapSpace" A..=) <$> (overlayFlexContainerHighlightConfigRowGapSpace p),
+    ("columnGapSpace" A..=) <$> (overlayFlexContainerHighlightConfigColumnGapSpace p),
+    ("crossAlignment" A..=) <$> (overlayFlexContainerHighlightConfigCrossAlignment p)
+    ]
+
+-- | Type 'Overlay.FlexItemHighlightConfig'.
+--   Configuration data for the highlighting of Flex item elements.
+data OverlayFlexItemHighlightConfig = OverlayFlexItemHighlightConfig
+  {
+    -- | Style of the box representing the item's base size
+    overlayFlexItemHighlightConfigBaseSizeBox :: Maybe OverlayBoxStyle,
+    -- | Style of the border around the box representing the item's base size
+    overlayFlexItemHighlightConfigBaseSizeBorder :: Maybe OverlayLineStyle,
+    -- | Style of the arrow representing if the item grew or shrank
+    overlayFlexItemHighlightConfigFlexibilityArrow :: Maybe OverlayLineStyle
+  }
+  deriving (Eq, Show)
+instance FromJSON OverlayFlexItemHighlightConfig where
+  parseJSON = A.withObject "OverlayFlexItemHighlightConfig" $ \o -> OverlayFlexItemHighlightConfig
+    <$> o A..:? "baseSizeBox"
+    <*> o A..:? "baseSizeBorder"
+    <*> o A..:? "flexibilityArrow"
+instance ToJSON OverlayFlexItemHighlightConfig where
+  toJSON p = A.object $ catMaybes [
+    ("baseSizeBox" A..=) <$> (overlayFlexItemHighlightConfigBaseSizeBox p),
+    ("baseSizeBorder" A..=) <$> (overlayFlexItemHighlightConfigBaseSizeBorder p),
+    ("flexibilityArrow" A..=) <$> (overlayFlexItemHighlightConfigFlexibilityArrow p)
+    ]
+
+-- | Type 'Overlay.LineStyle'.
+--   Style information for drawing a line.
+data OverlayLineStylePattern = OverlayLineStylePatternDashed | OverlayLineStylePatternDotted
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON OverlayLineStylePattern where
+  parseJSON = A.withText "OverlayLineStylePattern" $ \v -> case v of
+    "dashed" -> pure OverlayLineStylePatternDashed
+    "dotted" -> pure OverlayLineStylePatternDotted
+    "_" -> fail "failed to parse OverlayLineStylePattern"
+instance ToJSON OverlayLineStylePattern where
+  toJSON v = A.String $ case v of
+    OverlayLineStylePatternDashed -> "dashed"
+    OverlayLineStylePatternDotted -> "dotted"
+data OverlayLineStyle = OverlayLineStyle
+  {
+    -- | The color of the line (default: transparent)
+    overlayLineStyleColor :: Maybe DOMPageNetworkEmulationSecurity.DOMRGBA,
+    -- | The line pattern (default: solid)
+    overlayLineStylePattern :: Maybe OverlayLineStylePattern
+  }
+  deriving (Eq, Show)
+instance FromJSON OverlayLineStyle where
+  parseJSON = A.withObject "OverlayLineStyle" $ \o -> OverlayLineStyle
+    <$> o A..:? "color"
+    <*> o A..:? "pattern"
+instance ToJSON OverlayLineStyle where
+  toJSON p = A.object $ catMaybes [
+    ("color" A..=) <$> (overlayLineStyleColor p),
+    ("pattern" A..=) <$> (overlayLineStylePattern p)
+    ]
+
+-- | Type 'Overlay.BoxStyle'.
+--   Style information for drawing a box.
+data OverlayBoxStyle = OverlayBoxStyle
+  {
+    -- | The background color for the box (default: transparent)
+    overlayBoxStyleFillColor :: Maybe DOMPageNetworkEmulationSecurity.DOMRGBA,
+    -- | The hatching color for the box (default: transparent)
+    overlayBoxStyleHatchColor :: Maybe DOMPageNetworkEmulationSecurity.DOMRGBA
+  }
+  deriving (Eq, Show)
+instance FromJSON OverlayBoxStyle where
+  parseJSON = A.withObject "OverlayBoxStyle" $ \o -> OverlayBoxStyle
+    <$> o A..:? "fillColor"
+    <*> o A..:? "hatchColor"
+instance ToJSON OverlayBoxStyle where
+  toJSON p = A.object $ catMaybes [
+    ("fillColor" A..=) <$> (overlayBoxStyleFillColor p),
+    ("hatchColor" A..=) <$> (overlayBoxStyleHatchColor p)
+    ]
+
+-- | Type 'Overlay.ContrastAlgorithm'.
+data OverlayContrastAlgorithm = OverlayContrastAlgorithmAa | OverlayContrastAlgorithmAaa | OverlayContrastAlgorithmApca
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON OverlayContrastAlgorithm where
+  parseJSON = A.withText "OverlayContrastAlgorithm" $ \v -> case v of
+    "aa" -> pure OverlayContrastAlgorithmAa
+    "aaa" -> pure OverlayContrastAlgorithmAaa
+    "apca" -> pure OverlayContrastAlgorithmApca
+    "_" -> fail "failed to parse OverlayContrastAlgorithm"
+instance ToJSON OverlayContrastAlgorithm where
+  toJSON v = A.String $ case v of
+    OverlayContrastAlgorithmAa -> "aa"
+    OverlayContrastAlgorithmAaa -> "aaa"
+    OverlayContrastAlgorithmApca -> "apca"
+
+-- | Type 'Overlay.HighlightConfig'.
+--   Configuration data for the highlighting of page elements.
+data OverlayHighlightConfig = OverlayHighlightConfig
+  {
+    -- | Whether the node info tooltip should be shown (default: false).
+    overlayHighlightConfigShowInfo :: Maybe Bool,
+    -- | Whether the node styles in the tooltip (default: false).
+    overlayHighlightConfigShowStyles :: Maybe Bool,
+    -- | Whether the rulers should be shown (default: false).
+    overlayHighlightConfigShowRulers :: Maybe Bool,
+    -- | Whether the a11y info should be shown (default: true).
+    overlayHighlightConfigShowAccessibilityInfo :: Maybe Bool,
+    -- | Whether the extension lines from node to the rulers should be shown (default: false).
+    overlayHighlightConfigShowExtensionLines :: Maybe Bool,
+    -- | The content box highlight fill color (default: transparent).
+    overlayHighlightConfigContentColor :: Maybe DOMPageNetworkEmulationSecurity.DOMRGBA,
+    -- | The padding highlight fill color (default: transparent).
+    overlayHighlightConfigPaddingColor :: Maybe DOMPageNetworkEmulationSecurity.DOMRGBA,
+    -- | The border highlight fill color (default: transparent).
+    overlayHighlightConfigBorderColor :: Maybe DOMPageNetworkEmulationSecurity.DOMRGBA,
+    -- | The margin highlight fill color (default: transparent).
+    overlayHighlightConfigMarginColor :: Maybe DOMPageNetworkEmulationSecurity.DOMRGBA,
+    -- | The event target element highlight fill color (default: transparent).
+    overlayHighlightConfigEventTargetColor :: Maybe DOMPageNetworkEmulationSecurity.DOMRGBA,
+    -- | The shape outside fill color (default: transparent).
+    overlayHighlightConfigShapeColor :: Maybe DOMPageNetworkEmulationSecurity.DOMRGBA,
+    -- | The shape margin fill color (default: transparent).
+    overlayHighlightConfigShapeMarginColor :: Maybe DOMPageNetworkEmulationSecurity.DOMRGBA,
+    -- | The grid layout color (default: transparent).
+    overlayHighlightConfigCssGridColor :: Maybe DOMPageNetworkEmulationSecurity.DOMRGBA,
+    -- | The color format used to format color styles (default: hex).
+    overlayHighlightConfigColorFormat :: Maybe OverlayColorFormat,
+    -- | The grid layout highlight configuration (default: all transparent).
+    overlayHighlightConfigGridHighlightConfig :: Maybe OverlayGridHighlightConfig,
+    -- | The flex container highlight configuration (default: all transparent).
+    overlayHighlightConfigFlexContainerHighlightConfig :: Maybe OverlayFlexContainerHighlightConfig,
+    -- | The flex item highlight configuration (default: all transparent).
+    overlayHighlightConfigFlexItemHighlightConfig :: Maybe OverlayFlexItemHighlightConfig,
+    -- | The contrast algorithm to use for the contrast ratio (default: aa).
+    overlayHighlightConfigContrastAlgorithm :: Maybe OverlayContrastAlgorithm,
+    -- | The container query container highlight configuration (default: all transparent).
+    overlayHighlightConfigContainerQueryContainerHighlightConfig :: Maybe OverlayContainerQueryContainerHighlightConfig
+  }
+  deriving (Eq, Show)
+instance FromJSON OverlayHighlightConfig where
+  parseJSON = A.withObject "OverlayHighlightConfig" $ \o -> OverlayHighlightConfig
+    <$> o A..:? "showInfo"
+    <*> o A..:? "showStyles"
+    <*> o A..:? "showRulers"
+    <*> o A..:? "showAccessibilityInfo"
+    <*> o A..:? "showExtensionLines"
+    <*> o A..:? "contentColor"
+    <*> o A..:? "paddingColor"
+    <*> o A..:? "borderColor"
+    <*> o A..:? "marginColor"
+    <*> o A..:? "eventTargetColor"
+    <*> o A..:? "shapeColor"
+    <*> o A..:? "shapeMarginColor"
+    <*> o A..:? "cssGridColor"
+    <*> o A..:? "colorFormat"
+    <*> o A..:? "gridHighlightConfig"
+    <*> o A..:? "flexContainerHighlightConfig"
+    <*> o A..:? "flexItemHighlightConfig"
+    <*> o A..:? "contrastAlgorithm"
+    <*> o A..:? "containerQueryContainerHighlightConfig"
+instance ToJSON OverlayHighlightConfig where
+  toJSON p = A.object $ catMaybes [
+    ("showInfo" A..=) <$> (overlayHighlightConfigShowInfo p),
+    ("showStyles" A..=) <$> (overlayHighlightConfigShowStyles p),
+    ("showRulers" A..=) <$> (overlayHighlightConfigShowRulers p),
+    ("showAccessibilityInfo" A..=) <$> (overlayHighlightConfigShowAccessibilityInfo p),
+    ("showExtensionLines" A..=) <$> (overlayHighlightConfigShowExtensionLines p),
+    ("contentColor" A..=) <$> (overlayHighlightConfigContentColor p),
+    ("paddingColor" A..=) <$> (overlayHighlightConfigPaddingColor p),
+    ("borderColor" A..=) <$> (overlayHighlightConfigBorderColor p),
+    ("marginColor" A..=) <$> (overlayHighlightConfigMarginColor p),
+    ("eventTargetColor" A..=) <$> (overlayHighlightConfigEventTargetColor p),
+    ("shapeColor" A..=) <$> (overlayHighlightConfigShapeColor p),
+    ("shapeMarginColor" A..=) <$> (overlayHighlightConfigShapeMarginColor p),
+    ("cssGridColor" A..=) <$> (overlayHighlightConfigCssGridColor p),
+    ("colorFormat" A..=) <$> (overlayHighlightConfigColorFormat p),
+    ("gridHighlightConfig" A..=) <$> (overlayHighlightConfigGridHighlightConfig p),
+    ("flexContainerHighlightConfig" A..=) <$> (overlayHighlightConfigFlexContainerHighlightConfig p),
+    ("flexItemHighlightConfig" A..=) <$> (overlayHighlightConfigFlexItemHighlightConfig p),
+    ("contrastAlgorithm" A..=) <$> (overlayHighlightConfigContrastAlgorithm p),
+    ("containerQueryContainerHighlightConfig" A..=) <$> (overlayHighlightConfigContainerQueryContainerHighlightConfig p)
+    ]
+
+-- | Type 'Overlay.ColorFormat'.
+data OverlayColorFormat = OverlayColorFormatRgb | OverlayColorFormatHsl | OverlayColorFormatHwb | OverlayColorFormatHex
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON OverlayColorFormat where
+  parseJSON = A.withText "OverlayColorFormat" $ \v -> case v of
+    "rgb" -> pure OverlayColorFormatRgb
+    "hsl" -> pure OverlayColorFormatHsl
+    "hwb" -> pure OverlayColorFormatHwb
+    "hex" -> pure OverlayColorFormatHex
+    "_" -> fail "failed to parse OverlayColorFormat"
+instance ToJSON OverlayColorFormat where
+  toJSON v = A.String $ case v of
+    OverlayColorFormatRgb -> "rgb"
+    OverlayColorFormatHsl -> "hsl"
+    OverlayColorFormatHwb -> "hwb"
+    OverlayColorFormatHex -> "hex"
+
+-- | Type 'Overlay.GridNodeHighlightConfig'.
+--   Configurations for Persistent Grid Highlight
+data OverlayGridNodeHighlightConfig = OverlayGridNodeHighlightConfig
+  {
+    -- | A descriptor for the highlight appearance.
+    overlayGridNodeHighlightConfigGridHighlightConfig :: OverlayGridHighlightConfig,
+    -- | Identifier of the node to highlight.
+    overlayGridNodeHighlightConfigNodeId :: DOMPageNetworkEmulationSecurity.DOMNodeId
+  }
+  deriving (Eq, Show)
+instance FromJSON OverlayGridNodeHighlightConfig where
+  parseJSON = A.withObject "OverlayGridNodeHighlightConfig" $ \o -> OverlayGridNodeHighlightConfig
+    <$> o A..: "gridHighlightConfig"
+    <*> o A..: "nodeId"
+instance ToJSON OverlayGridNodeHighlightConfig where
+  toJSON p = A.object $ catMaybes [
+    ("gridHighlightConfig" A..=) <$> Just (overlayGridNodeHighlightConfigGridHighlightConfig p),
+    ("nodeId" A..=) <$> Just (overlayGridNodeHighlightConfigNodeId p)
+    ]
+
+-- | Type 'Overlay.FlexNodeHighlightConfig'.
+data OverlayFlexNodeHighlightConfig = OverlayFlexNodeHighlightConfig
+  {
+    -- | A descriptor for the highlight appearance of flex containers.
+    overlayFlexNodeHighlightConfigFlexContainerHighlightConfig :: OverlayFlexContainerHighlightConfig,
+    -- | Identifier of the node to highlight.
+    overlayFlexNodeHighlightConfigNodeId :: DOMPageNetworkEmulationSecurity.DOMNodeId
+  }
+  deriving (Eq, Show)
+instance FromJSON OverlayFlexNodeHighlightConfig where
+  parseJSON = A.withObject "OverlayFlexNodeHighlightConfig" $ \o -> OverlayFlexNodeHighlightConfig
+    <$> o A..: "flexContainerHighlightConfig"
+    <*> o A..: "nodeId"
+instance ToJSON OverlayFlexNodeHighlightConfig where
+  toJSON p = A.object $ catMaybes [
+    ("flexContainerHighlightConfig" A..=) <$> Just (overlayFlexNodeHighlightConfigFlexContainerHighlightConfig p),
+    ("nodeId" A..=) <$> Just (overlayFlexNodeHighlightConfigNodeId p)
+    ]
+
+-- | Type 'Overlay.ScrollSnapContainerHighlightConfig'.
+data OverlayScrollSnapContainerHighlightConfig = OverlayScrollSnapContainerHighlightConfig
+  {
+    -- | The style of the snapport border (default: transparent)
+    overlayScrollSnapContainerHighlightConfigSnapportBorder :: Maybe OverlayLineStyle,
+    -- | The style of the snap area border (default: transparent)
+    overlayScrollSnapContainerHighlightConfigSnapAreaBorder :: Maybe OverlayLineStyle,
+    -- | The margin highlight fill color (default: transparent).
+    overlayScrollSnapContainerHighlightConfigScrollMarginColor :: Maybe DOMPageNetworkEmulationSecurity.DOMRGBA,
+    -- | The padding highlight fill color (default: transparent).
+    overlayScrollSnapContainerHighlightConfigScrollPaddingColor :: Maybe DOMPageNetworkEmulationSecurity.DOMRGBA
+  }
+  deriving (Eq, Show)
+instance FromJSON OverlayScrollSnapContainerHighlightConfig where
+  parseJSON = A.withObject "OverlayScrollSnapContainerHighlightConfig" $ \o -> OverlayScrollSnapContainerHighlightConfig
+    <$> o A..:? "snapportBorder"
+    <*> o A..:? "snapAreaBorder"
+    <*> o A..:? "scrollMarginColor"
+    <*> o A..:? "scrollPaddingColor"
+instance ToJSON OverlayScrollSnapContainerHighlightConfig where
+  toJSON p = A.object $ catMaybes [
+    ("snapportBorder" A..=) <$> (overlayScrollSnapContainerHighlightConfigSnapportBorder p),
+    ("snapAreaBorder" A..=) <$> (overlayScrollSnapContainerHighlightConfigSnapAreaBorder p),
+    ("scrollMarginColor" A..=) <$> (overlayScrollSnapContainerHighlightConfigScrollMarginColor p),
+    ("scrollPaddingColor" A..=) <$> (overlayScrollSnapContainerHighlightConfigScrollPaddingColor p)
+    ]
+
+-- | Type 'Overlay.ScrollSnapHighlightConfig'.
+data OverlayScrollSnapHighlightConfig = OverlayScrollSnapHighlightConfig
+  {
+    -- | A descriptor for the highlight appearance of scroll snap containers.
+    overlayScrollSnapHighlightConfigScrollSnapContainerHighlightConfig :: OverlayScrollSnapContainerHighlightConfig,
+    -- | Identifier of the node to highlight.
+    overlayScrollSnapHighlightConfigNodeId :: DOMPageNetworkEmulationSecurity.DOMNodeId
+  }
+  deriving (Eq, Show)
+instance FromJSON OverlayScrollSnapHighlightConfig where
+  parseJSON = A.withObject "OverlayScrollSnapHighlightConfig" $ \o -> OverlayScrollSnapHighlightConfig
+    <$> o A..: "scrollSnapContainerHighlightConfig"
+    <*> o A..: "nodeId"
+instance ToJSON OverlayScrollSnapHighlightConfig where
+  toJSON p = A.object $ catMaybes [
+    ("scrollSnapContainerHighlightConfig" A..=) <$> Just (overlayScrollSnapHighlightConfigScrollSnapContainerHighlightConfig p),
+    ("nodeId" A..=) <$> Just (overlayScrollSnapHighlightConfigNodeId p)
+    ]
+
+-- | Type 'Overlay.HingeConfig'.
+--   Configuration for dual screen hinge
+data OverlayHingeConfig = OverlayHingeConfig
+  {
+    -- | A rectangle represent hinge
+    overlayHingeConfigRect :: DOMPageNetworkEmulationSecurity.DOMRect,
+    -- | The content box highlight fill color (default: a dark color).
+    overlayHingeConfigContentColor :: Maybe DOMPageNetworkEmulationSecurity.DOMRGBA,
+    -- | The content box highlight outline color (default: transparent).
+    overlayHingeConfigOutlineColor :: Maybe DOMPageNetworkEmulationSecurity.DOMRGBA
+  }
+  deriving (Eq, Show)
+instance FromJSON OverlayHingeConfig where
+  parseJSON = A.withObject "OverlayHingeConfig" $ \o -> OverlayHingeConfig
+    <$> o A..: "rect"
+    <*> o A..:? "contentColor"
+    <*> o A..:? "outlineColor"
+instance ToJSON OverlayHingeConfig where
+  toJSON p = A.object $ catMaybes [
+    ("rect" A..=) <$> Just (overlayHingeConfigRect p),
+    ("contentColor" A..=) <$> (overlayHingeConfigContentColor p),
+    ("outlineColor" A..=) <$> (overlayHingeConfigOutlineColor p)
+    ]
+
+-- | Type 'Overlay.ContainerQueryHighlightConfig'.
+data OverlayContainerQueryHighlightConfig = OverlayContainerQueryHighlightConfig
+  {
+    -- | A descriptor for the highlight appearance of container query containers.
+    overlayContainerQueryHighlightConfigContainerQueryContainerHighlightConfig :: OverlayContainerQueryContainerHighlightConfig,
+    -- | Identifier of the container node to highlight.
+    overlayContainerQueryHighlightConfigNodeId :: DOMPageNetworkEmulationSecurity.DOMNodeId
+  }
+  deriving (Eq, Show)
+instance FromJSON OverlayContainerQueryHighlightConfig where
+  parseJSON = A.withObject "OverlayContainerQueryHighlightConfig" $ \o -> OverlayContainerQueryHighlightConfig
+    <$> o A..: "containerQueryContainerHighlightConfig"
+    <*> o A..: "nodeId"
+instance ToJSON OverlayContainerQueryHighlightConfig where
+  toJSON p = A.object $ catMaybes [
+    ("containerQueryContainerHighlightConfig" A..=) <$> Just (overlayContainerQueryHighlightConfigContainerQueryContainerHighlightConfig p),
+    ("nodeId" A..=) <$> Just (overlayContainerQueryHighlightConfigNodeId p)
+    ]
+
+-- | Type 'Overlay.ContainerQueryContainerHighlightConfig'.
+data OverlayContainerQueryContainerHighlightConfig = OverlayContainerQueryContainerHighlightConfig
+  {
+    -- | The style of the container border.
+    overlayContainerQueryContainerHighlightConfigContainerBorder :: Maybe OverlayLineStyle,
+    -- | The style of the descendants' borders.
+    overlayContainerQueryContainerHighlightConfigDescendantBorder :: Maybe OverlayLineStyle
+  }
+  deriving (Eq, Show)
+instance FromJSON OverlayContainerQueryContainerHighlightConfig where
+  parseJSON = A.withObject "OverlayContainerQueryContainerHighlightConfig" $ \o -> OverlayContainerQueryContainerHighlightConfig
+    <$> o A..:? "containerBorder"
+    <*> o A..:? "descendantBorder"
+instance ToJSON OverlayContainerQueryContainerHighlightConfig where
+  toJSON p = A.object $ catMaybes [
+    ("containerBorder" A..=) <$> (overlayContainerQueryContainerHighlightConfigContainerBorder p),
+    ("descendantBorder" A..=) <$> (overlayContainerQueryContainerHighlightConfigDescendantBorder p)
+    ]
+
+-- | Type 'Overlay.IsolatedElementHighlightConfig'.
+data OverlayIsolatedElementHighlightConfig = OverlayIsolatedElementHighlightConfig
+  {
+    -- | A descriptor for the highlight appearance of an element in isolation mode.
+    overlayIsolatedElementHighlightConfigIsolationModeHighlightConfig :: OverlayIsolationModeHighlightConfig,
+    -- | Identifier of the isolated element to highlight.
+    overlayIsolatedElementHighlightConfigNodeId :: DOMPageNetworkEmulationSecurity.DOMNodeId
+  }
+  deriving (Eq, Show)
+instance FromJSON OverlayIsolatedElementHighlightConfig where
+  parseJSON = A.withObject "OverlayIsolatedElementHighlightConfig" $ \o -> OverlayIsolatedElementHighlightConfig
+    <$> o A..: "isolationModeHighlightConfig"
+    <*> o A..: "nodeId"
+instance ToJSON OverlayIsolatedElementHighlightConfig where
+  toJSON p = A.object $ catMaybes [
+    ("isolationModeHighlightConfig" A..=) <$> Just (overlayIsolatedElementHighlightConfigIsolationModeHighlightConfig p),
+    ("nodeId" A..=) <$> Just (overlayIsolatedElementHighlightConfigNodeId p)
+    ]
+
+-- | Type 'Overlay.IsolationModeHighlightConfig'.
+data OverlayIsolationModeHighlightConfig = OverlayIsolationModeHighlightConfig
+  {
+    -- | The fill color of the resizers (default: transparent).
+    overlayIsolationModeHighlightConfigResizerColor :: Maybe DOMPageNetworkEmulationSecurity.DOMRGBA,
+    -- | The fill color for resizer handles (default: transparent).
+    overlayIsolationModeHighlightConfigResizerHandleColor :: Maybe DOMPageNetworkEmulationSecurity.DOMRGBA,
+    -- | The fill color for the mask covering non-isolated elements (default: transparent).
+    overlayIsolationModeHighlightConfigMaskColor :: Maybe DOMPageNetworkEmulationSecurity.DOMRGBA
+  }
+  deriving (Eq, Show)
+instance FromJSON OverlayIsolationModeHighlightConfig where
+  parseJSON = A.withObject "OverlayIsolationModeHighlightConfig" $ \o -> OverlayIsolationModeHighlightConfig
+    <$> o A..:? "resizerColor"
+    <*> o A..:? "resizerHandleColor"
+    <*> o A..:? "maskColor"
+instance ToJSON OverlayIsolationModeHighlightConfig where
+  toJSON p = A.object $ catMaybes [
+    ("resizerColor" A..=) <$> (overlayIsolationModeHighlightConfigResizerColor p),
+    ("resizerHandleColor" A..=) <$> (overlayIsolationModeHighlightConfigResizerHandleColor p),
+    ("maskColor" A..=) <$> (overlayIsolationModeHighlightConfigMaskColor p)
+    ]
+
+-- | Type 'Overlay.InspectMode'.
+data OverlayInspectMode = OverlayInspectModeSearchForNode | OverlayInspectModeSearchForUAShadowDOM | OverlayInspectModeCaptureAreaScreenshot | OverlayInspectModeShowDistances | OverlayInspectModeNone
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON OverlayInspectMode where
+  parseJSON = A.withText "OverlayInspectMode" $ \v -> case v of
+    "searchForNode" -> pure OverlayInspectModeSearchForNode
+    "searchForUAShadowDOM" -> pure OverlayInspectModeSearchForUAShadowDOM
+    "captureAreaScreenshot" -> pure OverlayInspectModeCaptureAreaScreenshot
+    "showDistances" -> pure OverlayInspectModeShowDistances
+    "none" -> pure OverlayInspectModeNone
+    "_" -> fail "failed to parse OverlayInspectMode"
+instance ToJSON OverlayInspectMode where
+  toJSON v = A.String $ case v of
+    OverlayInspectModeSearchForNode -> "searchForNode"
+    OverlayInspectModeSearchForUAShadowDOM -> "searchForUAShadowDOM"
+    OverlayInspectModeCaptureAreaScreenshot -> "captureAreaScreenshot"
+    OverlayInspectModeShowDistances -> "showDistances"
+    OverlayInspectModeNone -> "none"
+
+-- | Type of the 'Overlay.inspectNodeRequested' event.
+data OverlayInspectNodeRequested = OverlayInspectNodeRequested
+  {
+    -- | Id of the node to inspect.
+    overlayInspectNodeRequestedBackendNodeId :: DOMPageNetworkEmulationSecurity.DOMBackendNodeId
+  }
+  deriving (Eq, Show)
+instance FromJSON OverlayInspectNodeRequested where
+  parseJSON = A.withObject "OverlayInspectNodeRequested" $ \o -> OverlayInspectNodeRequested
+    <$> o A..: "backendNodeId"
+instance Event OverlayInspectNodeRequested where
+  eventName _ = "Overlay.inspectNodeRequested"
+
+-- | Type of the 'Overlay.nodeHighlightRequested' event.
+data OverlayNodeHighlightRequested = OverlayNodeHighlightRequested
+  {
+    overlayNodeHighlightRequestedNodeId :: DOMPageNetworkEmulationSecurity.DOMNodeId
+  }
+  deriving (Eq, Show)
+instance FromJSON OverlayNodeHighlightRequested where
+  parseJSON = A.withObject "OverlayNodeHighlightRequested" $ \o -> OverlayNodeHighlightRequested
+    <$> o A..: "nodeId"
+instance Event OverlayNodeHighlightRequested where
+  eventName _ = "Overlay.nodeHighlightRequested"
+
+-- | Type of the 'Overlay.screenshotRequested' event.
+data OverlayScreenshotRequested = OverlayScreenshotRequested
+  {
+    -- | Viewport to capture, in device independent pixels (dip).
+    overlayScreenshotRequestedViewport :: DOMPageNetworkEmulationSecurity.PageViewport
+  }
+  deriving (Eq, Show)
+instance FromJSON OverlayScreenshotRequested where
+  parseJSON = A.withObject "OverlayScreenshotRequested" $ \o -> OverlayScreenshotRequested
+    <$> o A..: "viewport"
+instance Event OverlayScreenshotRequested where
+  eventName _ = "Overlay.screenshotRequested"
+
+-- | Type of the 'Overlay.inspectModeCanceled' event.
+data OverlayInspectModeCanceled = OverlayInspectModeCanceled
+  deriving (Eq, Show, Read)
+instance FromJSON OverlayInspectModeCanceled where
+  parseJSON _ = pure OverlayInspectModeCanceled
+instance Event OverlayInspectModeCanceled where
+  eventName _ = "Overlay.inspectModeCanceled"
+
+-- | Disables domain notifications.
+
+-- | Parameters of the 'Overlay.disable' command.
+data POverlayDisable = POverlayDisable
+  deriving (Eq, Show)
+pOverlayDisable
+  :: POverlayDisable
+pOverlayDisable
+  = POverlayDisable
+instance ToJSON POverlayDisable where
+  toJSON _ = A.Null
+instance Command POverlayDisable where
+  type CommandResponse POverlayDisable = ()
+  commandName _ = "Overlay.disable"
+  fromJSON = const . A.Success . const ()
+
+-- | Enables domain notifications.
+
+-- | Parameters of the 'Overlay.enable' command.
+data POverlayEnable = POverlayEnable
+  deriving (Eq, Show)
+pOverlayEnable
+  :: POverlayEnable
+pOverlayEnable
+  = POverlayEnable
+instance ToJSON POverlayEnable where
+  toJSON _ = A.Null
+instance Command POverlayEnable where
+  type CommandResponse POverlayEnable = ()
+  commandName _ = "Overlay.enable"
+  fromJSON = const . A.Success . const ()
+
+-- | For testing.
+
+-- | Parameters of the 'Overlay.getHighlightObjectForTest' command.
+data POverlayGetHighlightObjectForTest = POverlayGetHighlightObjectForTest
+  {
+    -- | Id of the node to get highlight object for.
+    pOverlayGetHighlightObjectForTestNodeId :: DOMPageNetworkEmulationSecurity.DOMNodeId,
+    -- | Whether to include distance info.
+    pOverlayGetHighlightObjectForTestIncludeDistance :: Maybe Bool,
+    -- | Whether to include style info.
+    pOverlayGetHighlightObjectForTestIncludeStyle :: Maybe Bool,
+    -- | The color format to get config with (default: hex).
+    pOverlayGetHighlightObjectForTestColorFormat :: Maybe OverlayColorFormat,
+    -- | Whether to show accessibility info (default: true).
+    pOverlayGetHighlightObjectForTestShowAccessibilityInfo :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pOverlayGetHighlightObjectForTest
+  {-
+  -- | Id of the node to get highlight object for.
+  -}
+  :: DOMPageNetworkEmulationSecurity.DOMNodeId
+  -> POverlayGetHighlightObjectForTest
+pOverlayGetHighlightObjectForTest
+  arg_pOverlayGetHighlightObjectForTestNodeId
+  = POverlayGetHighlightObjectForTest
+    arg_pOverlayGetHighlightObjectForTestNodeId
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON POverlayGetHighlightObjectForTest where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> Just (pOverlayGetHighlightObjectForTestNodeId p),
+    ("includeDistance" A..=) <$> (pOverlayGetHighlightObjectForTestIncludeDistance p),
+    ("includeStyle" A..=) <$> (pOverlayGetHighlightObjectForTestIncludeStyle p),
+    ("colorFormat" A..=) <$> (pOverlayGetHighlightObjectForTestColorFormat p),
+    ("showAccessibilityInfo" A..=) <$> (pOverlayGetHighlightObjectForTestShowAccessibilityInfo p)
+    ]
+data OverlayGetHighlightObjectForTest = OverlayGetHighlightObjectForTest
+  {
+    -- | Highlight data for the node.
+    overlayGetHighlightObjectForTestHighlight :: [(T.Text, T.Text)]
+  }
+  deriving (Eq, Show)
+instance FromJSON OverlayGetHighlightObjectForTest where
+  parseJSON = A.withObject "OverlayGetHighlightObjectForTest" $ \o -> OverlayGetHighlightObjectForTest
+    <$> o A..: "highlight"
+instance Command POverlayGetHighlightObjectForTest where
+  type CommandResponse POverlayGetHighlightObjectForTest = OverlayGetHighlightObjectForTest
+  commandName _ = "Overlay.getHighlightObjectForTest"
+
+-- | For Persistent Grid testing.
+
+-- | Parameters of the 'Overlay.getGridHighlightObjectsForTest' command.
+data POverlayGetGridHighlightObjectsForTest = POverlayGetGridHighlightObjectsForTest
+  {
+    -- | Ids of the node to get highlight object for.
+    pOverlayGetGridHighlightObjectsForTestNodeIds :: [DOMPageNetworkEmulationSecurity.DOMNodeId]
+  }
+  deriving (Eq, Show)
+pOverlayGetGridHighlightObjectsForTest
+  {-
+  -- | Ids of the node to get highlight object for.
+  -}
+  :: [DOMPageNetworkEmulationSecurity.DOMNodeId]
+  -> POverlayGetGridHighlightObjectsForTest
+pOverlayGetGridHighlightObjectsForTest
+  arg_pOverlayGetGridHighlightObjectsForTestNodeIds
+  = POverlayGetGridHighlightObjectsForTest
+    arg_pOverlayGetGridHighlightObjectsForTestNodeIds
+instance ToJSON POverlayGetGridHighlightObjectsForTest where
+  toJSON p = A.object $ catMaybes [
+    ("nodeIds" A..=) <$> Just (pOverlayGetGridHighlightObjectsForTestNodeIds p)
+    ]
+data OverlayGetGridHighlightObjectsForTest = OverlayGetGridHighlightObjectsForTest
+  {
+    -- | Grid Highlight data for the node ids provided.
+    overlayGetGridHighlightObjectsForTestHighlights :: [(T.Text, T.Text)]
+  }
+  deriving (Eq, Show)
+instance FromJSON OverlayGetGridHighlightObjectsForTest where
+  parseJSON = A.withObject "OverlayGetGridHighlightObjectsForTest" $ \o -> OverlayGetGridHighlightObjectsForTest
+    <$> o A..: "highlights"
+instance Command POverlayGetGridHighlightObjectsForTest where
+  type CommandResponse POverlayGetGridHighlightObjectsForTest = OverlayGetGridHighlightObjectsForTest
+  commandName _ = "Overlay.getGridHighlightObjectsForTest"
+
+-- | For Source Order Viewer testing.
+
+-- | Parameters of the 'Overlay.getSourceOrderHighlightObjectForTest' command.
+data POverlayGetSourceOrderHighlightObjectForTest = POverlayGetSourceOrderHighlightObjectForTest
+  {
+    -- | Id of the node to highlight.
+    pOverlayGetSourceOrderHighlightObjectForTestNodeId :: DOMPageNetworkEmulationSecurity.DOMNodeId
+  }
+  deriving (Eq, Show)
+pOverlayGetSourceOrderHighlightObjectForTest
+  {-
+  -- | Id of the node to highlight.
+  -}
+  :: DOMPageNetworkEmulationSecurity.DOMNodeId
+  -> POverlayGetSourceOrderHighlightObjectForTest
+pOverlayGetSourceOrderHighlightObjectForTest
+  arg_pOverlayGetSourceOrderHighlightObjectForTestNodeId
+  = POverlayGetSourceOrderHighlightObjectForTest
+    arg_pOverlayGetSourceOrderHighlightObjectForTestNodeId
+instance ToJSON POverlayGetSourceOrderHighlightObjectForTest where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> Just (pOverlayGetSourceOrderHighlightObjectForTestNodeId p)
+    ]
+data OverlayGetSourceOrderHighlightObjectForTest = OverlayGetSourceOrderHighlightObjectForTest
+  {
+    -- | Source order highlight data for the node id provided.
+    overlayGetSourceOrderHighlightObjectForTestHighlight :: [(T.Text, T.Text)]
+  }
+  deriving (Eq, Show)
+instance FromJSON OverlayGetSourceOrderHighlightObjectForTest where
+  parseJSON = A.withObject "OverlayGetSourceOrderHighlightObjectForTest" $ \o -> OverlayGetSourceOrderHighlightObjectForTest
+    <$> o A..: "highlight"
+instance Command POverlayGetSourceOrderHighlightObjectForTest where
+  type CommandResponse POverlayGetSourceOrderHighlightObjectForTest = OverlayGetSourceOrderHighlightObjectForTest
+  commandName _ = "Overlay.getSourceOrderHighlightObjectForTest"
+
+-- | Hides any highlight.
+
+-- | Parameters of the 'Overlay.hideHighlight' command.
+data POverlayHideHighlight = POverlayHideHighlight
+  deriving (Eq, Show)
+pOverlayHideHighlight
+  :: POverlayHideHighlight
+pOverlayHideHighlight
+  = POverlayHideHighlight
+instance ToJSON POverlayHideHighlight where
+  toJSON _ = A.Null
+instance Command POverlayHideHighlight where
+  type CommandResponse POverlayHideHighlight = ()
+  commandName _ = "Overlay.hideHighlight"
+  fromJSON = const . A.Success . const ()
+
+-- | Highlights DOM node with given id or with the given JavaScript object wrapper. Either nodeId or
+--   objectId must be specified.
+
+-- | Parameters of the 'Overlay.highlightNode' command.
+data POverlayHighlightNode = POverlayHighlightNode
+  {
+    -- | A descriptor for the highlight appearance.
+    pOverlayHighlightNodeHighlightConfig :: OverlayHighlightConfig,
+    -- | Identifier of the node to highlight.
+    pOverlayHighlightNodeNodeId :: Maybe DOMPageNetworkEmulationSecurity.DOMNodeId,
+    -- | Identifier of the backend node to highlight.
+    pOverlayHighlightNodeBackendNodeId :: Maybe DOMPageNetworkEmulationSecurity.DOMBackendNodeId,
+    -- | JavaScript object id of the node to be highlighted.
+    pOverlayHighlightNodeObjectId :: Maybe Runtime.RuntimeRemoteObjectId,
+    -- | Selectors to highlight relevant nodes.
+    pOverlayHighlightNodeSelector :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+pOverlayHighlightNode
+  {-
+  -- | A descriptor for the highlight appearance.
+  -}
+  :: OverlayHighlightConfig
+  -> POverlayHighlightNode
+pOverlayHighlightNode
+  arg_pOverlayHighlightNodeHighlightConfig
+  = POverlayHighlightNode
+    arg_pOverlayHighlightNodeHighlightConfig
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON POverlayHighlightNode where
+  toJSON p = A.object $ catMaybes [
+    ("highlightConfig" A..=) <$> Just (pOverlayHighlightNodeHighlightConfig p),
+    ("nodeId" A..=) <$> (pOverlayHighlightNodeNodeId p),
+    ("backendNodeId" A..=) <$> (pOverlayHighlightNodeBackendNodeId p),
+    ("objectId" A..=) <$> (pOverlayHighlightNodeObjectId p),
+    ("selector" A..=) <$> (pOverlayHighlightNodeSelector p)
+    ]
+instance Command POverlayHighlightNode where
+  type CommandResponse POverlayHighlightNode = ()
+  commandName _ = "Overlay.highlightNode"
+  fromJSON = const . A.Success . const ()
+
+-- | Highlights given quad. Coordinates are absolute with respect to the main frame viewport.
+
+-- | Parameters of the 'Overlay.highlightQuad' command.
+data POverlayHighlightQuad = POverlayHighlightQuad
+  {
+    -- | Quad to highlight
+    pOverlayHighlightQuadQuad :: DOMPageNetworkEmulationSecurity.DOMQuad,
+    -- | The highlight fill color (default: transparent).
+    pOverlayHighlightQuadColor :: Maybe DOMPageNetworkEmulationSecurity.DOMRGBA,
+    -- | The highlight outline color (default: transparent).
+    pOverlayHighlightQuadOutlineColor :: Maybe DOMPageNetworkEmulationSecurity.DOMRGBA
+  }
+  deriving (Eq, Show)
+pOverlayHighlightQuad
+  {-
+  -- | Quad to highlight
+  -}
+  :: DOMPageNetworkEmulationSecurity.DOMQuad
+  -> POverlayHighlightQuad
+pOverlayHighlightQuad
+  arg_pOverlayHighlightQuadQuad
+  = POverlayHighlightQuad
+    arg_pOverlayHighlightQuadQuad
+    Nothing
+    Nothing
+instance ToJSON POverlayHighlightQuad where
+  toJSON p = A.object $ catMaybes [
+    ("quad" A..=) <$> Just (pOverlayHighlightQuadQuad p),
+    ("color" A..=) <$> (pOverlayHighlightQuadColor p),
+    ("outlineColor" A..=) <$> (pOverlayHighlightQuadOutlineColor p)
+    ]
+instance Command POverlayHighlightQuad where
+  type CommandResponse POverlayHighlightQuad = ()
+  commandName _ = "Overlay.highlightQuad"
+  fromJSON = const . A.Success . const ()
+
+-- | Highlights given rectangle. Coordinates are absolute with respect to the main frame viewport.
+
+-- | Parameters of the 'Overlay.highlightRect' command.
+data POverlayHighlightRect = POverlayHighlightRect
+  {
+    -- | X coordinate
+    pOverlayHighlightRectX :: Int,
+    -- | Y coordinate
+    pOverlayHighlightRectY :: Int,
+    -- | Rectangle width
+    pOverlayHighlightRectWidth :: Int,
+    -- | Rectangle height
+    pOverlayHighlightRectHeight :: Int,
+    -- | The highlight fill color (default: transparent).
+    pOverlayHighlightRectColor :: Maybe DOMPageNetworkEmulationSecurity.DOMRGBA,
+    -- | The highlight outline color (default: transparent).
+    pOverlayHighlightRectOutlineColor :: Maybe DOMPageNetworkEmulationSecurity.DOMRGBA
+  }
+  deriving (Eq, Show)
+pOverlayHighlightRect
+  {-
+  -- | X coordinate
+  -}
+  :: Int
+  {-
+  -- | Y coordinate
+  -}
+  -> Int
+  {-
+  -- | Rectangle width
+  -}
+  -> Int
+  {-
+  -- | Rectangle height
+  -}
+  -> Int
+  -> POverlayHighlightRect
+pOverlayHighlightRect
+  arg_pOverlayHighlightRectX
+  arg_pOverlayHighlightRectY
+  arg_pOverlayHighlightRectWidth
+  arg_pOverlayHighlightRectHeight
+  = POverlayHighlightRect
+    arg_pOverlayHighlightRectX
+    arg_pOverlayHighlightRectY
+    arg_pOverlayHighlightRectWidth
+    arg_pOverlayHighlightRectHeight
+    Nothing
+    Nothing
+instance ToJSON POverlayHighlightRect where
+  toJSON p = A.object $ catMaybes [
+    ("x" A..=) <$> Just (pOverlayHighlightRectX p),
+    ("y" A..=) <$> Just (pOverlayHighlightRectY p),
+    ("width" A..=) <$> Just (pOverlayHighlightRectWidth p),
+    ("height" A..=) <$> Just (pOverlayHighlightRectHeight p),
+    ("color" A..=) <$> (pOverlayHighlightRectColor p),
+    ("outlineColor" A..=) <$> (pOverlayHighlightRectOutlineColor p)
+    ]
+instance Command POverlayHighlightRect where
+  type CommandResponse POverlayHighlightRect = ()
+  commandName _ = "Overlay.highlightRect"
+  fromJSON = const . A.Success . const ()
+
+-- | Highlights the source order of the children of the DOM node with given id or with the given
+--   JavaScript object wrapper. Either nodeId or objectId must be specified.
+
+-- | Parameters of the 'Overlay.highlightSourceOrder' command.
+data POverlayHighlightSourceOrder = POverlayHighlightSourceOrder
+  {
+    -- | A descriptor for the appearance of the overlay drawing.
+    pOverlayHighlightSourceOrderSourceOrderConfig :: OverlaySourceOrderConfig,
+    -- | Identifier of the node to highlight.
+    pOverlayHighlightSourceOrderNodeId :: Maybe DOMPageNetworkEmulationSecurity.DOMNodeId,
+    -- | Identifier of the backend node to highlight.
+    pOverlayHighlightSourceOrderBackendNodeId :: Maybe DOMPageNetworkEmulationSecurity.DOMBackendNodeId,
+    -- | JavaScript object id of the node to be highlighted.
+    pOverlayHighlightSourceOrderObjectId :: Maybe Runtime.RuntimeRemoteObjectId
+  }
+  deriving (Eq, Show)
+pOverlayHighlightSourceOrder
+  {-
+  -- | A descriptor for the appearance of the overlay drawing.
+  -}
+  :: OverlaySourceOrderConfig
+  -> POverlayHighlightSourceOrder
+pOverlayHighlightSourceOrder
+  arg_pOverlayHighlightSourceOrderSourceOrderConfig
+  = POverlayHighlightSourceOrder
+    arg_pOverlayHighlightSourceOrderSourceOrderConfig
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON POverlayHighlightSourceOrder where
+  toJSON p = A.object $ catMaybes [
+    ("sourceOrderConfig" A..=) <$> Just (pOverlayHighlightSourceOrderSourceOrderConfig p),
+    ("nodeId" A..=) <$> (pOverlayHighlightSourceOrderNodeId p),
+    ("backendNodeId" A..=) <$> (pOverlayHighlightSourceOrderBackendNodeId p),
+    ("objectId" A..=) <$> (pOverlayHighlightSourceOrderObjectId p)
+    ]
+instance Command POverlayHighlightSourceOrder where
+  type CommandResponse POverlayHighlightSourceOrder = ()
+  commandName _ = "Overlay.highlightSourceOrder"
+  fromJSON = const . A.Success . const ()
+
+-- | Enters the 'inspect' mode. In this mode, elements that user is hovering over are highlighted.
+--   Backend then generates 'inspectNodeRequested' event upon element selection.
+
+-- | Parameters of the 'Overlay.setInspectMode' command.
+data POverlaySetInspectMode = POverlaySetInspectMode
+  {
+    -- | Set an inspection mode.
+    pOverlaySetInspectModeMode :: OverlayInspectMode,
+    -- | A descriptor for the highlight appearance of hovered-over nodes. May be omitted if `enabled
+    --   == false`.
+    pOverlaySetInspectModeHighlightConfig :: Maybe OverlayHighlightConfig
+  }
+  deriving (Eq, Show)
+pOverlaySetInspectMode
+  {-
+  -- | Set an inspection mode.
+  -}
+  :: OverlayInspectMode
+  -> POverlaySetInspectMode
+pOverlaySetInspectMode
+  arg_pOverlaySetInspectModeMode
+  = POverlaySetInspectMode
+    arg_pOverlaySetInspectModeMode
+    Nothing
+instance ToJSON POverlaySetInspectMode where
+  toJSON p = A.object $ catMaybes [
+    ("mode" A..=) <$> Just (pOverlaySetInspectModeMode p),
+    ("highlightConfig" A..=) <$> (pOverlaySetInspectModeHighlightConfig p)
+    ]
+instance Command POverlaySetInspectMode where
+  type CommandResponse POverlaySetInspectMode = ()
+  commandName _ = "Overlay.setInspectMode"
+  fromJSON = const . A.Success . const ()
+
+-- | Highlights owner element of all frames detected to be ads.
+
+-- | Parameters of the 'Overlay.setShowAdHighlights' command.
+data POverlaySetShowAdHighlights = POverlaySetShowAdHighlights
+  {
+    -- | True for showing ad highlights
+    pOverlaySetShowAdHighlightsShow :: Bool
+  }
+  deriving (Eq, Show)
+pOverlaySetShowAdHighlights
+  {-
+  -- | True for showing ad highlights
+  -}
+  :: Bool
+  -> POverlaySetShowAdHighlights
+pOverlaySetShowAdHighlights
+  arg_pOverlaySetShowAdHighlightsShow
+  = POverlaySetShowAdHighlights
+    arg_pOverlaySetShowAdHighlightsShow
+instance ToJSON POverlaySetShowAdHighlights where
+  toJSON p = A.object $ catMaybes [
+    ("show" A..=) <$> Just (pOverlaySetShowAdHighlightsShow p)
+    ]
+instance Command POverlaySetShowAdHighlights where
+  type CommandResponse POverlaySetShowAdHighlights = ()
+  commandName _ = "Overlay.setShowAdHighlights"
+  fromJSON = const . A.Success . const ()
+
+
+-- | Parameters of the 'Overlay.setPausedInDebuggerMessage' command.
+data POverlaySetPausedInDebuggerMessage = POverlaySetPausedInDebuggerMessage
+  {
+    -- | The message to display, also triggers resume and step over controls.
+    pOverlaySetPausedInDebuggerMessageMessage :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+pOverlaySetPausedInDebuggerMessage
+  :: POverlaySetPausedInDebuggerMessage
+pOverlaySetPausedInDebuggerMessage
+  = POverlaySetPausedInDebuggerMessage
+    Nothing
+instance ToJSON POverlaySetPausedInDebuggerMessage where
+  toJSON p = A.object $ catMaybes [
+    ("message" A..=) <$> (pOverlaySetPausedInDebuggerMessageMessage p)
+    ]
+instance Command POverlaySetPausedInDebuggerMessage where
+  type CommandResponse POverlaySetPausedInDebuggerMessage = ()
+  commandName _ = "Overlay.setPausedInDebuggerMessage"
+  fromJSON = const . A.Success . const ()
+
+-- | Requests that backend shows debug borders on layers
+
+-- | Parameters of the 'Overlay.setShowDebugBorders' command.
+data POverlaySetShowDebugBorders = POverlaySetShowDebugBorders
+  {
+    -- | True for showing debug borders
+    pOverlaySetShowDebugBordersShow :: Bool
+  }
+  deriving (Eq, Show)
+pOverlaySetShowDebugBorders
+  {-
+  -- | True for showing debug borders
+  -}
+  :: Bool
+  -> POverlaySetShowDebugBorders
+pOverlaySetShowDebugBorders
+  arg_pOverlaySetShowDebugBordersShow
+  = POverlaySetShowDebugBorders
+    arg_pOverlaySetShowDebugBordersShow
+instance ToJSON POverlaySetShowDebugBorders where
+  toJSON p = A.object $ catMaybes [
+    ("show" A..=) <$> Just (pOverlaySetShowDebugBordersShow p)
+    ]
+instance Command POverlaySetShowDebugBorders where
+  type CommandResponse POverlaySetShowDebugBorders = ()
+  commandName _ = "Overlay.setShowDebugBorders"
+  fromJSON = const . A.Success . const ()
+
+-- | Requests that backend shows the FPS counter
+
+-- | Parameters of the 'Overlay.setShowFPSCounter' command.
+data POverlaySetShowFPSCounter = POverlaySetShowFPSCounter
+  {
+    -- | True for showing the FPS counter
+    pOverlaySetShowFPSCounterShow :: Bool
+  }
+  deriving (Eq, Show)
+pOverlaySetShowFPSCounter
+  {-
+  -- | True for showing the FPS counter
+  -}
+  :: Bool
+  -> POverlaySetShowFPSCounter
+pOverlaySetShowFPSCounter
+  arg_pOverlaySetShowFPSCounterShow
+  = POverlaySetShowFPSCounter
+    arg_pOverlaySetShowFPSCounterShow
+instance ToJSON POverlaySetShowFPSCounter where
+  toJSON p = A.object $ catMaybes [
+    ("show" A..=) <$> Just (pOverlaySetShowFPSCounterShow p)
+    ]
+instance Command POverlaySetShowFPSCounter where
+  type CommandResponse POverlaySetShowFPSCounter = ()
+  commandName _ = "Overlay.setShowFPSCounter"
+  fromJSON = const . A.Success . const ()
+
+-- | Highlight multiple elements with the CSS Grid overlay.
+
+-- | Parameters of the 'Overlay.setShowGridOverlays' command.
+data POverlaySetShowGridOverlays = POverlaySetShowGridOverlays
+  {
+    -- | An array of node identifiers and descriptors for the highlight appearance.
+    pOverlaySetShowGridOverlaysGridNodeHighlightConfigs :: [OverlayGridNodeHighlightConfig]
+  }
+  deriving (Eq, Show)
+pOverlaySetShowGridOverlays
+  {-
+  -- | An array of node identifiers and descriptors for the highlight appearance.
+  -}
+  :: [OverlayGridNodeHighlightConfig]
+  -> POverlaySetShowGridOverlays
+pOverlaySetShowGridOverlays
+  arg_pOverlaySetShowGridOverlaysGridNodeHighlightConfigs
+  = POverlaySetShowGridOverlays
+    arg_pOverlaySetShowGridOverlaysGridNodeHighlightConfigs
+instance ToJSON POverlaySetShowGridOverlays where
+  toJSON p = A.object $ catMaybes [
+    ("gridNodeHighlightConfigs" A..=) <$> Just (pOverlaySetShowGridOverlaysGridNodeHighlightConfigs p)
+    ]
+instance Command POverlaySetShowGridOverlays where
+  type CommandResponse POverlaySetShowGridOverlays = ()
+  commandName _ = "Overlay.setShowGridOverlays"
+  fromJSON = const . A.Success . const ()
+
+
+-- | Parameters of the 'Overlay.setShowFlexOverlays' command.
+data POverlaySetShowFlexOverlays = POverlaySetShowFlexOverlays
+  {
+    -- | An array of node identifiers and descriptors for the highlight appearance.
+    pOverlaySetShowFlexOverlaysFlexNodeHighlightConfigs :: [OverlayFlexNodeHighlightConfig]
+  }
+  deriving (Eq, Show)
+pOverlaySetShowFlexOverlays
+  {-
+  -- | An array of node identifiers and descriptors for the highlight appearance.
+  -}
+  :: [OverlayFlexNodeHighlightConfig]
+  -> POverlaySetShowFlexOverlays
+pOverlaySetShowFlexOverlays
+  arg_pOverlaySetShowFlexOverlaysFlexNodeHighlightConfigs
+  = POverlaySetShowFlexOverlays
+    arg_pOverlaySetShowFlexOverlaysFlexNodeHighlightConfigs
+instance ToJSON POverlaySetShowFlexOverlays where
+  toJSON p = A.object $ catMaybes [
+    ("flexNodeHighlightConfigs" A..=) <$> Just (pOverlaySetShowFlexOverlaysFlexNodeHighlightConfigs p)
+    ]
+instance Command POverlaySetShowFlexOverlays where
+  type CommandResponse POverlaySetShowFlexOverlays = ()
+  commandName _ = "Overlay.setShowFlexOverlays"
+  fromJSON = const . A.Success . const ()
+
+
+-- | Parameters of the 'Overlay.setShowScrollSnapOverlays' command.
+data POverlaySetShowScrollSnapOverlays = POverlaySetShowScrollSnapOverlays
+  {
+    -- | An array of node identifiers and descriptors for the highlight appearance.
+    pOverlaySetShowScrollSnapOverlaysScrollSnapHighlightConfigs :: [OverlayScrollSnapHighlightConfig]
+  }
+  deriving (Eq, Show)
+pOverlaySetShowScrollSnapOverlays
+  {-
+  -- | An array of node identifiers and descriptors for the highlight appearance.
+  -}
+  :: [OverlayScrollSnapHighlightConfig]
+  -> POverlaySetShowScrollSnapOverlays
+pOverlaySetShowScrollSnapOverlays
+  arg_pOverlaySetShowScrollSnapOverlaysScrollSnapHighlightConfigs
+  = POverlaySetShowScrollSnapOverlays
+    arg_pOverlaySetShowScrollSnapOverlaysScrollSnapHighlightConfigs
+instance ToJSON POverlaySetShowScrollSnapOverlays where
+  toJSON p = A.object $ catMaybes [
+    ("scrollSnapHighlightConfigs" A..=) <$> Just (pOverlaySetShowScrollSnapOverlaysScrollSnapHighlightConfigs p)
+    ]
+instance Command POverlaySetShowScrollSnapOverlays where
+  type CommandResponse POverlaySetShowScrollSnapOverlays = ()
+  commandName _ = "Overlay.setShowScrollSnapOverlays"
+  fromJSON = const . A.Success . const ()
+
+
+-- | Parameters of the 'Overlay.setShowContainerQueryOverlays' command.
+data POverlaySetShowContainerQueryOverlays = POverlaySetShowContainerQueryOverlays
+  {
+    -- | An array of node identifiers and descriptors for the highlight appearance.
+    pOverlaySetShowContainerQueryOverlaysContainerQueryHighlightConfigs :: [OverlayContainerQueryHighlightConfig]
+  }
+  deriving (Eq, Show)
+pOverlaySetShowContainerQueryOverlays
+  {-
+  -- | An array of node identifiers and descriptors for the highlight appearance.
+  -}
+  :: [OverlayContainerQueryHighlightConfig]
+  -> POverlaySetShowContainerQueryOverlays
+pOverlaySetShowContainerQueryOverlays
+  arg_pOverlaySetShowContainerQueryOverlaysContainerQueryHighlightConfigs
+  = POverlaySetShowContainerQueryOverlays
+    arg_pOverlaySetShowContainerQueryOverlaysContainerQueryHighlightConfigs
+instance ToJSON POverlaySetShowContainerQueryOverlays where
+  toJSON p = A.object $ catMaybes [
+    ("containerQueryHighlightConfigs" A..=) <$> Just (pOverlaySetShowContainerQueryOverlaysContainerQueryHighlightConfigs p)
+    ]
+instance Command POverlaySetShowContainerQueryOverlays where
+  type CommandResponse POverlaySetShowContainerQueryOverlays = ()
+  commandName _ = "Overlay.setShowContainerQueryOverlays"
+  fromJSON = const . A.Success . const ()
+
+-- | Requests that backend shows paint rectangles
+
+-- | Parameters of the 'Overlay.setShowPaintRects' command.
+data POverlaySetShowPaintRects = POverlaySetShowPaintRects
+  {
+    -- | True for showing paint rectangles
+    pOverlaySetShowPaintRectsResult :: Bool
+  }
+  deriving (Eq, Show)
+pOverlaySetShowPaintRects
+  {-
+  -- | True for showing paint rectangles
+  -}
+  :: Bool
+  -> POverlaySetShowPaintRects
+pOverlaySetShowPaintRects
+  arg_pOverlaySetShowPaintRectsResult
+  = POverlaySetShowPaintRects
+    arg_pOverlaySetShowPaintRectsResult
+instance ToJSON POverlaySetShowPaintRects where
+  toJSON p = A.object $ catMaybes [
+    ("result" A..=) <$> Just (pOverlaySetShowPaintRectsResult p)
+    ]
+instance Command POverlaySetShowPaintRects where
+  type CommandResponse POverlaySetShowPaintRects = ()
+  commandName _ = "Overlay.setShowPaintRects"
+  fromJSON = const . A.Success . const ()
+
+-- | Requests that backend shows layout shift regions
+
+-- | Parameters of the 'Overlay.setShowLayoutShiftRegions' command.
+data POverlaySetShowLayoutShiftRegions = POverlaySetShowLayoutShiftRegions
+  {
+    -- | True for showing layout shift regions
+    pOverlaySetShowLayoutShiftRegionsResult :: Bool
+  }
+  deriving (Eq, Show)
+pOverlaySetShowLayoutShiftRegions
+  {-
+  -- | True for showing layout shift regions
+  -}
+  :: Bool
+  -> POverlaySetShowLayoutShiftRegions
+pOverlaySetShowLayoutShiftRegions
+  arg_pOverlaySetShowLayoutShiftRegionsResult
+  = POverlaySetShowLayoutShiftRegions
+    arg_pOverlaySetShowLayoutShiftRegionsResult
+instance ToJSON POverlaySetShowLayoutShiftRegions where
+  toJSON p = A.object $ catMaybes [
+    ("result" A..=) <$> Just (pOverlaySetShowLayoutShiftRegionsResult p)
+    ]
+instance Command POverlaySetShowLayoutShiftRegions where
+  type CommandResponse POverlaySetShowLayoutShiftRegions = ()
+  commandName _ = "Overlay.setShowLayoutShiftRegions"
+  fromJSON = const . A.Success . const ()
+
+-- | Requests that backend shows scroll bottleneck rects
+
+-- | Parameters of the 'Overlay.setShowScrollBottleneckRects' command.
+data POverlaySetShowScrollBottleneckRects = POverlaySetShowScrollBottleneckRects
+  {
+    -- | True for showing scroll bottleneck rects
+    pOverlaySetShowScrollBottleneckRectsShow :: Bool
+  }
+  deriving (Eq, Show)
+pOverlaySetShowScrollBottleneckRects
+  {-
+  -- | True for showing scroll bottleneck rects
+  -}
+  :: Bool
+  -> POverlaySetShowScrollBottleneckRects
+pOverlaySetShowScrollBottleneckRects
+  arg_pOverlaySetShowScrollBottleneckRectsShow
+  = POverlaySetShowScrollBottleneckRects
+    arg_pOverlaySetShowScrollBottleneckRectsShow
+instance ToJSON POverlaySetShowScrollBottleneckRects where
+  toJSON p = A.object $ catMaybes [
+    ("show" A..=) <$> Just (pOverlaySetShowScrollBottleneckRectsShow p)
+    ]
+instance Command POverlaySetShowScrollBottleneckRects where
+  type CommandResponse POverlaySetShowScrollBottleneckRects = ()
+  commandName _ = "Overlay.setShowScrollBottleneckRects"
+  fromJSON = const . A.Success . const ()
+
+-- | Request that backend shows an overlay with web vital metrics.
+
+-- | Parameters of the 'Overlay.setShowWebVitals' command.
+data POverlaySetShowWebVitals = POverlaySetShowWebVitals
+  {
+    pOverlaySetShowWebVitalsShow :: Bool
+  }
+  deriving (Eq, Show)
+pOverlaySetShowWebVitals
+  :: Bool
+  -> POverlaySetShowWebVitals
+pOverlaySetShowWebVitals
+  arg_pOverlaySetShowWebVitalsShow
+  = POverlaySetShowWebVitals
+    arg_pOverlaySetShowWebVitalsShow
+instance ToJSON POverlaySetShowWebVitals where
+  toJSON p = A.object $ catMaybes [
+    ("show" A..=) <$> Just (pOverlaySetShowWebVitalsShow p)
+    ]
+instance Command POverlaySetShowWebVitals where
+  type CommandResponse POverlaySetShowWebVitals = ()
+  commandName _ = "Overlay.setShowWebVitals"
+  fromJSON = const . A.Success . const ()
+
+-- | Paints viewport size upon main frame resize.
+
+-- | Parameters of the 'Overlay.setShowViewportSizeOnResize' command.
+data POverlaySetShowViewportSizeOnResize = POverlaySetShowViewportSizeOnResize
+  {
+    -- | Whether to paint size or not.
+    pOverlaySetShowViewportSizeOnResizeShow :: Bool
+  }
+  deriving (Eq, Show)
+pOverlaySetShowViewportSizeOnResize
+  {-
+  -- | Whether to paint size or not.
+  -}
+  :: Bool
+  -> POverlaySetShowViewportSizeOnResize
+pOverlaySetShowViewportSizeOnResize
+  arg_pOverlaySetShowViewportSizeOnResizeShow
+  = POverlaySetShowViewportSizeOnResize
+    arg_pOverlaySetShowViewportSizeOnResizeShow
+instance ToJSON POverlaySetShowViewportSizeOnResize where
+  toJSON p = A.object $ catMaybes [
+    ("show" A..=) <$> Just (pOverlaySetShowViewportSizeOnResizeShow p)
+    ]
+instance Command POverlaySetShowViewportSizeOnResize where
+  type CommandResponse POverlaySetShowViewportSizeOnResize = ()
+  commandName _ = "Overlay.setShowViewportSizeOnResize"
+  fromJSON = const . A.Success . const ()
+
+-- | Add a dual screen device hinge
+
+-- | Parameters of the 'Overlay.setShowHinge' command.
+data POverlaySetShowHinge = POverlaySetShowHinge
+  {
+    -- | hinge data, null means hideHinge
+    pOverlaySetShowHingeHingeConfig :: Maybe OverlayHingeConfig
+  }
+  deriving (Eq, Show)
+pOverlaySetShowHinge
+  :: POverlaySetShowHinge
+pOverlaySetShowHinge
+  = POverlaySetShowHinge
+    Nothing
+instance ToJSON POverlaySetShowHinge where
+  toJSON p = A.object $ catMaybes [
+    ("hingeConfig" A..=) <$> (pOverlaySetShowHingeHingeConfig p)
+    ]
+instance Command POverlaySetShowHinge where
+  type CommandResponse POverlaySetShowHinge = ()
+  commandName _ = "Overlay.setShowHinge"
+  fromJSON = const . A.Success . const ()
+
+-- | Show elements in isolation mode with overlays.
+
+-- | Parameters of the 'Overlay.setShowIsolatedElements' command.
+data POverlaySetShowIsolatedElements = POverlaySetShowIsolatedElements
+  {
+    -- | An array of node identifiers and descriptors for the highlight appearance.
+    pOverlaySetShowIsolatedElementsIsolatedElementHighlightConfigs :: [OverlayIsolatedElementHighlightConfig]
+  }
+  deriving (Eq, Show)
+pOverlaySetShowIsolatedElements
+  {-
+  -- | An array of node identifiers and descriptors for the highlight appearance.
+  -}
+  :: [OverlayIsolatedElementHighlightConfig]
+  -> POverlaySetShowIsolatedElements
+pOverlaySetShowIsolatedElements
+  arg_pOverlaySetShowIsolatedElementsIsolatedElementHighlightConfigs
+  = POverlaySetShowIsolatedElements
+    arg_pOverlaySetShowIsolatedElementsIsolatedElementHighlightConfigs
+instance ToJSON POverlaySetShowIsolatedElements where
+  toJSON p = A.object $ catMaybes [
+    ("isolatedElementHighlightConfigs" A..=) <$> Just (pOverlaySetShowIsolatedElementsIsolatedElementHighlightConfigs p)
+    ]
+instance Command POverlaySetShowIsolatedElements where
+  type CommandResponse POverlaySetShowIsolatedElements = ()
+  commandName _ = "Overlay.setShowIsolatedElements"
+  fromJSON = const . A.Success . const ()
+
diff --git a/src/CDP/Domains/Performance.hs b/src/CDP/Domains/Performance.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains/Performance.hs
@@ -0,0 +1,159 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+
+
+{- |
+= Performance
+
+-}
+
+
+module CDP.Domains.Performance (module CDP.Domains.Performance) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+
+
+
+-- | Type 'Performance.Metric'.
+--   Run-time execution metric.
+data PerformanceMetric = PerformanceMetric
+  {
+    -- | Metric name.
+    performanceMetricName :: T.Text,
+    -- | Metric value.
+    performanceMetricValue :: Double
+  }
+  deriving (Eq, Show)
+instance FromJSON PerformanceMetric where
+  parseJSON = A.withObject "PerformanceMetric" $ \o -> PerformanceMetric
+    <$> o A..: "name"
+    <*> o A..: "value"
+instance ToJSON PerformanceMetric where
+  toJSON p = A.object $ catMaybes [
+    ("name" A..=) <$> Just (performanceMetricName p),
+    ("value" A..=) <$> Just (performanceMetricValue p)
+    ]
+
+-- | Type of the 'Performance.metrics' event.
+data PerformanceMetrics = PerformanceMetrics
+  {
+    -- | Current values of the metrics.
+    performanceMetricsMetrics :: [PerformanceMetric],
+    -- | Timestamp title.
+    performanceMetricsTitle :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON PerformanceMetrics where
+  parseJSON = A.withObject "PerformanceMetrics" $ \o -> PerformanceMetrics
+    <$> o A..: "metrics"
+    <*> o A..: "title"
+instance Event PerformanceMetrics where
+  eventName _ = "Performance.metrics"
+
+-- | Disable collecting and reporting metrics.
+
+-- | Parameters of the 'Performance.disable' command.
+data PPerformanceDisable = PPerformanceDisable
+  deriving (Eq, Show)
+pPerformanceDisable
+  :: PPerformanceDisable
+pPerformanceDisable
+  = PPerformanceDisable
+instance ToJSON PPerformanceDisable where
+  toJSON _ = A.Null
+instance Command PPerformanceDisable where
+  type CommandResponse PPerformanceDisable = ()
+  commandName _ = "Performance.disable"
+  fromJSON = const . A.Success . const ()
+
+-- | Enable collecting and reporting metrics.
+
+-- | Parameters of the 'Performance.enable' command.
+data PPerformanceEnableTimeDomain = PPerformanceEnableTimeDomainTimeTicks | PPerformanceEnableTimeDomainThreadTicks
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PPerformanceEnableTimeDomain where
+  parseJSON = A.withText "PPerformanceEnableTimeDomain" $ \v -> case v of
+    "timeTicks" -> pure PPerformanceEnableTimeDomainTimeTicks
+    "threadTicks" -> pure PPerformanceEnableTimeDomainThreadTicks
+    "_" -> fail "failed to parse PPerformanceEnableTimeDomain"
+instance ToJSON PPerformanceEnableTimeDomain where
+  toJSON v = A.String $ case v of
+    PPerformanceEnableTimeDomainTimeTicks -> "timeTicks"
+    PPerformanceEnableTimeDomainThreadTicks -> "threadTicks"
+data PPerformanceEnable = PPerformanceEnable
+  {
+    -- | Time domain to use for collecting and reporting duration metrics.
+    pPerformanceEnableTimeDomain :: Maybe PPerformanceEnableTimeDomain
+  }
+  deriving (Eq, Show)
+pPerformanceEnable
+  :: PPerformanceEnable
+pPerformanceEnable
+  = PPerformanceEnable
+    Nothing
+instance ToJSON PPerformanceEnable where
+  toJSON p = A.object $ catMaybes [
+    ("timeDomain" A..=) <$> (pPerformanceEnableTimeDomain p)
+    ]
+instance Command PPerformanceEnable where
+  type CommandResponse PPerformanceEnable = ()
+  commandName _ = "Performance.enable"
+  fromJSON = const . A.Success . const ()
+
+-- | Retrieve current values of run-time metrics.
+
+-- | Parameters of the 'Performance.getMetrics' command.
+data PPerformanceGetMetrics = PPerformanceGetMetrics
+  deriving (Eq, Show)
+pPerformanceGetMetrics
+  :: PPerformanceGetMetrics
+pPerformanceGetMetrics
+  = PPerformanceGetMetrics
+instance ToJSON PPerformanceGetMetrics where
+  toJSON _ = A.Null
+data PerformanceGetMetrics = PerformanceGetMetrics
+  {
+    -- | Current values for run-time metrics.
+    performanceGetMetricsMetrics :: [PerformanceMetric]
+  }
+  deriving (Eq, Show)
+instance FromJSON PerformanceGetMetrics where
+  parseJSON = A.withObject "PerformanceGetMetrics" $ \o -> PerformanceGetMetrics
+    <$> o A..: "metrics"
+instance Command PPerformanceGetMetrics where
+  type CommandResponse PPerformanceGetMetrics = PerformanceGetMetrics
+  commandName _ = "Performance.getMetrics"
+
diff --git a/src/CDP/Domains/PerformanceTimeline.hs b/src/CDP/Domains/PerformanceTimeline.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains/PerformanceTimeline.hs
@@ -0,0 +1,217 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+
+
+{- |
+= PerformanceTimeline
+
+Reporting of performance timeline events, as specified in
+https://w3c.github.io/performance-timeline/#dom-performanceobserver.
+-}
+
+
+module CDP.Domains.PerformanceTimeline (module CDP.Domains.PerformanceTimeline) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+
+import CDP.Domains.DOMPageNetworkEmulationSecurity as DOMPageNetworkEmulationSecurity
+
+
+-- | Type 'PerformanceTimeline.LargestContentfulPaint'.
+--   See https://github.com/WICG/LargestContentfulPaint and largest_contentful_paint.idl
+data PerformanceTimelineLargestContentfulPaint = PerformanceTimelineLargestContentfulPaint
+  {
+    performanceTimelineLargestContentfulPaintRenderTime :: DOMPageNetworkEmulationSecurity.NetworkTimeSinceEpoch,
+    performanceTimelineLargestContentfulPaintLoadTime :: DOMPageNetworkEmulationSecurity.NetworkTimeSinceEpoch,
+    -- | The number of pixels being painted.
+    performanceTimelineLargestContentfulPaintSize :: Double,
+    -- | The id attribute of the element, if available.
+    performanceTimelineLargestContentfulPaintElementId :: Maybe T.Text,
+    -- | The URL of the image (may be trimmed).
+    performanceTimelineLargestContentfulPaintUrl :: Maybe T.Text,
+    performanceTimelineLargestContentfulPaintNodeId :: Maybe DOMPageNetworkEmulationSecurity.DOMBackendNodeId
+  }
+  deriving (Eq, Show)
+instance FromJSON PerformanceTimelineLargestContentfulPaint where
+  parseJSON = A.withObject "PerformanceTimelineLargestContentfulPaint" $ \o -> PerformanceTimelineLargestContentfulPaint
+    <$> o A..: "renderTime"
+    <*> o A..: "loadTime"
+    <*> o A..: "size"
+    <*> o A..:? "elementId"
+    <*> o A..:? "url"
+    <*> o A..:? "nodeId"
+instance ToJSON PerformanceTimelineLargestContentfulPaint where
+  toJSON p = A.object $ catMaybes [
+    ("renderTime" A..=) <$> Just (performanceTimelineLargestContentfulPaintRenderTime p),
+    ("loadTime" A..=) <$> Just (performanceTimelineLargestContentfulPaintLoadTime p),
+    ("size" A..=) <$> Just (performanceTimelineLargestContentfulPaintSize p),
+    ("elementId" A..=) <$> (performanceTimelineLargestContentfulPaintElementId p),
+    ("url" A..=) <$> (performanceTimelineLargestContentfulPaintUrl p),
+    ("nodeId" A..=) <$> (performanceTimelineLargestContentfulPaintNodeId p)
+    ]
+
+-- | Type 'PerformanceTimeline.LayoutShiftAttribution'.
+data PerformanceTimelineLayoutShiftAttribution = PerformanceTimelineLayoutShiftAttribution
+  {
+    performanceTimelineLayoutShiftAttributionPreviousRect :: DOMPageNetworkEmulationSecurity.DOMRect,
+    performanceTimelineLayoutShiftAttributionCurrentRect :: DOMPageNetworkEmulationSecurity.DOMRect,
+    performanceTimelineLayoutShiftAttributionNodeId :: Maybe DOMPageNetworkEmulationSecurity.DOMBackendNodeId
+  }
+  deriving (Eq, Show)
+instance FromJSON PerformanceTimelineLayoutShiftAttribution where
+  parseJSON = A.withObject "PerformanceTimelineLayoutShiftAttribution" $ \o -> PerformanceTimelineLayoutShiftAttribution
+    <$> o A..: "previousRect"
+    <*> o A..: "currentRect"
+    <*> o A..:? "nodeId"
+instance ToJSON PerformanceTimelineLayoutShiftAttribution where
+  toJSON p = A.object $ catMaybes [
+    ("previousRect" A..=) <$> Just (performanceTimelineLayoutShiftAttributionPreviousRect p),
+    ("currentRect" A..=) <$> Just (performanceTimelineLayoutShiftAttributionCurrentRect p),
+    ("nodeId" A..=) <$> (performanceTimelineLayoutShiftAttributionNodeId p)
+    ]
+
+-- | Type 'PerformanceTimeline.LayoutShift'.
+--   See https://wicg.github.io/layout-instability/#sec-layout-shift and layout_shift.idl
+data PerformanceTimelineLayoutShift = PerformanceTimelineLayoutShift
+  {
+    -- | Score increment produced by this event.
+    performanceTimelineLayoutShiftValue :: Double,
+    performanceTimelineLayoutShiftHadRecentInput :: Bool,
+    performanceTimelineLayoutShiftLastInputTime :: DOMPageNetworkEmulationSecurity.NetworkTimeSinceEpoch,
+    performanceTimelineLayoutShiftSources :: [PerformanceTimelineLayoutShiftAttribution]
+  }
+  deriving (Eq, Show)
+instance FromJSON PerformanceTimelineLayoutShift where
+  parseJSON = A.withObject "PerformanceTimelineLayoutShift" $ \o -> PerformanceTimelineLayoutShift
+    <$> o A..: "value"
+    <*> o A..: "hadRecentInput"
+    <*> o A..: "lastInputTime"
+    <*> o A..: "sources"
+instance ToJSON PerformanceTimelineLayoutShift where
+  toJSON p = A.object $ catMaybes [
+    ("value" A..=) <$> Just (performanceTimelineLayoutShiftValue p),
+    ("hadRecentInput" A..=) <$> Just (performanceTimelineLayoutShiftHadRecentInput p),
+    ("lastInputTime" A..=) <$> Just (performanceTimelineLayoutShiftLastInputTime p),
+    ("sources" A..=) <$> Just (performanceTimelineLayoutShiftSources p)
+    ]
+
+-- | Type 'PerformanceTimeline.TimelineEvent'.
+data PerformanceTimelineTimelineEvent = PerformanceTimelineTimelineEvent
+  {
+    -- | Identifies the frame that this event is related to. Empty for non-frame targets.
+    performanceTimelineTimelineEventFrameId :: DOMPageNetworkEmulationSecurity.PageFrameId,
+    -- | The event type, as specified in https://w3c.github.io/performance-timeline/#dom-performanceentry-entrytype
+    --   This determines which of the optional "details" fiedls is present.
+    performanceTimelineTimelineEventType :: T.Text,
+    -- | Name may be empty depending on the type.
+    performanceTimelineTimelineEventName :: T.Text,
+    -- | Time in seconds since Epoch, monotonically increasing within document lifetime.
+    performanceTimelineTimelineEventTime :: DOMPageNetworkEmulationSecurity.NetworkTimeSinceEpoch,
+    -- | Event duration, if applicable.
+    performanceTimelineTimelineEventDuration :: Maybe Double,
+    performanceTimelineTimelineEventLcpDetails :: Maybe PerformanceTimelineLargestContentfulPaint,
+    performanceTimelineTimelineEventLayoutShiftDetails :: Maybe PerformanceTimelineLayoutShift
+  }
+  deriving (Eq, Show)
+instance FromJSON PerformanceTimelineTimelineEvent where
+  parseJSON = A.withObject "PerformanceTimelineTimelineEvent" $ \o -> PerformanceTimelineTimelineEvent
+    <$> o A..: "frameId"
+    <*> o A..: "type"
+    <*> o A..: "name"
+    <*> o A..: "time"
+    <*> o A..:? "duration"
+    <*> o A..:? "lcpDetails"
+    <*> o A..:? "layoutShiftDetails"
+instance ToJSON PerformanceTimelineTimelineEvent where
+  toJSON p = A.object $ catMaybes [
+    ("frameId" A..=) <$> Just (performanceTimelineTimelineEventFrameId p),
+    ("type" A..=) <$> Just (performanceTimelineTimelineEventType p),
+    ("name" A..=) <$> Just (performanceTimelineTimelineEventName p),
+    ("time" A..=) <$> Just (performanceTimelineTimelineEventTime p),
+    ("duration" A..=) <$> (performanceTimelineTimelineEventDuration p),
+    ("lcpDetails" A..=) <$> (performanceTimelineTimelineEventLcpDetails p),
+    ("layoutShiftDetails" A..=) <$> (performanceTimelineTimelineEventLayoutShiftDetails p)
+    ]
+
+-- | Type of the 'PerformanceTimeline.timelineEventAdded' event.
+data PerformanceTimelineTimelineEventAdded = PerformanceTimelineTimelineEventAdded
+  {
+    performanceTimelineTimelineEventAddedEvent :: PerformanceTimelineTimelineEvent
+  }
+  deriving (Eq, Show)
+instance FromJSON PerformanceTimelineTimelineEventAdded where
+  parseJSON = A.withObject "PerformanceTimelineTimelineEventAdded" $ \o -> PerformanceTimelineTimelineEventAdded
+    <$> o A..: "event"
+instance Event PerformanceTimelineTimelineEventAdded where
+  eventName _ = "PerformanceTimeline.timelineEventAdded"
+
+-- | Previously buffered events would be reported before method returns.
+--   See also: timelineEventAdded
+
+-- | Parameters of the 'PerformanceTimeline.enable' command.
+data PPerformanceTimelineEnable = PPerformanceTimelineEnable
+  {
+    -- | The types of event to report, as specified in
+    --   https://w3c.github.io/performance-timeline/#dom-performanceentry-entrytype
+    --   The specified filter overrides any previous filters, passing empty
+    --   filter disables recording.
+    --   Note that not all types exposed to the web platform are currently supported.
+    pPerformanceTimelineEnableEventTypes :: [T.Text]
+  }
+  deriving (Eq, Show)
+pPerformanceTimelineEnable
+  {-
+  -- | The types of event to report, as specified in
+  --   https://w3c.github.io/performance-timeline/#dom-performanceentry-entrytype
+  --   The specified filter overrides any previous filters, passing empty
+  --   filter disables recording.
+  --   Note that not all types exposed to the web platform are currently supported.
+  -}
+  :: [T.Text]
+  -> PPerformanceTimelineEnable
+pPerformanceTimelineEnable
+  arg_pPerformanceTimelineEnableEventTypes
+  = PPerformanceTimelineEnable
+    arg_pPerformanceTimelineEnableEventTypes
+instance ToJSON PPerformanceTimelineEnable where
+  toJSON p = A.object $ catMaybes [
+    ("eventTypes" A..=) <$> Just (pPerformanceTimelineEnableEventTypes p)
+    ]
+instance Command PPerformanceTimelineEnable where
+  type CommandResponse PPerformanceTimelineEnable = ()
+  commandName _ = "PerformanceTimeline.enable"
+  fromJSON = const . A.Success . const ()
+
diff --git a/src/CDP/Domains/Profiler.hs b/src/CDP/Domains/Profiler.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains/Profiler.hs
@@ -0,0 +1,477 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+
+
+{- |
+= Profiler
+
+-}
+
+
+module CDP.Domains.Profiler (module CDP.Domains.Profiler) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+
+import CDP.Domains.Debugger as Debugger
+import CDP.Domains.Runtime as Runtime
+
+
+-- | Type 'Profiler.ProfileNode'.
+--   Profile node. Holds callsite information, execution statistics and child nodes.
+data ProfilerProfileNode = ProfilerProfileNode
+  {
+    -- | Unique id of the node.
+    profilerProfileNodeId :: Int,
+    -- | Function location.
+    profilerProfileNodeCallFrame :: Runtime.RuntimeCallFrame,
+    -- | Number of samples where this node was on top of the call stack.
+    profilerProfileNodeHitCount :: Maybe Int,
+    -- | Child node ids.
+    profilerProfileNodeChildren :: Maybe [Int],
+    -- | The reason of being not optimized. The function may be deoptimized or marked as don't
+    --   optimize.
+    profilerProfileNodeDeoptReason :: Maybe T.Text,
+    -- | An array of source position ticks.
+    profilerProfileNodePositionTicks :: Maybe [ProfilerPositionTickInfo]
+  }
+  deriving (Eq, Show)
+instance FromJSON ProfilerProfileNode where
+  parseJSON = A.withObject "ProfilerProfileNode" $ \o -> ProfilerProfileNode
+    <$> o A..: "id"
+    <*> o A..: "callFrame"
+    <*> o A..:? "hitCount"
+    <*> o A..:? "children"
+    <*> o A..:? "deoptReason"
+    <*> o A..:? "positionTicks"
+instance ToJSON ProfilerProfileNode where
+  toJSON p = A.object $ catMaybes [
+    ("id" A..=) <$> Just (profilerProfileNodeId p),
+    ("callFrame" A..=) <$> Just (profilerProfileNodeCallFrame p),
+    ("hitCount" A..=) <$> (profilerProfileNodeHitCount p),
+    ("children" A..=) <$> (profilerProfileNodeChildren p),
+    ("deoptReason" A..=) <$> (profilerProfileNodeDeoptReason p),
+    ("positionTicks" A..=) <$> (profilerProfileNodePositionTicks p)
+    ]
+
+-- | Type 'Profiler.Profile'.
+--   Profile.
+data ProfilerProfile = ProfilerProfile
+  {
+    -- | The list of profile nodes. First item is the root node.
+    profilerProfileNodes :: [ProfilerProfileNode],
+    -- | Profiling start timestamp in microseconds.
+    profilerProfileStartTime :: Double,
+    -- | Profiling end timestamp in microseconds.
+    profilerProfileEndTime :: Double,
+    -- | Ids of samples top nodes.
+    profilerProfileSamples :: Maybe [Int],
+    -- | Time intervals between adjacent samples in microseconds. The first delta is relative to the
+    --   profile startTime.
+    profilerProfileTimeDeltas :: Maybe [Int]
+  }
+  deriving (Eq, Show)
+instance FromJSON ProfilerProfile where
+  parseJSON = A.withObject "ProfilerProfile" $ \o -> ProfilerProfile
+    <$> o A..: "nodes"
+    <*> o A..: "startTime"
+    <*> o A..: "endTime"
+    <*> o A..:? "samples"
+    <*> o A..:? "timeDeltas"
+instance ToJSON ProfilerProfile where
+  toJSON p = A.object $ catMaybes [
+    ("nodes" A..=) <$> Just (profilerProfileNodes p),
+    ("startTime" A..=) <$> Just (profilerProfileStartTime p),
+    ("endTime" A..=) <$> Just (profilerProfileEndTime p),
+    ("samples" A..=) <$> (profilerProfileSamples p),
+    ("timeDeltas" A..=) <$> (profilerProfileTimeDeltas p)
+    ]
+
+-- | Type 'Profiler.PositionTickInfo'.
+--   Specifies a number of samples attributed to a certain source position.
+data ProfilerPositionTickInfo = ProfilerPositionTickInfo
+  {
+    -- | Source line number (1-based).
+    profilerPositionTickInfoLine :: Int,
+    -- | Number of samples attributed to the source line.
+    profilerPositionTickInfoTicks :: Int
+  }
+  deriving (Eq, Show)
+instance FromJSON ProfilerPositionTickInfo where
+  parseJSON = A.withObject "ProfilerPositionTickInfo" $ \o -> ProfilerPositionTickInfo
+    <$> o A..: "line"
+    <*> o A..: "ticks"
+instance ToJSON ProfilerPositionTickInfo where
+  toJSON p = A.object $ catMaybes [
+    ("line" A..=) <$> Just (profilerPositionTickInfoLine p),
+    ("ticks" A..=) <$> Just (profilerPositionTickInfoTicks p)
+    ]
+
+-- | Type 'Profiler.CoverageRange'.
+--   Coverage data for a source range.
+data ProfilerCoverageRange = ProfilerCoverageRange
+  {
+    -- | JavaScript script source offset for the range start.
+    profilerCoverageRangeStartOffset :: Int,
+    -- | JavaScript script source offset for the range end.
+    profilerCoverageRangeEndOffset :: Int,
+    -- | Collected execution count of the source range.
+    profilerCoverageRangeCount :: Int
+  }
+  deriving (Eq, Show)
+instance FromJSON ProfilerCoverageRange where
+  parseJSON = A.withObject "ProfilerCoverageRange" $ \o -> ProfilerCoverageRange
+    <$> o A..: "startOffset"
+    <*> o A..: "endOffset"
+    <*> o A..: "count"
+instance ToJSON ProfilerCoverageRange where
+  toJSON p = A.object $ catMaybes [
+    ("startOffset" A..=) <$> Just (profilerCoverageRangeStartOffset p),
+    ("endOffset" A..=) <$> Just (profilerCoverageRangeEndOffset p),
+    ("count" A..=) <$> Just (profilerCoverageRangeCount p)
+    ]
+
+-- | Type 'Profiler.FunctionCoverage'.
+--   Coverage data for a JavaScript function.
+data ProfilerFunctionCoverage = ProfilerFunctionCoverage
+  {
+    -- | JavaScript function name.
+    profilerFunctionCoverageFunctionName :: T.Text,
+    -- | Source ranges inside the function with coverage data.
+    profilerFunctionCoverageRanges :: [ProfilerCoverageRange],
+    -- | Whether coverage data for this function has block granularity.
+    profilerFunctionCoverageIsBlockCoverage :: Bool
+  }
+  deriving (Eq, Show)
+instance FromJSON ProfilerFunctionCoverage where
+  parseJSON = A.withObject "ProfilerFunctionCoverage" $ \o -> ProfilerFunctionCoverage
+    <$> o A..: "functionName"
+    <*> o A..: "ranges"
+    <*> o A..: "isBlockCoverage"
+instance ToJSON ProfilerFunctionCoverage where
+  toJSON p = A.object $ catMaybes [
+    ("functionName" A..=) <$> Just (profilerFunctionCoverageFunctionName p),
+    ("ranges" A..=) <$> Just (profilerFunctionCoverageRanges p),
+    ("isBlockCoverage" A..=) <$> Just (profilerFunctionCoverageIsBlockCoverage p)
+    ]
+
+-- | Type 'Profiler.ScriptCoverage'.
+--   Coverage data for a JavaScript script.
+data ProfilerScriptCoverage = ProfilerScriptCoverage
+  {
+    -- | JavaScript script id.
+    profilerScriptCoverageScriptId :: Runtime.RuntimeScriptId,
+    -- | JavaScript script name or url.
+    profilerScriptCoverageUrl :: T.Text,
+    -- | Functions contained in the script that has coverage data.
+    profilerScriptCoverageFunctions :: [ProfilerFunctionCoverage]
+  }
+  deriving (Eq, Show)
+instance FromJSON ProfilerScriptCoverage where
+  parseJSON = A.withObject "ProfilerScriptCoverage" $ \o -> ProfilerScriptCoverage
+    <$> o A..: "scriptId"
+    <*> o A..: "url"
+    <*> o A..: "functions"
+instance ToJSON ProfilerScriptCoverage where
+  toJSON p = A.object $ catMaybes [
+    ("scriptId" A..=) <$> Just (profilerScriptCoverageScriptId p),
+    ("url" A..=) <$> Just (profilerScriptCoverageUrl p),
+    ("functions" A..=) <$> Just (profilerScriptCoverageFunctions p)
+    ]
+
+-- | Type of the 'Profiler.consoleProfileFinished' event.
+data ProfilerConsoleProfileFinished = ProfilerConsoleProfileFinished
+  {
+    profilerConsoleProfileFinishedId :: T.Text,
+    -- | Location of console.profileEnd().
+    profilerConsoleProfileFinishedLocation :: Debugger.DebuggerLocation,
+    profilerConsoleProfileFinishedProfile :: ProfilerProfile,
+    -- | Profile title passed as an argument to console.profile().
+    profilerConsoleProfileFinishedTitle :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON ProfilerConsoleProfileFinished where
+  parseJSON = A.withObject "ProfilerConsoleProfileFinished" $ \o -> ProfilerConsoleProfileFinished
+    <$> o A..: "id"
+    <*> o A..: "location"
+    <*> o A..: "profile"
+    <*> o A..:? "title"
+instance Event ProfilerConsoleProfileFinished where
+  eventName _ = "Profiler.consoleProfileFinished"
+
+-- | Type of the 'Profiler.consoleProfileStarted' event.
+data ProfilerConsoleProfileStarted = ProfilerConsoleProfileStarted
+  {
+    profilerConsoleProfileStartedId :: T.Text,
+    -- | Location of console.profile().
+    profilerConsoleProfileStartedLocation :: Debugger.DebuggerLocation,
+    -- | Profile title passed as an argument to console.profile().
+    profilerConsoleProfileStartedTitle :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON ProfilerConsoleProfileStarted where
+  parseJSON = A.withObject "ProfilerConsoleProfileStarted" $ \o -> ProfilerConsoleProfileStarted
+    <$> o A..: "id"
+    <*> o A..: "location"
+    <*> o A..:? "title"
+instance Event ProfilerConsoleProfileStarted where
+  eventName _ = "Profiler.consoleProfileStarted"
+
+-- | Type of the 'Profiler.preciseCoverageDeltaUpdate' event.
+data ProfilerPreciseCoverageDeltaUpdate = ProfilerPreciseCoverageDeltaUpdate
+  {
+    -- | Monotonically increasing time (in seconds) when the coverage update was taken in the backend.
+    profilerPreciseCoverageDeltaUpdateTimestamp :: Double,
+    -- | Identifier for distinguishing coverage events.
+    profilerPreciseCoverageDeltaUpdateOccasion :: T.Text,
+    -- | Coverage data for the current isolate.
+    profilerPreciseCoverageDeltaUpdateResult :: [ProfilerScriptCoverage]
+  }
+  deriving (Eq, Show)
+instance FromJSON ProfilerPreciseCoverageDeltaUpdate where
+  parseJSON = A.withObject "ProfilerPreciseCoverageDeltaUpdate" $ \o -> ProfilerPreciseCoverageDeltaUpdate
+    <$> o A..: "timestamp"
+    <*> o A..: "occasion"
+    <*> o A..: "result"
+instance Event ProfilerPreciseCoverageDeltaUpdate where
+  eventName _ = "Profiler.preciseCoverageDeltaUpdate"
+
+
+-- | Parameters of the 'Profiler.disable' command.
+data PProfilerDisable = PProfilerDisable
+  deriving (Eq, Show)
+pProfilerDisable
+  :: PProfilerDisable
+pProfilerDisable
+  = PProfilerDisable
+instance ToJSON PProfilerDisable where
+  toJSON _ = A.Null
+instance Command PProfilerDisable where
+  type CommandResponse PProfilerDisable = ()
+  commandName _ = "Profiler.disable"
+  fromJSON = const . A.Success . const ()
+
+
+-- | Parameters of the 'Profiler.enable' command.
+data PProfilerEnable = PProfilerEnable
+  deriving (Eq, Show)
+pProfilerEnable
+  :: PProfilerEnable
+pProfilerEnable
+  = PProfilerEnable
+instance ToJSON PProfilerEnable where
+  toJSON _ = A.Null
+instance Command PProfilerEnable where
+  type CommandResponse PProfilerEnable = ()
+  commandName _ = "Profiler.enable"
+  fromJSON = const . A.Success . const ()
+
+-- | Collect coverage data for the current isolate. The coverage data may be incomplete due to
+--   garbage collection.
+
+-- | Parameters of the 'Profiler.getBestEffortCoverage' command.
+data PProfilerGetBestEffortCoverage = PProfilerGetBestEffortCoverage
+  deriving (Eq, Show)
+pProfilerGetBestEffortCoverage
+  :: PProfilerGetBestEffortCoverage
+pProfilerGetBestEffortCoverage
+  = PProfilerGetBestEffortCoverage
+instance ToJSON PProfilerGetBestEffortCoverage where
+  toJSON _ = A.Null
+data ProfilerGetBestEffortCoverage = ProfilerGetBestEffortCoverage
+  {
+    -- | Coverage data for the current isolate.
+    profilerGetBestEffortCoverageResult :: [ProfilerScriptCoverage]
+  }
+  deriving (Eq, Show)
+instance FromJSON ProfilerGetBestEffortCoverage where
+  parseJSON = A.withObject "ProfilerGetBestEffortCoverage" $ \o -> ProfilerGetBestEffortCoverage
+    <$> o A..: "result"
+instance Command PProfilerGetBestEffortCoverage where
+  type CommandResponse PProfilerGetBestEffortCoverage = ProfilerGetBestEffortCoverage
+  commandName _ = "Profiler.getBestEffortCoverage"
+
+-- | Changes CPU profiler sampling interval. Must be called before CPU profiles recording started.
+
+-- | Parameters of the 'Profiler.setSamplingInterval' command.
+data PProfilerSetSamplingInterval = PProfilerSetSamplingInterval
+  {
+    -- | New sampling interval in microseconds.
+    pProfilerSetSamplingIntervalInterval :: Int
+  }
+  deriving (Eq, Show)
+pProfilerSetSamplingInterval
+  {-
+  -- | New sampling interval in microseconds.
+  -}
+  :: Int
+  -> PProfilerSetSamplingInterval
+pProfilerSetSamplingInterval
+  arg_pProfilerSetSamplingIntervalInterval
+  = PProfilerSetSamplingInterval
+    arg_pProfilerSetSamplingIntervalInterval
+instance ToJSON PProfilerSetSamplingInterval where
+  toJSON p = A.object $ catMaybes [
+    ("interval" A..=) <$> Just (pProfilerSetSamplingIntervalInterval p)
+    ]
+instance Command PProfilerSetSamplingInterval where
+  type CommandResponse PProfilerSetSamplingInterval = ()
+  commandName _ = "Profiler.setSamplingInterval"
+  fromJSON = const . A.Success . const ()
+
+
+-- | Parameters of the 'Profiler.start' command.
+data PProfilerStart = PProfilerStart
+  deriving (Eq, Show)
+pProfilerStart
+  :: PProfilerStart
+pProfilerStart
+  = PProfilerStart
+instance ToJSON PProfilerStart where
+  toJSON _ = A.Null
+instance Command PProfilerStart where
+  type CommandResponse PProfilerStart = ()
+  commandName _ = "Profiler.start"
+  fromJSON = const . A.Success . const ()
+
+-- | Enable precise code coverage. Coverage data for JavaScript executed before enabling precise code
+--   coverage may be incomplete. Enabling prevents running optimized code and resets execution
+--   counters.
+
+-- | Parameters of the 'Profiler.startPreciseCoverage' command.
+data PProfilerStartPreciseCoverage = PProfilerStartPreciseCoverage
+  {
+    -- | Collect accurate call counts beyond simple 'covered' or 'not covered'.
+    pProfilerStartPreciseCoverageCallCount :: Maybe Bool,
+    -- | Collect block-based coverage.
+    pProfilerStartPreciseCoverageDetailed :: Maybe Bool,
+    -- | Allow the backend to send updates on its own initiative
+    pProfilerStartPreciseCoverageAllowTriggeredUpdates :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pProfilerStartPreciseCoverage
+  :: PProfilerStartPreciseCoverage
+pProfilerStartPreciseCoverage
+  = PProfilerStartPreciseCoverage
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PProfilerStartPreciseCoverage where
+  toJSON p = A.object $ catMaybes [
+    ("callCount" A..=) <$> (pProfilerStartPreciseCoverageCallCount p),
+    ("detailed" A..=) <$> (pProfilerStartPreciseCoverageDetailed p),
+    ("allowTriggeredUpdates" A..=) <$> (pProfilerStartPreciseCoverageAllowTriggeredUpdates p)
+    ]
+data ProfilerStartPreciseCoverage = ProfilerStartPreciseCoverage
+  {
+    -- | Monotonically increasing time (in seconds) when the coverage update was taken in the backend.
+    profilerStartPreciseCoverageTimestamp :: Double
+  }
+  deriving (Eq, Show)
+instance FromJSON ProfilerStartPreciseCoverage where
+  parseJSON = A.withObject "ProfilerStartPreciseCoverage" $ \o -> ProfilerStartPreciseCoverage
+    <$> o A..: "timestamp"
+instance Command PProfilerStartPreciseCoverage where
+  type CommandResponse PProfilerStartPreciseCoverage = ProfilerStartPreciseCoverage
+  commandName _ = "Profiler.startPreciseCoverage"
+
+
+-- | Parameters of the 'Profiler.stop' command.
+data PProfilerStop = PProfilerStop
+  deriving (Eq, Show)
+pProfilerStop
+  :: PProfilerStop
+pProfilerStop
+  = PProfilerStop
+instance ToJSON PProfilerStop where
+  toJSON _ = A.Null
+data ProfilerStop = ProfilerStop
+  {
+    -- | Recorded profile.
+    profilerStopProfile :: ProfilerProfile
+  }
+  deriving (Eq, Show)
+instance FromJSON ProfilerStop where
+  parseJSON = A.withObject "ProfilerStop" $ \o -> ProfilerStop
+    <$> o A..: "profile"
+instance Command PProfilerStop where
+  type CommandResponse PProfilerStop = ProfilerStop
+  commandName _ = "Profiler.stop"
+
+-- | Disable precise code coverage. Disabling releases unnecessary execution count records and allows
+--   executing optimized code.
+
+-- | Parameters of the 'Profiler.stopPreciseCoverage' command.
+data PProfilerStopPreciseCoverage = PProfilerStopPreciseCoverage
+  deriving (Eq, Show)
+pProfilerStopPreciseCoverage
+  :: PProfilerStopPreciseCoverage
+pProfilerStopPreciseCoverage
+  = PProfilerStopPreciseCoverage
+instance ToJSON PProfilerStopPreciseCoverage where
+  toJSON _ = A.Null
+instance Command PProfilerStopPreciseCoverage where
+  type CommandResponse PProfilerStopPreciseCoverage = ()
+  commandName _ = "Profiler.stopPreciseCoverage"
+  fromJSON = const . A.Success . const ()
+
+-- | Collect coverage data for the current isolate, and resets execution counters. Precise code
+--   coverage needs to have started.
+
+-- | Parameters of the 'Profiler.takePreciseCoverage' command.
+data PProfilerTakePreciseCoverage = PProfilerTakePreciseCoverage
+  deriving (Eq, Show)
+pProfilerTakePreciseCoverage
+  :: PProfilerTakePreciseCoverage
+pProfilerTakePreciseCoverage
+  = PProfilerTakePreciseCoverage
+instance ToJSON PProfilerTakePreciseCoverage where
+  toJSON _ = A.Null
+data ProfilerTakePreciseCoverage = ProfilerTakePreciseCoverage
+  {
+    -- | Coverage data for the current isolate.
+    profilerTakePreciseCoverageResult :: [ProfilerScriptCoverage],
+    -- | Monotonically increasing time (in seconds) when the coverage update was taken in the backend.
+    profilerTakePreciseCoverageTimestamp :: Double
+  }
+  deriving (Eq, Show)
+instance FromJSON ProfilerTakePreciseCoverage where
+  parseJSON = A.withObject "ProfilerTakePreciseCoverage" $ \o -> ProfilerTakePreciseCoverage
+    <$> o A..: "result"
+    <*> o A..: "timestamp"
+instance Command PProfilerTakePreciseCoverage where
+  type CommandResponse PProfilerTakePreciseCoverage = ProfilerTakePreciseCoverage
+  commandName _ = "Profiler.takePreciseCoverage"
+
diff --git a/src/CDP/Domains/Runtime.hs b/src/CDP/Domains/Runtime.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains/Runtime.hs
@@ -0,0 +1,1889 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+
+
+{- |
+= Runtime
+
+Runtime domain exposes JavaScript runtime by means of remote evaluation and mirror objects.
+Evaluation results are returned as mirror object that expose object type, string representation
+and unique identifier that can be used for further object reference. Original objects are
+maintained in memory unless they are either explicitly released or are released along with the
+other objects in their object group.
+-}
+
+
+module CDP.Domains.Runtime (module CDP.Domains.Runtime) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+
+
+
+-- | Type 'Runtime.ScriptId'.
+--   Unique script identifier.
+type RuntimeScriptId = T.Text
+
+-- | Type 'Runtime.WebDriverValue'.
+--   Represents the value serialiazed by the WebDriver BiDi specification
+--   https://w3c.github.io/webdriver-bidi.
+data RuntimeWebDriverValueType = RuntimeWebDriverValueTypeUndefined | RuntimeWebDriverValueTypeNull | RuntimeWebDriverValueTypeString | RuntimeWebDriverValueTypeNumber | RuntimeWebDriverValueTypeBoolean | RuntimeWebDriverValueTypeBigint | RuntimeWebDriverValueTypeRegexp | RuntimeWebDriverValueTypeDate | RuntimeWebDriverValueTypeSymbol | RuntimeWebDriverValueTypeArray | RuntimeWebDriverValueTypeObject | RuntimeWebDriverValueTypeFunction | RuntimeWebDriverValueTypeMap | RuntimeWebDriverValueTypeSet | RuntimeWebDriverValueTypeWeakmap | RuntimeWebDriverValueTypeWeakset | RuntimeWebDriverValueTypeError | RuntimeWebDriverValueTypeProxy | RuntimeWebDriverValueTypePromise | RuntimeWebDriverValueTypeTypedarray | RuntimeWebDriverValueTypeArraybuffer | RuntimeWebDriverValueTypeNode | RuntimeWebDriverValueTypeWindow
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON RuntimeWebDriverValueType where
+  parseJSON = A.withText "RuntimeWebDriverValueType" $ \v -> case v of
+    "undefined" -> pure RuntimeWebDriverValueTypeUndefined
+    "null" -> pure RuntimeWebDriverValueTypeNull
+    "string" -> pure RuntimeWebDriverValueTypeString
+    "number" -> pure RuntimeWebDriverValueTypeNumber
+    "boolean" -> pure RuntimeWebDriverValueTypeBoolean
+    "bigint" -> pure RuntimeWebDriverValueTypeBigint
+    "regexp" -> pure RuntimeWebDriverValueTypeRegexp
+    "date" -> pure RuntimeWebDriverValueTypeDate
+    "symbol" -> pure RuntimeWebDriverValueTypeSymbol
+    "array" -> pure RuntimeWebDriverValueTypeArray
+    "object" -> pure RuntimeWebDriverValueTypeObject
+    "function" -> pure RuntimeWebDriverValueTypeFunction
+    "map" -> pure RuntimeWebDriverValueTypeMap
+    "set" -> pure RuntimeWebDriverValueTypeSet
+    "weakmap" -> pure RuntimeWebDriverValueTypeWeakmap
+    "weakset" -> pure RuntimeWebDriverValueTypeWeakset
+    "error" -> pure RuntimeWebDriverValueTypeError
+    "proxy" -> pure RuntimeWebDriverValueTypeProxy
+    "promise" -> pure RuntimeWebDriverValueTypePromise
+    "typedarray" -> pure RuntimeWebDriverValueTypeTypedarray
+    "arraybuffer" -> pure RuntimeWebDriverValueTypeArraybuffer
+    "node" -> pure RuntimeWebDriverValueTypeNode
+    "window" -> pure RuntimeWebDriverValueTypeWindow
+    "_" -> fail "failed to parse RuntimeWebDriverValueType"
+instance ToJSON RuntimeWebDriverValueType where
+  toJSON v = A.String $ case v of
+    RuntimeWebDriverValueTypeUndefined -> "undefined"
+    RuntimeWebDriverValueTypeNull -> "null"
+    RuntimeWebDriverValueTypeString -> "string"
+    RuntimeWebDriverValueTypeNumber -> "number"
+    RuntimeWebDriverValueTypeBoolean -> "boolean"
+    RuntimeWebDriverValueTypeBigint -> "bigint"
+    RuntimeWebDriverValueTypeRegexp -> "regexp"
+    RuntimeWebDriverValueTypeDate -> "date"
+    RuntimeWebDriverValueTypeSymbol -> "symbol"
+    RuntimeWebDriverValueTypeArray -> "array"
+    RuntimeWebDriverValueTypeObject -> "object"
+    RuntimeWebDriverValueTypeFunction -> "function"
+    RuntimeWebDriverValueTypeMap -> "map"
+    RuntimeWebDriverValueTypeSet -> "set"
+    RuntimeWebDriverValueTypeWeakmap -> "weakmap"
+    RuntimeWebDriverValueTypeWeakset -> "weakset"
+    RuntimeWebDriverValueTypeError -> "error"
+    RuntimeWebDriverValueTypeProxy -> "proxy"
+    RuntimeWebDriverValueTypePromise -> "promise"
+    RuntimeWebDriverValueTypeTypedarray -> "typedarray"
+    RuntimeWebDriverValueTypeArraybuffer -> "arraybuffer"
+    RuntimeWebDriverValueTypeNode -> "node"
+    RuntimeWebDriverValueTypeWindow -> "window"
+data RuntimeWebDriverValue = RuntimeWebDriverValue
+  {
+    runtimeWebDriverValueType :: RuntimeWebDriverValueType,
+    runtimeWebDriverValueValue :: Maybe A.Value,
+    runtimeWebDriverValueObjectId :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON RuntimeWebDriverValue where
+  parseJSON = A.withObject "RuntimeWebDriverValue" $ \o -> RuntimeWebDriverValue
+    <$> o A..: "type"
+    <*> o A..:? "value"
+    <*> o A..:? "objectId"
+instance ToJSON RuntimeWebDriverValue where
+  toJSON p = A.object $ catMaybes [
+    ("type" A..=) <$> Just (runtimeWebDriverValueType p),
+    ("value" A..=) <$> (runtimeWebDriverValueValue p),
+    ("objectId" A..=) <$> (runtimeWebDriverValueObjectId p)
+    ]
+
+-- | Type 'Runtime.RemoteObjectId'.
+--   Unique object identifier.
+type RuntimeRemoteObjectId = T.Text
+
+-- | Type 'Runtime.UnserializableValue'.
+--   Primitive value which cannot be JSON-stringified. Includes values `-0`, `NaN`, `Infinity`,
+--   `-Infinity`, and bigint literals.
+type RuntimeUnserializableValue = T.Text
+
+-- | Type 'Runtime.RemoteObject'.
+--   Mirror object referencing original JavaScript object.
+data RuntimeRemoteObjectType = RuntimeRemoteObjectTypeObject | RuntimeRemoteObjectTypeFunction | RuntimeRemoteObjectTypeUndefined | RuntimeRemoteObjectTypeString | RuntimeRemoteObjectTypeNumber | RuntimeRemoteObjectTypeBoolean | RuntimeRemoteObjectTypeSymbol | RuntimeRemoteObjectTypeBigint
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON RuntimeRemoteObjectType where
+  parseJSON = A.withText "RuntimeRemoteObjectType" $ \v -> case v of
+    "object" -> pure RuntimeRemoteObjectTypeObject
+    "function" -> pure RuntimeRemoteObjectTypeFunction
+    "undefined" -> pure RuntimeRemoteObjectTypeUndefined
+    "string" -> pure RuntimeRemoteObjectTypeString
+    "number" -> pure RuntimeRemoteObjectTypeNumber
+    "boolean" -> pure RuntimeRemoteObjectTypeBoolean
+    "symbol" -> pure RuntimeRemoteObjectTypeSymbol
+    "bigint" -> pure RuntimeRemoteObjectTypeBigint
+    "_" -> fail "failed to parse RuntimeRemoteObjectType"
+instance ToJSON RuntimeRemoteObjectType where
+  toJSON v = A.String $ case v of
+    RuntimeRemoteObjectTypeObject -> "object"
+    RuntimeRemoteObjectTypeFunction -> "function"
+    RuntimeRemoteObjectTypeUndefined -> "undefined"
+    RuntimeRemoteObjectTypeString -> "string"
+    RuntimeRemoteObjectTypeNumber -> "number"
+    RuntimeRemoteObjectTypeBoolean -> "boolean"
+    RuntimeRemoteObjectTypeSymbol -> "symbol"
+    RuntimeRemoteObjectTypeBigint -> "bigint"
+data RuntimeRemoteObjectSubtype = RuntimeRemoteObjectSubtypeArray | RuntimeRemoteObjectSubtypeNull | RuntimeRemoteObjectSubtypeNode | RuntimeRemoteObjectSubtypeRegexp | RuntimeRemoteObjectSubtypeDate | RuntimeRemoteObjectSubtypeMap | RuntimeRemoteObjectSubtypeSet | RuntimeRemoteObjectSubtypeWeakmap | RuntimeRemoteObjectSubtypeWeakset | RuntimeRemoteObjectSubtypeIterator | RuntimeRemoteObjectSubtypeGenerator | RuntimeRemoteObjectSubtypeError | RuntimeRemoteObjectSubtypeProxy | RuntimeRemoteObjectSubtypePromise | RuntimeRemoteObjectSubtypeTypedarray | RuntimeRemoteObjectSubtypeArraybuffer | RuntimeRemoteObjectSubtypeDataview | RuntimeRemoteObjectSubtypeWebassemblymemory | RuntimeRemoteObjectSubtypeWasmvalue
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON RuntimeRemoteObjectSubtype where
+  parseJSON = A.withText "RuntimeRemoteObjectSubtype" $ \v -> case v of
+    "array" -> pure RuntimeRemoteObjectSubtypeArray
+    "null" -> pure RuntimeRemoteObjectSubtypeNull
+    "node" -> pure RuntimeRemoteObjectSubtypeNode
+    "regexp" -> pure RuntimeRemoteObjectSubtypeRegexp
+    "date" -> pure RuntimeRemoteObjectSubtypeDate
+    "map" -> pure RuntimeRemoteObjectSubtypeMap
+    "set" -> pure RuntimeRemoteObjectSubtypeSet
+    "weakmap" -> pure RuntimeRemoteObjectSubtypeWeakmap
+    "weakset" -> pure RuntimeRemoteObjectSubtypeWeakset
+    "iterator" -> pure RuntimeRemoteObjectSubtypeIterator
+    "generator" -> pure RuntimeRemoteObjectSubtypeGenerator
+    "error" -> pure RuntimeRemoteObjectSubtypeError
+    "proxy" -> pure RuntimeRemoteObjectSubtypeProxy
+    "promise" -> pure RuntimeRemoteObjectSubtypePromise
+    "typedarray" -> pure RuntimeRemoteObjectSubtypeTypedarray
+    "arraybuffer" -> pure RuntimeRemoteObjectSubtypeArraybuffer
+    "dataview" -> pure RuntimeRemoteObjectSubtypeDataview
+    "webassemblymemory" -> pure RuntimeRemoteObjectSubtypeWebassemblymemory
+    "wasmvalue" -> pure RuntimeRemoteObjectSubtypeWasmvalue
+    "_" -> fail "failed to parse RuntimeRemoteObjectSubtype"
+instance ToJSON RuntimeRemoteObjectSubtype where
+  toJSON v = A.String $ case v of
+    RuntimeRemoteObjectSubtypeArray -> "array"
+    RuntimeRemoteObjectSubtypeNull -> "null"
+    RuntimeRemoteObjectSubtypeNode -> "node"
+    RuntimeRemoteObjectSubtypeRegexp -> "regexp"
+    RuntimeRemoteObjectSubtypeDate -> "date"
+    RuntimeRemoteObjectSubtypeMap -> "map"
+    RuntimeRemoteObjectSubtypeSet -> "set"
+    RuntimeRemoteObjectSubtypeWeakmap -> "weakmap"
+    RuntimeRemoteObjectSubtypeWeakset -> "weakset"
+    RuntimeRemoteObjectSubtypeIterator -> "iterator"
+    RuntimeRemoteObjectSubtypeGenerator -> "generator"
+    RuntimeRemoteObjectSubtypeError -> "error"
+    RuntimeRemoteObjectSubtypeProxy -> "proxy"
+    RuntimeRemoteObjectSubtypePromise -> "promise"
+    RuntimeRemoteObjectSubtypeTypedarray -> "typedarray"
+    RuntimeRemoteObjectSubtypeArraybuffer -> "arraybuffer"
+    RuntimeRemoteObjectSubtypeDataview -> "dataview"
+    RuntimeRemoteObjectSubtypeWebassemblymemory -> "webassemblymemory"
+    RuntimeRemoteObjectSubtypeWasmvalue -> "wasmvalue"
+data RuntimeRemoteObject = RuntimeRemoteObject
+  {
+    -- | Object type.
+    runtimeRemoteObjectType :: RuntimeRemoteObjectType,
+    -- | Object subtype hint. Specified for `object` type values only.
+    --   NOTE: If you change anything here, make sure to also update
+    --   `subtype` in `ObjectPreview` and `PropertyPreview` below.
+    runtimeRemoteObjectSubtype :: Maybe RuntimeRemoteObjectSubtype,
+    -- | Object class (constructor) name. Specified for `object` type values only.
+    runtimeRemoteObjectClassName :: Maybe T.Text,
+    -- | Remote object value in case of primitive values or JSON values (if it was requested).
+    runtimeRemoteObjectValue :: Maybe A.Value,
+    -- | Primitive value which can not be JSON-stringified does not have `value`, but gets this
+    --   property.
+    runtimeRemoteObjectUnserializableValue :: Maybe RuntimeUnserializableValue,
+    -- | String representation of the object.
+    runtimeRemoteObjectDescription :: Maybe T.Text,
+    -- | WebDriver BiDi representation of the value.
+    runtimeRemoteObjectWebDriverValue :: Maybe RuntimeWebDriverValue,
+    -- | Unique object identifier (for non-primitive values).
+    runtimeRemoteObjectObjectId :: Maybe RuntimeRemoteObjectId,
+    -- | Preview containing abbreviated property values. Specified for `object` type values only.
+    runtimeRemoteObjectPreview :: Maybe RuntimeObjectPreview,
+    runtimeRemoteObjectCustomPreview :: Maybe RuntimeCustomPreview
+  }
+  deriving (Eq, Show)
+instance FromJSON RuntimeRemoteObject where
+  parseJSON = A.withObject "RuntimeRemoteObject" $ \o -> RuntimeRemoteObject
+    <$> o A..: "type"
+    <*> o A..:? "subtype"
+    <*> o A..:? "className"
+    <*> o A..:? "value"
+    <*> o A..:? "unserializableValue"
+    <*> o A..:? "description"
+    <*> o A..:? "webDriverValue"
+    <*> o A..:? "objectId"
+    <*> o A..:? "preview"
+    <*> o A..:? "customPreview"
+instance ToJSON RuntimeRemoteObject where
+  toJSON p = A.object $ catMaybes [
+    ("type" A..=) <$> Just (runtimeRemoteObjectType p),
+    ("subtype" A..=) <$> (runtimeRemoteObjectSubtype p),
+    ("className" A..=) <$> (runtimeRemoteObjectClassName p),
+    ("value" A..=) <$> (runtimeRemoteObjectValue p),
+    ("unserializableValue" A..=) <$> (runtimeRemoteObjectUnserializableValue p),
+    ("description" A..=) <$> (runtimeRemoteObjectDescription p),
+    ("webDriverValue" A..=) <$> (runtimeRemoteObjectWebDriverValue p),
+    ("objectId" A..=) <$> (runtimeRemoteObjectObjectId p),
+    ("preview" A..=) <$> (runtimeRemoteObjectPreview p),
+    ("customPreview" A..=) <$> (runtimeRemoteObjectCustomPreview p)
+    ]
+
+-- | Type 'Runtime.CustomPreview'.
+data RuntimeCustomPreview = RuntimeCustomPreview
+  {
+    -- | The JSON-stringified result of formatter.header(object, config) call.
+    --   It contains json ML array that represents RemoteObject.
+    runtimeCustomPreviewHeader :: T.Text,
+    -- | If formatter returns true as a result of formatter.hasBody call then bodyGetterId will
+    --   contain RemoteObjectId for the function that returns result of formatter.body(object, config) call.
+    --   The result value is json ML array.
+    runtimeCustomPreviewBodyGetterId :: Maybe RuntimeRemoteObjectId
+  }
+  deriving (Eq, Show)
+instance FromJSON RuntimeCustomPreview where
+  parseJSON = A.withObject "RuntimeCustomPreview" $ \o -> RuntimeCustomPreview
+    <$> o A..: "header"
+    <*> o A..:? "bodyGetterId"
+instance ToJSON RuntimeCustomPreview where
+  toJSON p = A.object $ catMaybes [
+    ("header" A..=) <$> Just (runtimeCustomPreviewHeader p),
+    ("bodyGetterId" A..=) <$> (runtimeCustomPreviewBodyGetterId p)
+    ]
+
+-- | Type 'Runtime.ObjectPreview'.
+--   Object containing abbreviated remote object value.
+data RuntimeObjectPreviewType = RuntimeObjectPreviewTypeObject | RuntimeObjectPreviewTypeFunction | RuntimeObjectPreviewTypeUndefined | RuntimeObjectPreviewTypeString | RuntimeObjectPreviewTypeNumber | RuntimeObjectPreviewTypeBoolean | RuntimeObjectPreviewTypeSymbol | RuntimeObjectPreviewTypeBigint
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON RuntimeObjectPreviewType where
+  parseJSON = A.withText "RuntimeObjectPreviewType" $ \v -> case v of
+    "object" -> pure RuntimeObjectPreviewTypeObject
+    "function" -> pure RuntimeObjectPreviewTypeFunction
+    "undefined" -> pure RuntimeObjectPreviewTypeUndefined
+    "string" -> pure RuntimeObjectPreviewTypeString
+    "number" -> pure RuntimeObjectPreviewTypeNumber
+    "boolean" -> pure RuntimeObjectPreviewTypeBoolean
+    "symbol" -> pure RuntimeObjectPreviewTypeSymbol
+    "bigint" -> pure RuntimeObjectPreviewTypeBigint
+    "_" -> fail "failed to parse RuntimeObjectPreviewType"
+instance ToJSON RuntimeObjectPreviewType where
+  toJSON v = A.String $ case v of
+    RuntimeObjectPreviewTypeObject -> "object"
+    RuntimeObjectPreviewTypeFunction -> "function"
+    RuntimeObjectPreviewTypeUndefined -> "undefined"
+    RuntimeObjectPreviewTypeString -> "string"
+    RuntimeObjectPreviewTypeNumber -> "number"
+    RuntimeObjectPreviewTypeBoolean -> "boolean"
+    RuntimeObjectPreviewTypeSymbol -> "symbol"
+    RuntimeObjectPreviewTypeBigint -> "bigint"
+data RuntimeObjectPreviewSubtype = RuntimeObjectPreviewSubtypeArray | RuntimeObjectPreviewSubtypeNull | RuntimeObjectPreviewSubtypeNode | RuntimeObjectPreviewSubtypeRegexp | RuntimeObjectPreviewSubtypeDate | RuntimeObjectPreviewSubtypeMap | RuntimeObjectPreviewSubtypeSet | RuntimeObjectPreviewSubtypeWeakmap | RuntimeObjectPreviewSubtypeWeakset | RuntimeObjectPreviewSubtypeIterator | RuntimeObjectPreviewSubtypeGenerator | RuntimeObjectPreviewSubtypeError | RuntimeObjectPreviewSubtypeProxy | RuntimeObjectPreviewSubtypePromise | RuntimeObjectPreviewSubtypeTypedarray | RuntimeObjectPreviewSubtypeArraybuffer | RuntimeObjectPreviewSubtypeDataview | RuntimeObjectPreviewSubtypeWebassemblymemory | RuntimeObjectPreviewSubtypeWasmvalue
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON RuntimeObjectPreviewSubtype where
+  parseJSON = A.withText "RuntimeObjectPreviewSubtype" $ \v -> case v of
+    "array" -> pure RuntimeObjectPreviewSubtypeArray
+    "null" -> pure RuntimeObjectPreviewSubtypeNull
+    "node" -> pure RuntimeObjectPreviewSubtypeNode
+    "regexp" -> pure RuntimeObjectPreviewSubtypeRegexp
+    "date" -> pure RuntimeObjectPreviewSubtypeDate
+    "map" -> pure RuntimeObjectPreviewSubtypeMap
+    "set" -> pure RuntimeObjectPreviewSubtypeSet
+    "weakmap" -> pure RuntimeObjectPreviewSubtypeWeakmap
+    "weakset" -> pure RuntimeObjectPreviewSubtypeWeakset
+    "iterator" -> pure RuntimeObjectPreviewSubtypeIterator
+    "generator" -> pure RuntimeObjectPreviewSubtypeGenerator
+    "error" -> pure RuntimeObjectPreviewSubtypeError
+    "proxy" -> pure RuntimeObjectPreviewSubtypeProxy
+    "promise" -> pure RuntimeObjectPreviewSubtypePromise
+    "typedarray" -> pure RuntimeObjectPreviewSubtypeTypedarray
+    "arraybuffer" -> pure RuntimeObjectPreviewSubtypeArraybuffer
+    "dataview" -> pure RuntimeObjectPreviewSubtypeDataview
+    "webassemblymemory" -> pure RuntimeObjectPreviewSubtypeWebassemblymemory
+    "wasmvalue" -> pure RuntimeObjectPreviewSubtypeWasmvalue
+    "_" -> fail "failed to parse RuntimeObjectPreviewSubtype"
+instance ToJSON RuntimeObjectPreviewSubtype where
+  toJSON v = A.String $ case v of
+    RuntimeObjectPreviewSubtypeArray -> "array"
+    RuntimeObjectPreviewSubtypeNull -> "null"
+    RuntimeObjectPreviewSubtypeNode -> "node"
+    RuntimeObjectPreviewSubtypeRegexp -> "regexp"
+    RuntimeObjectPreviewSubtypeDate -> "date"
+    RuntimeObjectPreviewSubtypeMap -> "map"
+    RuntimeObjectPreviewSubtypeSet -> "set"
+    RuntimeObjectPreviewSubtypeWeakmap -> "weakmap"
+    RuntimeObjectPreviewSubtypeWeakset -> "weakset"
+    RuntimeObjectPreviewSubtypeIterator -> "iterator"
+    RuntimeObjectPreviewSubtypeGenerator -> "generator"
+    RuntimeObjectPreviewSubtypeError -> "error"
+    RuntimeObjectPreviewSubtypeProxy -> "proxy"
+    RuntimeObjectPreviewSubtypePromise -> "promise"
+    RuntimeObjectPreviewSubtypeTypedarray -> "typedarray"
+    RuntimeObjectPreviewSubtypeArraybuffer -> "arraybuffer"
+    RuntimeObjectPreviewSubtypeDataview -> "dataview"
+    RuntimeObjectPreviewSubtypeWebassemblymemory -> "webassemblymemory"
+    RuntimeObjectPreviewSubtypeWasmvalue -> "wasmvalue"
+data RuntimeObjectPreview = RuntimeObjectPreview
+  {
+    -- | Object type.
+    runtimeObjectPreviewType :: RuntimeObjectPreviewType,
+    -- | Object subtype hint. Specified for `object` type values only.
+    runtimeObjectPreviewSubtype :: Maybe RuntimeObjectPreviewSubtype,
+    -- | String representation of the object.
+    runtimeObjectPreviewDescription :: Maybe T.Text,
+    -- | True iff some of the properties or entries of the original object did not fit.
+    runtimeObjectPreviewOverflow :: Bool,
+    -- | List of the properties.
+    runtimeObjectPreviewProperties :: [RuntimePropertyPreview],
+    -- | List of the entries. Specified for `map` and `set` subtype values only.
+    runtimeObjectPreviewEntries :: Maybe [RuntimeEntryPreview]
+  }
+  deriving (Eq, Show)
+instance FromJSON RuntimeObjectPreview where
+  parseJSON = A.withObject "RuntimeObjectPreview" $ \o -> RuntimeObjectPreview
+    <$> o A..: "type"
+    <*> o A..:? "subtype"
+    <*> o A..:? "description"
+    <*> o A..: "overflow"
+    <*> o A..: "properties"
+    <*> o A..:? "entries"
+instance ToJSON RuntimeObjectPreview where
+  toJSON p = A.object $ catMaybes [
+    ("type" A..=) <$> Just (runtimeObjectPreviewType p),
+    ("subtype" A..=) <$> (runtimeObjectPreviewSubtype p),
+    ("description" A..=) <$> (runtimeObjectPreviewDescription p),
+    ("overflow" A..=) <$> Just (runtimeObjectPreviewOverflow p),
+    ("properties" A..=) <$> Just (runtimeObjectPreviewProperties p),
+    ("entries" A..=) <$> (runtimeObjectPreviewEntries p)
+    ]
+
+-- | Type 'Runtime.PropertyPreview'.
+data RuntimePropertyPreviewType = RuntimePropertyPreviewTypeObject | RuntimePropertyPreviewTypeFunction | RuntimePropertyPreviewTypeUndefined | RuntimePropertyPreviewTypeString | RuntimePropertyPreviewTypeNumber | RuntimePropertyPreviewTypeBoolean | RuntimePropertyPreviewTypeSymbol | RuntimePropertyPreviewTypeAccessor | RuntimePropertyPreviewTypeBigint
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON RuntimePropertyPreviewType where
+  parseJSON = A.withText "RuntimePropertyPreviewType" $ \v -> case v of
+    "object" -> pure RuntimePropertyPreviewTypeObject
+    "function" -> pure RuntimePropertyPreviewTypeFunction
+    "undefined" -> pure RuntimePropertyPreviewTypeUndefined
+    "string" -> pure RuntimePropertyPreviewTypeString
+    "number" -> pure RuntimePropertyPreviewTypeNumber
+    "boolean" -> pure RuntimePropertyPreviewTypeBoolean
+    "symbol" -> pure RuntimePropertyPreviewTypeSymbol
+    "accessor" -> pure RuntimePropertyPreviewTypeAccessor
+    "bigint" -> pure RuntimePropertyPreviewTypeBigint
+    "_" -> fail "failed to parse RuntimePropertyPreviewType"
+instance ToJSON RuntimePropertyPreviewType where
+  toJSON v = A.String $ case v of
+    RuntimePropertyPreviewTypeObject -> "object"
+    RuntimePropertyPreviewTypeFunction -> "function"
+    RuntimePropertyPreviewTypeUndefined -> "undefined"
+    RuntimePropertyPreviewTypeString -> "string"
+    RuntimePropertyPreviewTypeNumber -> "number"
+    RuntimePropertyPreviewTypeBoolean -> "boolean"
+    RuntimePropertyPreviewTypeSymbol -> "symbol"
+    RuntimePropertyPreviewTypeAccessor -> "accessor"
+    RuntimePropertyPreviewTypeBigint -> "bigint"
+data RuntimePropertyPreviewSubtype = RuntimePropertyPreviewSubtypeArray | RuntimePropertyPreviewSubtypeNull | RuntimePropertyPreviewSubtypeNode | RuntimePropertyPreviewSubtypeRegexp | RuntimePropertyPreviewSubtypeDate | RuntimePropertyPreviewSubtypeMap | RuntimePropertyPreviewSubtypeSet | RuntimePropertyPreviewSubtypeWeakmap | RuntimePropertyPreviewSubtypeWeakset | RuntimePropertyPreviewSubtypeIterator | RuntimePropertyPreviewSubtypeGenerator | RuntimePropertyPreviewSubtypeError | RuntimePropertyPreviewSubtypeProxy | RuntimePropertyPreviewSubtypePromise | RuntimePropertyPreviewSubtypeTypedarray | RuntimePropertyPreviewSubtypeArraybuffer | RuntimePropertyPreviewSubtypeDataview | RuntimePropertyPreviewSubtypeWebassemblymemory | RuntimePropertyPreviewSubtypeWasmvalue
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON RuntimePropertyPreviewSubtype where
+  parseJSON = A.withText "RuntimePropertyPreviewSubtype" $ \v -> case v of
+    "array" -> pure RuntimePropertyPreviewSubtypeArray
+    "null" -> pure RuntimePropertyPreviewSubtypeNull
+    "node" -> pure RuntimePropertyPreviewSubtypeNode
+    "regexp" -> pure RuntimePropertyPreviewSubtypeRegexp
+    "date" -> pure RuntimePropertyPreviewSubtypeDate
+    "map" -> pure RuntimePropertyPreviewSubtypeMap
+    "set" -> pure RuntimePropertyPreviewSubtypeSet
+    "weakmap" -> pure RuntimePropertyPreviewSubtypeWeakmap
+    "weakset" -> pure RuntimePropertyPreviewSubtypeWeakset
+    "iterator" -> pure RuntimePropertyPreviewSubtypeIterator
+    "generator" -> pure RuntimePropertyPreviewSubtypeGenerator
+    "error" -> pure RuntimePropertyPreviewSubtypeError
+    "proxy" -> pure RuntimePropertyPreviewSubtypeProxy
+    "promise" -> pure RuntimePropertyPreviewSubtypePromise
+    "typedarray" -> pure RuntimePropertyPreviewSubtypeTypedarray
+    "arraybuffer" -> pure RuntimePropertyPreviewSubtypeArraybuffer
+    "dataview" -> pure RuntimePropertyPreviewSubtypeDataview
+    "webassemblymemory" -> pure RuntimePropertyPreviewSubtypeWebassemblymemory
+    "wasmvalue" -> pure RuntimePropertyPreviewSubtypeWasmvalue
+    "_" -> fail "failed to parse RuntimePropertyPreviewSubtype"
+instance ToJSON RuntimePropertyPreviewSubtype where
+  toJSON v = A.String $ case v of
+    RuntimePropertyPreviewSubtypeArray -> "array"
+    RuntimePropertyPreviewSubtypeNull -> "null"
+    RuntimePropertyPreviewSubtypeNode -> "node"
+    RuntimePropertyPreviewSubtypeRegexp -> "regexp"
+    RuntimePropertyPreviewSubtypeDate -> "date"
+    RuntimePropertyPreviewSubtypeMap -> "map"
+    RuntimePropertyPreviewSubtypeSet -> "set"
+    RuntimePropertyPreviewSubtypeWeakmap -> "weakmap"
+    RuntimePropertyPreviewSubtypeWeakset -> "weakset"
+    RuntimePropertyPreviewSubtypeIterator -> "iterator"
+    RuntimePropertyPreviewSubtypeGenerator -> "generator"
+    RuntimePropertyPreviewSubtypeError -> "error"
+    RuntimePropertyPreviewSubtypeProxy -> "proxy"
+    RuntimePropertyPreviewSubtypePromise -> "promise"
+    RuntimePropertyPreviewSubtypeTypedarray -> "typedarray"
+    RuntimePropertyPreviewSubtypeArraybuffer -> "arraybuffer"
+    RuntimePropertyPreviewSubtypeDataview -> "dataview"
+    RuntimePropertyPreviewSubtypeWebassemblymemory -> "webassemblymemory"
+    RuntimePropertyPreviewSubtypeWasmvalue -> "wasmvalue"
+data RuntimePropertyPreview = RuntimePropertyPreview
+  {
+    -- | Property name.
+    runtimePropertyPreviewName :: T.Text,
+    -- | Object type. Accessor means that the property itself is an accessor property.
+    runtimePropertyPreviewType :: RuntimePropertyPreviewType,
+    -- | User-friendly property value string.
+    runtimePropertyPreviewValue :: Maybe T.Text,
+    -- | Nested value preview.
+    runtimePropertyPreviewValuePreview :: Maybe RuntimeObjectPreview,
+    -- | Object subtype hint. Specified for `object` type values only.
+    runtimePropertyPreviewSubtype :: Maybe RuntimePropertyPreviewSubtype
+  }
+  deriving (Eq, Show)
+instance FromJSON RuntimePropertyPreview where
+  parseJSON = A.withObject "RuntimePropertyPreview" $ \o -> RuntimePropertyPreview
+    <$> o A..: "name"
+    <*> o A..: "type"
+    <*> o A..:? "value"
+    <*> o A..:? "valuePreview"
+    <*> o A..:? "subtype"
+instance ToJSON RuntimePropertyPreview where
+  toJSON p = A.object $ catMaybes [
+    ("name" A..=) <$> Just (runtimePropertyPreviewName p),
+    ("type" A..=) <$> Just (runtimePropertyPreviewType p),
+    ("value" A..=) <$> (runtimePropertyPreviewValue p),
+    ("valuePreview" A..=) <$> (runtimePropertyPreviewValuePreview p),
+    ("subtype" A..=) <$> (runtimePropertyPreviewSubtype p)
+    ]
+
+-- | Type 'Runtime.EntryPreview'.
+data RuntimeEntryPreview = RuntimeEntryPreview
+  {
+    -- | Preview of the key. Specified for map-like collection entries.
+    runtimeEntryPreviewKey :: Maybe RuntimeObjectPreview,
+    -- | Preview of the value.
+    runtimeEntryPreviewValue :: RuntimeObjectPreview
+  }
+  deriving (Eq, Show)
+instance FromJSON RuntimeEntryPreview where
+  parseJSON = A.withObject "RuntimeEntryPreview" $ \o -> RuntimeEntryPreview
+    <$> o A..:? "key"
+    <*> o A..: "value"
+instance ToJSON RuntimeEntryPreview where
+  toJSON p = A.object $ catMaybes [
+    ("key" A..=) <$> (runtimeEntryPreviewKey p),
+    ("value" A..=) <$> Just (runtimeEntryPreviewValue p)
+    ]
+
+-- | Type 'Runtime.PropertyDescriptor'.
+--   Object property descriptor.
+data RuntimePropertyDescriptor = RuntimePropertyDescriptor
+  {
+    -- | Property name or symbol description.
+    runtimePropertyDescriptorName :: T.Text,
+    -- | The value associated with the property.
+    runtimePropertyDescriptorValue :: Maybe RuntimeRemoteObject,
+    -- | True if the value associated with the property may be changed (data descriptors only).
+    runtimePropertyDescriptorWritable :: Maybe Bool,
+    -- | A function which serves as a getter for the property, or `undefined` if there is no getter
+    --   (accessor descriptors only).
+    runtimePropertyDescriptorGet :: Maybe RuntimeRemoteObject,
+    -- | A function which serves as a setter for the property, or `undefined` if there is no setter
+    --   (accessor descriptors only).
+    runtimePropertyDescriptorSet :: Maybe RuntimeRemoteObject,
+    -- | True if the type of this property descriptor may be changed and if the property may be
+    --   deleted from the corresponding object.
+    runtimePropertyDescriptorConfigurable :: Bool,
+    -- | True if this property shows up during enumeration of the properties on the corresponding
+    --   object.
+    runtimePropertyDescriptorEnumerable :: Bool,
+    -- | True if the result was thrown during the evaluation.
+    runtimePropertyDescriptorWasThrown :: Maybe Bool,
+    -- | True if the property is owned for the object.
+    runtimePropertyDescriptorIsOwn :: Maybe Bool,
+    -- | Property symbol object, if the property is of the `symbol` type.
+    runtimePropertyDescriptorSymbol :: Maybe RuntimeRemoteObject
+  }
+  deriving (Eq, Show)
+instance FromJSON RuntimePropertyDescriptor where
+  parseJSON = A.withObject "RuntimePropertyDescriptor" $ \o -> RuntimePropertyDescriptor
+    <$> o A..: "name"
+    <*> o A..:? "value"
+    <*> o A..:? "writable"
+    <*> o A..:? "get"
+    <*> o A..:? "set"
+    <*> o A..: "configurable"
+    <*> o A..: "enumerable"
+    <*> o A..:? "wasThrown"
+    <*> o A..:? "isOwn"
+    <*> o A..:? "symbol"
+instance ToJSON RuntimePropertyDescriptor where
+  toJSON p = A.object $ catMaybes [
+    ("name" A..=) <$> Just (runtimePropertyDescriptorName p),
+    ("value" A..=) <$> (runtimePropertyDescriptorValue p),
+    ("writable" A..=) <$> (runtimePropertyDescriptorWritable p),
+    ("get" A..=) <$> (runtimePropertyDescriptorGet p),
+    ("set" A..=) <$> (runtimePropertyDescriptorSet p),
+    ("configurable" A..=) <$> Just (runtimePropertyDescriptorConfigurable p),
+    ("enumerable" A..=) <$> Just (runtimePropertyDescriptorEnumerable p),
+    ("wasThrown" A..=) <$> (runtimePropertyDescriptorWasThrown p),
+    ("isOwn" A..=) <$> (runtimePropertyDescriptorIsOwn p),
+    ("symbol" A..=) <$> (runtimePropertyDescriptorSymbol p)
+    ]
+
+-- | Type 'Runtime.InternalPropertyDescriptor'.
+--   Object internal property descriptor. This property isn't normally visible in JavaScript code.
+data RuntimeInternalPropertyDescriptor = RuntimeInternalPropertyDescriptor
+  {
+    -- | Conventional property name.
+    runtimeInternalPropertyDescriptorName :: T.Text,
+    -- | The value associated with the property.
+    runtimeInternalPropertyDescriptorValue :: Maybe RuntimeRemoteObject
+  }
+  deriving (Eq, Show)
+instance FromJSON RuntimeInternalPropertyDescriptor where
+  parseJSON = A.withObject "RuntimeInternalPropertyDescriptor" $ \o -> RuntimeInternalPropertyDescriptor
+    <$> o A..: "name"
+    <*> o A..:? "value"
+instance ToJSON RuntimeInternalPropertyDescriptor where
+  toJSON p = A.object $ catMaybes [
+    ("name" A..=) <$> Just (runtimeInternalPropertyDescriptorName p),
+    ("value" A..=) <$> (runtimeInternalPropertyDescriptorValue p)
+    ]
+
+-- | Type 'Runtime.PrivatePropertyDescriptor'.
+--   Object private field descriptor.
+data RuntimePrivatePropertyDescriptor = RuntimePrivatePropertyDescriptor
+  {
+    -- | Private property name.
+    runtimePrivatePropertyDescriptorName :: T.Text,
+    -- | The value associated with the private property.
+    runtimePrivatePropertyDescriptorValue :: Maybe RuntimeRemoteObject,
+    -- | A function which serves as a getter for the private property,
+    --   or `undefined` if there is no getter (accessor descriptors only).
+    runtimePrivatePropertyDescriptorGet :: Maybe RuntimeRemoteObject,
+    -- | A function which serves as a setter for the private property,
+    --   or `undefined` if there is no setter (accessor descriptors only).
+    runtimePrivatePropertyDescriptorSet :: Maybe RuntimeRemoteObject
+  }
+  deriving (Eq, Show)
+instance FromJSON RuntimePrivatePropertyDescriptor where
+  parseJSON = A.withObject "RuntimePrivatePropertyDescriptor" $ \o -> RuntimePrivatePropertyDescriptor
+    <$> o A..: "name"
+    <*> o A..:? "value"
+    <*> o A..:? "get"
+    <*> o A..:? "set"
+instance ToJSON RuntimePrivatePropertyDescriptor where
+  toJSON p = A.object $ catMaybes [
+    ("name" A..=) <$> Just (runtimePrivatePropertyDescriptorName p),
+    ("value" A..=) <$> (runtimePrivatePropertyDescriptorValue p),
+    ("get" A..=) <$> (runtimePrivatePropertyDescriptorGet p),
+    ("set" A..=) <$> (runtimePrivatePropertyDescriptorSet p)
+    ]
+
+-- | Type 'Runtime.CallArgument'.
+--   Represents function call argument. Either remote object id `objectId`, primitive `value`,
+--   unserializable primitive value or neither of (for undefined) them should be specified.
+data RuntimeCallArgument = RuntimeCallArgument
+  {
+    -- | Primitive value or serializable javascript object.
+    runtimeCallArgumentValue :: Maybe A.Value,
+    -- | Primitive value which can not be JSON-stringified.
+    runtimeCallArgumentUnserializableValue :: Maybe RuntimeUnserializableValue,
+    -- | Remote object handle.
+    runtimeCallArgumentObjectId :: Maybe RuntimeRemoteObjectId
+  }
+  deriving (Eq, Show)
+instance FromJSON RuntimeCallArgument where
+  parseJSON = A.withObject "RuntimeCallArgument" $ \o -> RuntimeCallArgument
+    <$> o A..:? "value"
+    <*> o A..:? "unserializableValue"
+    <*> o A..:? "objectId"
+instance ToJSON RuntimeCallArgument where
+  toJSON p = A.object $ catMaybes [
+    ("value" A..=) <$> (runtimeCallArgumentValue p),
+    ("unserializableValue" A..=) <$> (runtimeCallArgumentUnserializableValue p),
+    ("objectId" A..=) <$> (runtimeCallArgumentObjectId p)
+    ]
+
+-- | Type 'Runtime.ExecutionContextId'.
+--   Id of an execution context.
+type RuntimeExecutionContextId = Int
+
+-- | Type 'Runtime.ExecutionContextDescription'.
+--   Description of an isolated world.
+data RuntimeExecutionContextDescription = RuntimeExecutionContextDescription
+  {
+    -- | Unique id of the execution context. It can be used to specify in which execution context
+    --   script evaluation should be performed.
+    runtimeExecutionContextDescriptionId :: RuntimeExecutionContextId,
+    -- | Execution context origin.
+    runtimeExecutionContextDescriptionOrigin :: T.Text,
+    -- | Human readable name describing given context.
+    runtimeExecutionContextDescriptionName :: T.Text,
+    -- | A system-unique execution context identifier. Unlike the id, this is unique across
+    --   multiple processes, so can be reliably used to identify specific context while backend
+    --   performs a cross-process navigation.
+    runtimeExecutionContextDescriptionUniqueId :: T.Text,
+    -- | Embedder-specific auxiliary data.
+    runtimeExecutionContextDescriptionAuxData :: Maybe [(T.Text, T.Text)]
+  }
+  deriving (Eq, Show)
+instance FromJSON RuntimeExecutionContextDescription where
+  parseJSON = A.withObject "RuntimeExecutionContextDescription" $ \o -> RuntimeExecutionContextDescription
+    <$> o A..: "id"
+    <*> o A..: "origin"
+    <*> o A..: "name"
+    <*> o A..: "uniqueId"
+    <*> o A..:? "auxData"
+instance ToJSON RuntimeExecutionContextDescription where
+  toJSON p = A.object $ catMaybes [
+    ("id" A..=) <$> Just (runtimeExecutionContextDescriptionId p),
+    ("origin" A..=) <$> Just (runtimeExecutionContextDescriptionOrigin p),
+    ("name" A..=) <$> Just (runtimeExecutionContextDescriptionName p),
+    ("uniqueId" A..=) <$> Just (runtimeExecutionContextDescriptionUniqueId p),
+    ("auxData" A..=) <$> (runtimeExecutionContextDescriptionAuxData p)
+    ]
+
+-- | Type 'Runtime.ExceptionDetails'.
+--   Detailed information about exception (or error) that was thrown during script compilation or
+--   execution.
+data RuntimeExceptionDetails = RuntimeExceptionDetails
+  {
+    -- | Exception id.
+    runtimeExceptionDetailsExceptionId :: Int,
+    -- | Exception text, which should be used together with exception object when available.
+    runtimeExceptionDetailsText :: T.Text,
+    -- | Line number of the exception location (0-based).
+    runtimeExceptionDetailsLineNumber :: Int,
+    -- | Column number of the exception location (0-based).
+    runtimeExceptionDetailsColumnNumber :: Int,
+    -- | Script ID of the exception location.
+    runtimeExceptionDetailsScriptId :: Maybe RuntimeScriptId,
+    -- | URL of the exception location, to be used when the script was not reported.
+    runtimeExceptionDetailsUrl :: Maybe T.Text,
+    -- | JavaScript stack trace if available.
+    runtimeExceptionDetailsStackTrace :: Maybe RuntimeStackTrace,
+    -- | Exception object if available.
+    runtimeExceptionDetailsException :: Maybe RuntimeRemoteObject,
+    -- | Identifier of the context where exception happened.
+    runtimeExceptionDetailsExecutionContextId :: Maybe RuntimeExecutionContextId,
+    -- | Dictionary with entries of meta data that the client associated
+    --   with this exception, such as information about associated network
+    --   requests, etc.
+    runtimeExceptionDetailsExceptionMetaData :: Maybe [(T.Text, T.Text)]
+  }
+  deriving (Eq, Show)
+instance FromJSON RuntimeExceptionDetails where
+  parseJSON = A.withObject "RuntimeExceptionDetails" $ \o -> RuntimeExceptionDetails
+    <$> o A..: "exceptionId"
+    <*> o A..: "text"
+    <*> o A..: "lineNumber"
+    <*> o A..: "columnNumber"
+    <*> o A..:? "scriptId"
+    <*> o A..:? "url"
+    <*> o A..:? "stackTrace"
+    <*> o A..:? "exception"
+    <*> o A..:? "executionContextId"
+    <*> o A..:? "exceptionMetaData"
+instance ToJSON RuntimeExceptionDetails where
+  toJSON p = A.object $ catMaybes [
+    ("exceptionId" A..=) <$> Just (runtimeExceptionDetailsExceptionId p),
+    ("text" A..=) <$> Just (runtimeExceptionDetailsText p),
+    ("lineNumber" A..=) <$> Just (runtimeExceptionDetailsLineNumber p),
+    ("columnNumber" A..=) <$> Just (runtimeExceptionDetailsColumnNumber p),
+    ("scriptId" A..=) <$> (runtimeExceptionDetailsScriptId p),
+    ("url" A..=) <$> (runtimeExceptionDetailsUrl p),
+    ("stackTrace" A..=) <$> (runtimeExceptionDetailsStackTrace p),
+    ("exception" A..=) <$> (runtimeExceptionDetailsException p),
+    ("executionContextId" A..=) <$> (runtimeExceptionDetailsExecutionContextId p),
+    ("exceptionMetaData" A..=) <$> (runtimeExceptionDetailsExceptionMetaData p)
+    ]
+
+-- | Type 'Runtime.Timestamp'.
+--   Number of milliseconds since epoch.
+type RuntimeTimestamp = Double
+
+-- | Type 'Runtime.TimeDelta'.
+--   Number of milliseconds.
+type RuntimeTimeDelta = Double
+
+-- | Type 'Runtime.CallFrame'.
+--   Stack entry for runtime errors and assertions.
+data RuntimeCallFrame = RuntimeCallFrame
+  {
+    -- | JavaScript function name.
+    runtimeCallFrameFunctionName :: T.Text,
+    -- | JavaScript script id.
+    runtimeCallFrameScriptId :: RuntimeScriptId,
+    -- | JavaScript script name or url.
+    runtimeCallFrameUrl :: T.Text,
+    -- | JavaScript script line number (0-based).
+    runtimeCallFrameLineNumber :: Int,
+    -- | JavaScript script column number (0-based).
+    runtimeCallFrameColumnNumber :: Int
+  }
+  deriving (Eq, Show)
+instance FromJSON RuntimeCallFrame where
+  parseJSON = A.withObject "RuntimeCallFrame" $ \o -> RuntimeCallFrame
+    <$> o A..: "functionName"
+    <*> o A..: "scriptId"
+    <*> o A..: "url"
+    <*> o A..: "lineNumber"
+    <*> o A..: "columnNumber"
+instance ToJSON RuntimeCallFrame where
+  toJSON p = A.object $ catMaybes [
+    ("functionName" A..=) <$> Just (runtimeCallFrameFunctionName p),
+    ("scriptId" A..=) <$> Just (runtimeCallFrameScriptId p),
+    ("url" A..=) <$> Just (runtimeCallFrameUrl p),
+    ("lineNumber" A..=) <$> Just (runtimeCallFrameLineNumber p),
+    ("columnNumber" A..=) <$> Just (runtimeCallFrameColumnNumber p)
+    ]
+
+-- | Type 'Runtime.StackTrace'.
+--   Call frames for assertions or error messages.
+data RuntimeStackTrace = RuntimeStackTrace
+  {
+    -- | String label of this stack trace. For async traces this may be a name of the function that
+    --   initiated the async call.
+    runtimeStackTraceDescription :: Maybe T.Text,
+    -- | JavaScript function name.
+    runtimeStackTraceCallFrames :: [RuntimeCallFrame],
+    -- | Asynchronous JavaScript stack trace that preceded this stack, if available.
+    runtimeStackTraceParent :: Maybe RuntimeStackTrace,
+    -- | Asynchronous JavaScript stack trace that preceded this stack, if available.
+    runtimeStackTraceParentId :: Maybe RuntimeStackTraceId
+  }
+  deriving (Eq, Show)
+instance FromJSON RuntimeStackTrace where
+  parseJSON = A.withObject "RuntimeStackTrace" $ \o -> RuntimeStackTrace
+    <$> o A..:? "description"
+    <*> o A..: "callFrames"
+    <*> o A..:? "parent"
+    <*> o A..:? "parentId"
+instance ToJSON RuntimeStackTrace where
+  toJSON p = A.object $ catMaybes [
+    ("description" A..=) <$> (runtimeStackTraceDescription p),
+    ("callFrames" A..=) <$> Just (runtimeStackTraceCallFrames p),
+    ("parent" A..=) <$> (runtimeStackTraceParent p),
+    ("parentId" A..=) <$> (runtimeStackTraceParentId p)
+    ]
+
+-- | Type 'Runtime.UniqueDebuggerId'.
+--   Unique identifier of current debugger.
+type RuntimeUniqueDebuggerId = T.Text
+
+-- | Type 'Runtime.StackTraceId'.
+--   If `debuggerId` is set stack trace comes from another debugger and can be resolved there. This
+--   allows to track cross-debugger calls. See `Runtime.StackTrace` and `Debugger.paused` for usages.
+data RuntimeStackTraceId = RuntimeStackTraceId
+  {
+    runtimeStackTraceIdId :: T.Text,
+    runtimeStackTraceIdDebuggerId :: Maybe RuntimeUniqueDebuggerId
+  }
+  deriving (Eq, Show)
+instance FromJSON RuntimeStackTraceId where
+  parseJSON = A.withObject "RuntimeStackTraceId" $ \o -> RuntimeStackTraceId
+    <$> o A..: "id"
+    <*> o A..:? "debuggerId"
+instance ToJSON RuntimeStackTraceId where
+  toJSON p = A.object $ catMaybes [
+    ("id" A..=) <$> Just (runtimeStackTraceIdId p),
+    ("debuggerId" A..=) <$> (runtimeStackTraceIdDebuggerId p)
+    ]
+
+-- | Type of the 'Runtime.bindingCalled' event.
+data RuntimeBindingCalled = RuntimeBindingCalled
+  {
+    runtimeBindingCalledName :: T.Text,
+    runtimeBindingCalledPayload :: T.Text,
+    -- | Identifier of the context where the call was made.
+    runtimeBindingCalledExecutionContextId :: RuntimeExecutionContextId
+  }
+  deriving (Eq, Show)
+instance FromJSON RuntimeBindingCalled where
+  parseJSON = A.withObject "RuntimeBindingCalled" $ \o -> RuntimeBindingCalled
+    <$> o A..: "name"
+    <*> o A..: "payload"
+    <*> o A..: "executionContextId"
+instance Event RuntimeBindingCalled where
+  eventName _ = "Runtime.bindingCalled"
+
+-- | Type of the 'Runtime.consoleAPICalled' event.
+data RuntimeConsoleAPICalledType = RuntimeConsoleAPICalledTypeLog | RuntimeConsoleAPICalledTypeDebug | RuntimeConsoleAPICalledTypeInfo | RuntimeConsoleAPICalledTypeError | RuntimeConsoleAPICalledTypeWarning | RuntimeConsoleAPICalledTypeDir | RuntimeConsoleAPICalledTypeDirxml | RuntimeConsoleAPICalledTypeTable | RuntimeConsoleAPICalledTypeTrace | RuntimeConsoleAPICalledTypeClear | RuntimeConsoleAPICalledTypeStartGroup | RuntimeConsoleAPICalledTypeStartGroupCollapsed | RuntimeConsoleAPICalledTypeEndGroup | RuntimeConsoleAPICalledTypeAssert | RuntimeConsoleAPICalledTypeProfile | RuntimeConsoleAPICalledTypeProfileEnd | RuntimeConsoleAPICalledTypeCount | RuntimeConsoleAPICalledTypeTimeEnd
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON RuntimeConsoleAPICalledType where
+  parseJSON = A.withText "RuntimeConsoleAPICalledType" $ \v -> case v of
+    "log" -> pure RuntimeConsoleAPICalledTypeLog
+    "debug" -> pure RuntimeConsoleAPICalledTypeDebug
+    "info" -> pure RuntimeConsoleAPICalledTypeInfo
+    "error" -> pure RuntimeConsoleAPICalledTypeError
+    "warning" -> pure RuntimeConsoleAPICalledTypeWarning
+    "dir" -> pure RuntimeConsoleAPICalledTypeDir
+    "dirxml" -> pure RuntimeConsoleAPICalledTypeDirxml
+    "table" -> pure RuntimeConsoleAPICalledTypeTable
+    "trace" -> pure RuntimeConsoleAPICalledTypeTrace
+    "clear" -> pure RuntimeConsoleAPICalledTypeClear
+    "startGroup" -> pure RuntimeConsoleAPICalledTypeStartGroup
+    "startGroupCollapsed" -> pure RuntimeConsoleAPICalledTypeStartGroupCollapsed
+    "endGroup" -> pure RuntimeConsoleAPICalledTypeEndGroup
+    "assert" -> pure RuntimeConsoleAPICalledTypeAssert
+    "profile" -> pure RuntimeConsoleAPICalledTypeProfile
+    "profileEnd" -> pure RuntimeConsoleAPICalledTypeProfileEnd
+    "count" -> pure RuntimeConsoleAPICalledTypeCount
+    "timeEnd" -> pure RuntimeConsoleAPICalledTypeTimeEnd
+    "_" -> fail "failed to parse RuntimeConsoleAPICalledType"
+instance ToJSON RuntimeConsoleAPICalledType where
+  toJSON v = A.String $ case v of
+    RuntimeConsoleAPICalledTypeLog -> "log"
+    RuntimeConsoleAPICalledTypeDebug -> "debug"
+    RuntimeConsoleAPICalledTypeInfo -> "info"
+    RuntimeConsoleAPICalledTypeError -> "error"
+    RuntimeConsoleAPICalledTypeWarning -> "warning"
+    RuntimeConsoleAPICalledTypeDir -> "dir"
+    RuntimeConsoleAPICalledTypeDirxml -> "dirxml"
+    RuntimeConsoleAPICalledTypeTable -> "table"
+    RuntimeConsoleAPICalledTypeTrace -> "trace"
+    RuntimeConsoleAPICalledTypeClear -> "clear"
+    RuntimeConsoleAPICalledTypeStartGroup -> "startGroup"
+    RuntimeConsoleAPICalledTypeStartGroupCollapsed -> "startGroupCollapsed"
+    RuntimeConsoleAPICalledTypeEndGroup -> "endGroup"
+    RuntimeConsoleAPICalledTypeAssert -> "assert"
+    RuntimeConsoleAPICalledTypeProfile -> "profile"
+    RuntimeConsoleAPICalledTypeProfileEnd -> "profileEnd"
+    RuntimeConsoleAPICalledTypeCount -> "count"
+    RuntimeConsoleAPICalledTypeTimeEnd -> "timeEnd"
+data RuntimeConsoleAPICalled = RuntimeConsoleAPICalled
+  {
+    -- | Type of the call.
+    runtimeConsoleAPICalledType :: RuntimeConsoleAPICalledType,
+    -- | Call arguments.
+    runtimeConsoleAPICalledArgs :: [RuntimeRemoteObject],
+    -- | Identifier of the context where the call was made.
+    runtimeConsoleAPICalledExecutionContextId :: RuntimeExecutionContextId,
+    -- | Call timestamp.
+    runtimeConsoleAPICalledTimestamp :: RuntimeTimestamp,
+    -- | Stack trace captured when the call was made. The async stack chain is automatically reported for
+    --   the following call types: `assert`, `error`, `trace`, `warning`. For other types the async call
+    --   chain can be retrieved using `Debugger.getStackTrace` and `stackTrace.parentId` field.
+    runtimeConsoleAPICalledStackTrace :: Maybe RuntimeStackTrace,
+    -- | Console context descriptor for calls on non-default console context (not console.*):
+    --   'anonymous#unique-logger-id' for call on unnamed context, 'name#unique-logger-id' for call
+    --   on named context.
+    runtimeConsoleAPICalledContext :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON RuntimeConsoleAPICalled where
+  parseJSON = A.withObject "RuntimeConsoleAPICalled" $ \o -> RuntimeConsoleAPICalled
+    <$> o A..: "type"
+    <*> o A..: "args"
+    <*> o A..: "executionContextId"
+    <*> o A..: "timestamp"
+    <*> o A..:? "stackTrace"
+    <*> o A..:? "context"
+instance Event RuntimeConsoleAPICalled where
+  eventName _ = "Runtime.consoleAPICalled"
+
+-- | Type of the 'Runtime.exceptionRevoked' event.
+data RuntimeExceptionRevoked = RuntimeExceptionRevoked
+  {
+    -- | Reason describing why exception was revoked.
+    runtimeExceptionRevokedReason :: T.Text,
+    -- | The id of revoked exception, as reported in `exceptionThrown`.
+    runtimeExceptionRevokedExceptionId :: Int
+  }
+  deriving (Eq, Show)
+instance FromJSON RuntimeExceptionRevoked where
+  parseJSON = A.withObject "RuntimeExceptionRevoked" $ \o -> RuntimeExceptionRevoked
+    <$> o A..: "reason"
+    <*> o A..: "exceptionId"
+instance Event RuntimeExceptionRevoked where
+  eventName _ = "Runtime.exceptionRevoked"
+
+-- | Type of the 'Runtime.exceptionThrown' event.
+data RuntimeExceptionThrown = RuntimeExceptionThrown
+  {
+    -- | Timestamp of the exception.
+    runtimeExceptionThrownTimestamp :: RuntimeTimestamp,
+    runtimeExceptionThrownExceptionDetails :: RuntimeExceptionDetails
+  }
+  deriving (Eq, Show)
+instance FromJSON RuntimeExceptionThrown where
+  parseJSON = A.withObject "RuntimeExceptionThrown" $ \o -> RuntimeExceptionThrown
+    <$> o A..: "timestamp"
+    <*> o A..: "exceptionDetails"
+instance Event RuntimeExceptionThrown where
+  eventName _ = "Runtime.exceptionThrown"
+
+-- | Type of the 'Runtime.executionContextCreated' event.
+data RuntimeExecutionContextCreated = RuntimeExecutionContextCreated
+  {
+    -- | A newly created execution context.
+    runtimeExecutionContextCreatedContext :: RuntimeExecutionContextDescription
+  }
+  deriving (Eq, Show)
+instance FromJSON RuntimeExecutionContextCreated where
+  parseJSON = A.withObject "RuntimeExecutionContextCreated" $ \o -> RuntimeExecutionContextCreated
+    <$> o A..: "context"
+instance Event RuntimeExecutionContextCreated where
+  eventName _ = "Runtime.executionContextCreated"
+
+-- | Type of the 'Runtime.executionContextDestroyed' event.
+data RuntimeExecutionContextDestroyed = RuntimeExecutionContextDestroyed
+  {
+    -- | Id of the destroyed context
+    runtimeExecutionContextDestroyedExecutionContextId :: RuntimeExecutionContextId
+  }
+  deriving (Eq, Show)
+instance FromJSON RuntimeExecutionContextDestroyed where
+  parseJSON = A.withObject "RuntimeExecutionContextDestroyed" $ \o -> RuntimeExecutionContextDestroyed
+    <$> o A..: "executionContextId"
+instance Event RuntimeExecutionContextDestroyed where
+  eventName _ = "Runtime.executionContextDestroyed"
+
+-- | Type of the 'Runtime.executionContextsCleared' event.
+data RuntimeExecutionContextsCleared = RuntimeExecutionContextsCleared
+  deriving (Eq, Show, Read)
+instance FromJSON RuntimeExecutionContextsCleared where
+  parseJSON _ = pure RuntimeExecutionContextsCleared
+instance Event RuntimeExecutionContextsCleared where
+  eventName _ = "Runtime.executionContextsCleared"
+
+-- | Type of the 'Runtime.inspectRequested' event.
+data RuntimeInspectRequested = RuntimeInspectRequested
+  {
+    runtimeInspectRequestedObject :: RuntimeRemoteObject,
+    runtimeInspectRequestedHints :: [(T.Text, T.Text)],
+    -- | Identifier of the context where the call was made.
+    runtimeInspectRequestedExecutionContextId :: Maybe RuntimeExecutionContextId
+  }
+  deriving (Eq, Show)
+instance FromJSON RuntimeInspectRequested where
+  parseJSON = A.withObject "RuntimeInspectRequested" $ \o -> RuntimeInspectRequested
+    <$> o A..: "object"
+    <*> o A..: "hints"
+    <*> o A..:? "executionContextId"
+instance Event RuntimeInspectRequested where
+  eventName _ = "Runtime.inspectRequested"
+
+-- | Add handler to promise with given promise object id.
+
+-- | Parameters of the 'Runtime.awaitPromise' command.
+data PRuntimeAwaitPromise = PRuntimeAwaitPromise
+  {
+    -- | Identifier of the promise.
+    pRuntimeAwaitPromisePromiseObjectId :: RuntimeRemoteObjectId,
+    -- | Whether the result is expected to be a JSON object that should be sent by value.
+    pRuntimeAwaitPromiseReturnByValue :: Maybe Bool,
+    -- | Whether preview should be generated for the result.
+    pRuntimeAwaitPromiseGeneratePreview :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pRuntimeAwaitPromise
+  {-
+  -- | Identifier of the promise.
+  -}
+  :: RuntimeRemoteObjectId
+  -> PRuntimeAwaitPromise
+pRuntimeAwaitPromise
+  arg_pRuntimeAwaitPromisePromiseObjectId
+  = PRuntimeAwaitPromise
+    arg_pRuntimeAwaitPromisePromiseObjectId
+    Nothing
+    Nothing
+instance ToJSON PRuntimeAwaitPromise where
+  toJSON p = A.object $ catMaybes [
+    ("promiseObjectId" A..=) <$> Just (pRuntimeAwaitPromisePromiseObjectId p),
+    ("returnByValue" A..=) <$> (pRuntimeAwaitPromiseReturnByValue p),
+    ("generatePreview" A..=) <$> (pRuntimeAwaitPromiseGeneratePreview p)
+    ]
+data RuntimeAwaitPromise = RuntimeAwaitPromise
+  {
+    -- | Promise result. Will contain rejected value if promise was rejected.
+    runtimeAwaitPromiseResult :: RuntimeRemoteObject,
+    -- | Exception details if stack strace is available.
+    runtimeAwaitPromiseExceptionDetails :: Maybe RuntimeExceptionDetails
+  }
+  deriving (Eq, Show)
+instance FromJSON RuntimeAwaitPromise where
+  parseJSON = A.withObject "RuntimeAwaitPromise" $ \o -> RuntimeAwaitPromise
+    <$> o A..: "result"
+    <*> o A..:? "exceptionDetails"
+instance Command PRuntimeAwaitPromise where
+  type CommandResponse PRuntimeAwaitPromise = RuntimeAwaitPromise
+  commandName _ = "Runtime.awaitPromise"
+
+-- | Calls function with given declaration on the given object. Object group of the result is
+--   inherited from the target object.
+
+-- | Parameters of the 'Runtime.callFunctionOn' command.
+data PRuntimeCallFunctionOn = PRuntimeCallFunctionOn
+  {
+    -- | Declaration of the function to call.
+    pRuntimeCallFunctionOnFunctionDeclaration :: T.Text,
+    -- | Identifier of the object to call function on. Either objectId or executionContextId should
+    --   be specified.
+    pRuntimeCallFunctionOnObjectId :: Maybe RuntimeRemoteObjectId,
+    -- | Call arguments. All call arguments must belong to the same JavaScript world as the target
+    --   object.
+    pRuntimeCallFunctionOnArguments :: Maybe [RuntimeCallArgument],
+    -- | In silent mode exceptions thrown during evaluation are not reported and do not pause
+    --   execution. Overrides `setPauseOnException` state.
+    pRuntimeCallFunctionOnSilent :: Maybe Bool,
+    -- | Whether the result is expected to be a JSON object which should be sent by value.
+    pRuntimeCallFunctionOnReturnByValue :: Maybe Bool,
+    -- | Whether preview should be generated for the result.
+    pRuntimeCallFunctionOnGeneratePreview :: Maybe Bool,
+    -- | Whether execution should be treated as initiated by user in the UI.
+    pRuntimeCallFunctionOnUserGesture :: Maybe Bool,
+    -- | Whether execution should `await` for resulting value and return once awaited promise is
+    --   resolved.
+    pRuntimeCallFunctionOnAwaitPromise :: Maybe Bool,
+    -- | Specifies execution context which global object will be used to call function on. Either
+    --   executionContextId or objectId should be specified.
+    pRuntimeCallFunctionOnExecutionContextId :: Maybe RuntimeExecutionContextId,
+    -- | Symbolic group name that can be used to release multiple objects. If objectGroup is not
+    --   specified and objectId is, objectGroup will be inherited from object.
+    pRuntimeCallFunctionOnObjectGroup :: Maybe T.Text,
+    -- | Whether to throw an exception if side effect cannot be ruled out during evaluation.
+    pRuntimeCallFunctionOnThrowOnSideEffect :: Maybe Bool,
+    -- | Whether the result should contain `webDriverValue`, serialized according to
+    --   https://w3c.github.io/webdriver-bidi. This is mutually exclusive with `returnByValue`, but
+    --   resulting `objectId` is still provided.
+    pRuntimeCallFunctionOnGenerateWebDriverValue :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pRuntimeCallFunctionOn
+  {-
+  -- | Declaration of the function to call.
+  -}
+  :: T.Text
+  -> PRuntimeCallFunctionOn
+pRuntimeCallFunctionOn
+  arg_pRuntimeCallFunctionOnFunctionDeclaration
+  = PRuntimeCallFunctionOn
+    arg_pRuntimeCallFunctionOnFunctionDeclaration
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PRuntimeCallFunctionOn where
+  toJSON p = A.object $ catMaybes [
+    ("functionDeclaration" A..=) <$> Just (pRuntimeCallFunctionOnFunctionDeclaration p),
+    ("objectId" A..=) <$> (pRuntimeCallFunctionOnObjectId p),
+    ("arguments" A..=) <$> (pRuntimeCallFunctionOnArguments p),
+    ("silent" A..=) <$> (pRuntimeCallFunctionOnSilent p),
+    ("returnByValue" A..=) <$> (pRuntimeCallFunctionOnReturnByValue p),
+    ("generatePreview" A..=) <$> (pRuntimeCallFunctionOnGeneratePreview p),
+    ("userGesture" A..=) <$> (pRuntimeCallFunctionOnUserGesture p),
+    ("awaitPromise" A..=) <$> (pRuntimeCallFunctionOnAwaitPromise p),
+    ("executionContextId" A..=) <$> (pRuntimeCallFunctionOnExecutionContextId p),
+    ("objectGroup" A..=) <$> (pRuntimeCallFunctionOnObjectGroup p),
+    ("throwOnSideEffect" A..=) <$> (pRuntimeCallFunctionOnThrowOnSideEffect p),
+    ("generateWebDriverValue" A..=) <$> (pRuntimeCallFunctionOnGenerateWebDriverValue p)
+    ]
+data RuntimeCallFunctionOn = RuntimeCallFunctionOn
+  {
+    -- | Call result.
+    runtimeCallFunctionOnResult :: RuntimeRemoteObject,
+    -- | Exception details.
+    runtimeCallFunctionOnExceptionDetails :: Maybe RuntimeExceptionDetails
+  }
+  deriving (Eq, Show)
+instance FromJSON RuntimeCallFunctionOn where
+  parseJSON = A.withObject "RuntimeCallFunctionOn" $ \o -> RuntimeCallFunctionOn
+    <$> o A..: "result"
+    <*> o A..:? "exceptionDetails"
+instance Command PRuntimeCallFunctionOn where
+  type CommandResponse PRuntimeCallFunctionOn = RuntimeCallFunctionOn
+  commandName _ = "Runtime.callFunctionOn"
+
+-- | Compiles expression.
+
+-- | Parameters of the 'Runtime.compileScript' command.
+data PRuntimeCompileScript = PRuntimeCompileScript
+  {
+    -- | Expression to compile.
+    pRuntimeCompileScriptExpression :: T.Text,
+    -- | Source url to be set for the script.
+    pRuntimeCompileScriptSourceURL :: T.Text,
+    -- | Specifies whether the compiled script should be persisted.
+    pRuntimeCompileScriptPersistScript :: Bool,
+    -- | Specifies in which execution context to perform script run. If the parameter is omitted the
+    --   evaluation will be performed in the context of the inspected page.
+    pRuntimeCompileScriptExecutionContextId :: Maybe RuntimeExecutionContextId
+  }
+  deriving (Eq, Show)
+pRuntimeCompileScript
+  {-
+  -- | Expression to compile.
+  -}
+  :: T.Text
+  {-
+  -- | Source url to be set for the script.
+  -}
+  -> T.Text
+  {-
+  -- | Specifies whether the compiled script should be persisted.
+  -}
+  -> Bool
+  -> PRuntimeCompileScript
+pRuntimeCompileScript
+  arg_pRuntimeCompileScriptExpression
+  arg_pRuntimeCompileScriptSourceURL
+  arg_pRuntimeCompileScriptPersistScript
+  = PRuntimeCompileScript
+    arg_pRuntimeCompileScriptExpression
+    arg_pRuntimeCompileScriptSourceURL
+    arg_pRuntimeCompileScriptPersistScript
+    Nothing
+instance ToJSON PRuntimeCompileScript where
+  toJSON p = A.object $ catMaybes [
+    ("expression" A..=) <$> Just (pRuntimeCompileScriptExpression p),
+    ("sourceURL" A..=) <$> Just (pRuntimeCompileScriptSourceURL p),
+    ("persistScript" A..=) <$> Just (pRuntimeCompileScriptPersistScript p),
+    ("executionContextId" A..=) <$> (pRuntimeCompileScriptExecutionContextId p)
+    ]
+data RuntimeCompileScript = RuntimeCompileScript
+  {
+    -- | Id of the script.
+    runtimeCompileScriptScriptId :: Maybe RuntimeScriptId,
+    -- | Exception details.
+    runtimeCompileScriptExceptionDetails :: Maybe RuntimeExceptionDetails
+  }
+  deriving (Eq, Show)
+instance FromJSON RuntimeCompileScript where
+  parseJSON = A.withObject "RuntimeCompileScript" $ \o -> RuntimeCompileScript
+    <$> o A..:? "scriptId"
+    <*> o A..:? "exceptionDetails"
+instance Command PRuntimeCompileScript where
+  type CommandResponse PRuntimeCompileScript = RuntimeCompileScript
+  commandName _ = "Runtime.compileScript"
+
+-- | Disables reporting of execution contexts creation.
+
+-- | Parameters of the 'Runtime.disable' command.
+data PRuntimeDisable = PRuntimeDisable
+  deriving (Eq, Show)
+pRuntimeDisable
+  :: PRuntimeDisable
+pRuntimeDisable
+  = PRuntimeDisable
+instance ToJSON PRuntimeDisable where
+  toJSON _ = A.Null
+instance Command PRuntimeDisable where
+  type CommandResponse PRuntimeDisable = ()
+  commandName _ = "Runtime.disable"
+  fromJSON = const . A.Success . const ()
+
+-- | Discards collected exceptions and console API calls.
+
+-- | Parameters of the 'Runtime.discardConsoleEntries' command.
+data PRuntimeDiscardConsoleEntries = PRuntimeDiscardConsoleEntries
+  deriving (Eq, Show)
+pRuntimeDiscardConsoleEntries
+  :: PRuntimeDiscardConsoleEntries
+pRuntimeDiscardConsoleEntries
+  = PRuntimeDiscardConsoleEntries
+instance ToJSON PRuntimeDiscardConsoleEntries where
+  toJSON _ = A.Null
+instance Command PRuntimeDiscardConsoleEntries where
+  type CommandResponse PRuntimeDiscardConsoleEntries = ()
+  commandName _ = "Runtime.discardConsoleEntries"
+  fromJSON = const . A.Success . const ()
+
+-- | Enables reporting of execution contexts creation by means of `executionContextCreated` event.
+--   When the reporting gets enabled the event will be sent immediately for each existing execution
+--   context.
+
+-- | Parameters of the 'Runtime.enable' command.
+data PRuntimeEnable = PRuntimeEnable
+  deriving (Eq, Show)
+pRuntimeEnable
+  :: PRuntimeEnable
+pRuntimeEnable
+  = PRuntimeEnable
+instance ToJSON PRuntimeEnable where
+  toJSON _ = A.Null
+instance Command PRuntimeEnable where
+  type CommandResponse PRuntimeEnable = ()
+  commandName _ = "Runtime.enable"
+  fromJSON = const . A.Success . const ()
+
+-- | Evaluates expression on global object.
+
+-- | Parameters of the 'Runtime.evaluate' command.
+data PRuntimeEvaluate = PRuntimeEvaluate
+  {
+    -- | Expression to evaluate.
+    pRuntimeEvaluateExpression :: T.Text,
+    -- | Symbolic group name that can be used to release multiple objects.
+    pRuntimeEvaluateObjectGroup :: Maybe T.Text,
+    -- | Determines whether Command Line API should be available during the evaluation.
+    pRuntimeEvaluateIncludeCommandLineAPI :: Maybe Bool,
+    -- | In silent mode exceptions thrown during evaluation are not reported and do not pause
+    --   execution. Overrides `setPauseOnException` state.
+    pRuntimeEvaluateSilent :: Maybe Bool,
+    -- | Specifies in which execution context to perform evaluation. If the parameter is omitted the
+    --   evaluation will be performed in the context of the inspected page.
+    --   This is mutually exclusive with `uniqueContextId`, which offers an
+    --   alternative way to identify the execution context that is more reliable
+    --   in a multi-process environment.
+    pRuntimeEvaluateContextId :: Maybe RuntimeExecutionContextId,
+    -- | Whether the result is expected to be a JSON object that should be sent by value.
+    pRuntimeEvaluateReturnByValue :: Maybe Bool,
+    -- | Whether preview should be generated for the result.
+    pRuntimeEvaluateGeneratePreview :: Maybe Bool,
+    -- | Whether execution should be treated as initiated by user in the UI.
+    pRuntimeEvaluateUserGesture :: Maybe Bool,
+    -- | Whether execution should `await` for resulting value and return once awaited promise is
+    --   resolved.
+    pRuntimeEvaluateAwaitPromise :: Maybe Bool,
+    -- | Whether to throw an exception if side effect cannot be ruled out during evaluation.
+    --   This implies `disableBreaks` below.
+    pRuntimeEvaluateThrowOnSideEffect :: Maybe Bool,
+    -- | Terminate execution after timing out (number of milliseconds).
+    pRuntimeEvaluateTimeout :: Maybe RuntimeTimeDelta,
+    -- | Disable breakpoints during execution.
+    pRuntimeEvaluateDisableBreaks :: Maybe Bool,
+    -- | Setting this flag to true enables `let` re-declaration and top-level `await`.
+    --   Note that `let` variables can only be re-declared if they originate from
+    --   `replMode` themselves.
+    pRuntimeEvaluateReplMode :: Maybe Bool,
+    -- | The Content Security Policy (CSP) for the target might block 'unsafe-eval'
+    --   which includes eval(), Function(), setTimeout() and setInterval()
+    --   when called with non-callable arguments. This flag bypasses CSP for this
+    --   evaluation and allows unsafe-eval. Defaults to true.
+    pRuntimeEvaluateAllowUnsafeEvalBlockedByCSP :: Maybe Bool,
+    -- | An alternative way to specify the execution context to evaluate in.
+    --   Compared to contextId that may be reused across processes, this is guaranteed to be
+    --   system-unique, so it can be used to prevent accidental evaluation of the expression
+    --   in context different than intended (e.g. as a result of navigation across process
+    --   boundaries).
+    --   This is mutually exclusive with `contextId`.
+    pRuntimeEvaluateUniqueContextId :: Maybe T.Text,
+    -- | Whether the result should be serialized according to https://w3c.github.io/webdriver-bidi.
+    pRuntimeEvaluateGenerateWebDriverValue :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pRuntimeEvaluate
+  {-
+  -- | Expression to evaluate.
+  -}
+  :: T.Text
+  -> PRuntimeEvaluate
+pRuntimeEvaluate
+  arg_pRuntimeEvaluateExpression
+  = PRuntimeEvaluate
+    arg_pRuntimeEvaluateExpression
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PRuntimeEvaluate where
+  toJSON p = A.object $ catMaybes [
+    ("expression" A..=) <$> Just (pRuntimeEvaluateExpression p),
+    ("objectGroup" A..=) <$> (pRuntimeEvaluateObjectGroup p),
+    ("includeCommandLineAPI" A..=) <$> (pRuntimeEvaluateIncludeCommandLineAPI p),
+    ("silent" A..=) <$> (pRuntimeEvaluateSilent p),
+    ("contextId" A..=) <$> (pRuntimeEvaluateContextId p),
+    ("returnByValue" A..=) <$> (pRuntimeEvaluateReturnByValue p),
+    ("generatePreview" A..=) <$> (pRuntimeEvaluateGeneratePreview p),
+    ("userGesture" A..=) <$> (pRuntimeEvaluateUserGesture p),
+    ("awaitPromise" A..=) <$> (pRuntimeEvaluateAwaitPromise p),
+    ("throwOnSideEffect" A..=) <$> (pRuntimeEvaluateThrowOnSideEffect p),
+    ("timeout" A..=) <$> (pRuntimeEvaluateTimeout p),
+    ("disableBreaks" A..=) <$> (pRuntimeEvaluateDisableBreaks p),
+    ("replMode" A..=) <$> (pRuntimeEvaluateReplMode p),
+    ("allowUnsafeEvalBlockedByCSP" A..=) <$> (pRuntimeEvaluateAllowUnsafeEvalBlockedByCSP p),
+    ("uniqueContextId" A..=) <$> (pRuntimeEvaluateUniqueContextId p),
+    ("generateWebDriverValue" A..=) <$> (pRuntimeEvaluateGenerateWebDriverValue p)
+    ]
+data RuntimeEvaluate = RuntimeEvaluate
+  {
+    -- | Evaluation result.
+    runtimeEvaluateResult :: RuntimeRemoteObject,
+    -- | Exception details.
+    runtimeEvaluateExceptionDetails :: Maybe RuntimeExceptionDetails
+  }
+  deriving (Eq, Show)
+instance FromJSON RuntimeEvaluate where
+  parseJSON = A.withObject "RuntimeEvaluate" $ \o -> RuntimeEvaluate
+    <$> o A..: "result"
+    <*> o A..:? "exceptionDetails"
+instance Command PRuntimeEvaluate where
+  type CommandResponse PRuntimeEvaluate = RuntimeEvaluate
+  commandName _ = "Runtime.evaluate"
+
+-- | Returns the isolate id.
+
+-- | Parameters of the 'Runtime.getIsolateId' command.
+data PRuntimeGetIsolateId = PRuntimeGetIsolateId
+  deriving (Eq, Show)
+pRuntimeGetIsolateId
+  :: PRuntimeGetIsolateId
+pRuntimeGetIsolateId
+  = PRuntimeGetIsolateId
+instance ToJSON PRuntimeGetIsolateId where
+  toJSON _ = A.Null
+data RuntimeGetIsolateId = RuntimeGetIsolateId
+  {
+    -- | The isolate id.
+    runtimeGetIsolateIdId :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON RuntimeGetIsolateId where
+  parseJSON = A.withObject "RuntimeGetIsolateId" $ \o -> RuntimeGetIsolateId
+    <$> o A..: "id"
+instance Command PRuntimeGetIsolateId where
+  type CommandResponse PRuntimeGetIsolateId = RuntimeGetIsolateId
+  commandName _ = "Runtime.getIsolateId"
+
+-- | Returns the JavaScript heap usage.
+--   It is the total usage of the corresponding isolate not scoped to a particular Runtime.
+
+-- | Parameters of the 'Runtime.getHeapUsage' command.
+data PRuntimeGetHeapUsage = PRuntimeGetHeapUsage
+  deriving (Eq, Show)
+pRuntimeGetHeapUsage
+  :: PRuntimeGetHeapUsage
+pRuntimeGetHeapUsage
+  = PRuntimeGetHeapUsage
+instance ToJSON PRuntimeGetHeapUsage where
+  toJSON _ = A.Null
+data RuntimeGetHeapUsage = RuntimeGetHeapUsage
+  {
+    -- | Used heap size in bytes.
+    runtimeGetHeapUsageUsedSize :: Double,
+    -- | Allocated heap size in bytes.
+    runtimeGetHeapUsageTotalSize :: Double
+  }
+  deriving (Eq, Show)
+instance FromJSON RuntimeGetHeapUsage where
+  parseJSON = A.withObject "RuntimeGetHeapUsage" $ \o -> RuntimeGetHeapUsage
+    <$> o A..: "usedSize"
+    <*> o A..: "totalSize"
+instance Command PRuntimeGetHeapUsage where
+  type CommandResponse PRuntimeGetHeapUsage = RuntimeGetHeapUsage
+  commandName _ = "Runtime.getHeapUsage"
+
+-- | Returns properties of a given object. Object group of the result is inherited from the target
+--   object.
+
+-- | Parameters of the 'Runtime.getProperties' command.
+data PRuntimeGetProperties = PRuntimeGetProperties
+  {
+    -- | Identifier of the object to return properties for.
+    pRuntimeGetPropertiesObjectId :: RuntimeRemoteObjectId,
+    -- | If true, returns properties belonging only to the element itself, not to its prototype
+    --   chain.
+    pRuntimeGetPropertiesOwnProperties :: Maybe Bool,
+    -- | If true, returns accessor properties (with getter/setter) only; internal properties are not
+    --   returned either.
+    pRuntimeGetPropertiesAccessorPropertiesOnly :: Maybe Bool,
+    -- | Whether preview should be generated for the results.
+    pRuntimeGetPropertiesGeneratePreview :: Maybe Bool,
+    -- | If true, returns non-indexed properties only.
+    pRuntimeGetPropertiesNonIndexedPropertiesOnly :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pRuntimeGetProperties
+  {-
+  -- | Identifier of the object to return properties for.
+  -}
+  :: RuntimeRemoteObjectId
+  -> PRuntimeGetProperties
+pRuntimeGetProperties
+  arg_pRuntimeGetPropertiesObjectId
+  = PRuntimeGetProperties
+    arg_pRuntimeGetPropertiesObjectId
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PRuntimeGetProperties where
+  toJSON p = A.object $ catMaybes [
+    ("objectId" A..=) <$> Just (pRuntimeGetPropertiesObjectId p),
+    ("ownProperties" A..=) <$> (pRuntimeGetPropertiesOwnProperties p),
+    ("accessorPropertiesOnly" A..=) <$> (pRuntimeGetPropertiesAccessorPropertiesOnly p),
+    ("generatePreview" A..=) <$> (pRuntimeGetPropertiesGeneratePreview p),
+    ("nonIndexedPropertiesOnly" A..=) <$> (pRuntimeGetPropertiesNonIndexedPropertiesOnly p)
+    ]
+data RuntimeGetProperties = RuntimeGetProperties
+  {
+    -- | Object properties.
+    runtimeGetPropertiesResult :: [RuntimePropertyDescriptor],
+    -- | Internal object properties (only of the element itself).
+    runtimeGetPropertiesInternalProperties :: Maybe [RuntimeInternalPropertyDescriptor],
+    -- | Object private properties.
+    runtimeGetPropertiesPrivateProperties :: Maybe [RuntimePrivatePropertyDescriptor],
+    -- | Exception details.
+    runtimeGetPropertiesExceptionDetails :: Maybe RuntimeExceptionDetails
+  }
+  deriving (Eq, Show)
+instance FromJSON RuntimeGetProperties where
+  parseJSON = A.withObject "RuntimeGetProperties" $ \o -> RuntimeGetProperties
+    <$> o A..: "result"
+    <*> o A..:? "internalProperties"
+    <*> o A..:? "privateProperties"
+    <*> o A..:? "exceptionDetails"
+instance Command PRuntimeGetProperties where
+  type CommandResponse PRuntimeGetProperties = RuntimeGetProperties
+  commandName _ = "Runtime.getProperties"
+
+-- | Returns all let, const and class variables from global scope.
+
+-- | Parameters of the 'Runtime.globalLexicalScopeNames' command.
+data PRuntimeGlobalLexicalScopeNames = PRuntimeGlobalLexicalScopeNames
+  {
+    -- | Specifies in which execution context to lookup global scope variables.
+    pRuntimeGlobalLexicalScopeNamesExecutionContextId :: Maybe RuntimeExecutionContextId
+  }
+  deriving (Eq, Show)
+pRuntimeGlobalLexicalScopeNames
+  :: PRuntimeGlobalLexicalScopeNames
+pRuntimeGlobalLexicalScopeNames
+  = PRuntimeGlobalLexicalScopeNames
+    Nothing
+instance ToJSON PRuntimeGlobalLexicalScopeNames where
+  toJSON p = A.object $ catMaybes [
+    ("executionContextId" A..=) <$> (pRuntimeGlobalLexicalScopeNamesExecutionContextId p)
+    ]
+data RuntimeGlobalLexicalScopeNames = RuntimeGlobalLexicalScopeNames
+  {
+    runtimeGlobalLexicalScopeNamesNames :: [T.Text]
+  }
+  deriving (Eq, Show)
+instance FromJSON RuntimeGlobalLexicalScopeNames where
+  parseJSON = A.withObject "RuntimeGlobalLexicalScopeNames" $ \o -> RuntimeGlobalLexicalScopeNames
+    <$> o A..: "names"
+instance Command PRuntimeGlobalLexicalScopeNames where
+  type CommandResponse PRuntimeGlobalLexicalScopeNames = RuntimeGlobalLexicalScopeNames
+  commandName _ = "Runtime.globalLexicalScopeNames"
+
+
+-- | Parameters of the 'Runtime.queryObjects' command.
+data PRuntimeQueryObjects = PRuntimeQueryObjects
+  {
+    -- | Identifier of the prototype to return objects for.
+    pRuntimeQueryObjectsPrototypeObjectId :: RuntimeRemoteObjectId,
+    -- | Symbolic group name that can be used to release the results.
+    pRuntimeQueryObjectsObjectGroup :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+pRuntimeQueryObjects
+  {-
+  -- | Identifier of the prototype to return objects for.
+  -}
+  :: RuntimeRemoteObjectId
+  -> PRuntimeQueryObjects
+pRuntimeQueryObjects
+  arg_pRuntimeQueryObjectsPrototypeObjectId
+  = PRuntimeQueryObjects
+    arg_pRuntimeQueryObjectsPrototypeObjectId
+    Nothing
+instance ToJSON PRuntimeQueryObjects where
+  toJSON p = A.object $ catMaybes [
+    ("prototypeObjectId" A..=) <$> Just (pRuntimeQueryObjectsPrototypeObjectId p),
+    ("objectGroup" A..=) <$> (pRuntimeQueryObjectsObjectGroup p)
+    ]
+data RuntimeQueryObjects = RuntimeQueryObjects
+  {
+    -- | Array with objects.
+    runtimeQueryObjectsObjects :: RuntimeRemoteObject
+  }
+  deriving (Eq, Show)
+instance FromJSON RuntimeQueryObjects where
+  parseJSON = A.withObject "RuntimeQueryObjects" $ \o -> RuntimeQueryObjects
+    <$> o A..: "objects"
+instance Command PRuntimeQueryObjects where
+  type CommandResponse PRuntimeQueryObjects = RuntimeQueryObjects
+  commandName _ = "Runtime.queryObjects"
+
+-- | Releases remote object with given id.
+
+-- | Parameters of the 'Runtime.releaseObject' command.
+data PRuntimeReleaseObject = PRuntimeReleaseObject
+  {
+    -- | Identifier of the object to release.
+    pRuntimeReleaseObjectObjectId :: RuntimeRemoteObjectId
+  }
+  deriving (Eq, Show)
+pRuntimeReleaseObject
+  {-
+  -- | Identifier of the object to release.
+  -}
+  :: RuntimeRemoteObjectId
+  -> PRuntimeReleaseObject
+pRuntimeReleaseObject
+  arg_pRuntimeReleaseObjectObjectId
+  = PRuntimeReleaseObject
+    arg_pRuntimeReleaseObjectObjectId
+instance ToJSON PRuntimeReleaseObject where
+  toJSON p = A.object $ catMaybes [
+    ("objectId" A..=) <$> Just (pRuntimeReleaseObjectObjectId p)
+    ]
+instance Command PRuntimeReleaseObject where
+  type CommandResponse PRuntimeReleaseObject = ()
+  commandName _ = "Runtime.releaseObject"
+  fromJSON = const . A.Success . const ()
+
+-- | Releases all remote objects that belong to a given group.
+
+-- | Parameters of the 'Runtime.releaseObjectGroup' command.
+data PRuntimeReleaseObjectGroup = PRuntimeReleaseObjectGroup
+  {
+    -- | Symbolic object group name.
+    pRuntimeReleaseObjectGroupObjectGroup :: T.Text
+  }
+  deriving (Eq, Show)
+pRuntimeReleaseObjectGroup
+  {-
+  -- | Symbolic object group name.
+  -}
+  :: T.Text
+  -> PRuntimeReleaseObjectGroup
+pRuntimeReleaseObjectGroup
+  arg_pRuntimeReleaseObjectGroupObjectGroup
+  = PRuntimeReleaseObjectGroup
+    arg_pRuntimeReleaseObjectGroupObjectGroup
+instance ToJSON PRuntimeReleaseObjectGroup where
+  toJSON p = A.object $ catMaybes [
+    ("objectGroup" A..=) <$> Just (pRuntimeReleaseObjectGroupObjectGroup p)
+    ]
+instance Command PRuntimeReleaseObjectGroup where
+  type CommandResponse PRuntimeReleaseObjectGroup = ()
+  commandName _ = "Runtime.releaseObjectGroup"
+  fromJSON = const . A.Success . const ()
+
+-- | Tells inspected instance to run if it was waiting for debugger to attach.
+
+-- | Parameters of the 'Runtime.runIfWaitingForDebugger' command.
+data PRuntimeRunIfWaitingForDebugger = PRuntimeRunIfWaitingForDebugger
+  deriving (Eq, Show)
+pRuntimeRunIfWaitingForDebugger
+  :: PRuntimeRunIfWaitingForDebugger
+pRuntimeRunIfWaitingForDebugger
+  = PRuntimeRunIfWaitingForDebugger
+instance ToJSON PRuntimeRunIfWaitingForDebugger where
+  toJSON _ = A.Null
+instance Command PRuntimeRunIfWaitingForDebugger where
+  type CommandResponse PRuntimeRunIfWaitingForDebugger = ()
+  commandName _ = "Runtime.runIfWaitingForDebugger"
+  fromJSON = const . A.Success . const ()
+
+-- | Runs script with given id in a given context.
+
+-- | Parameters of the 'Runtime.runScript' command.
+data PRuntimeRunScript = PRuntimeRunScript
+  {
+    -- | Id of the script to run.
+    pRuntimeRunScriptScriptId :: RuntimeScriptId,
+    -- | Specifies in which execution context to perform script run. If the parameter is omitted the
+    --   evaluation will be performed in the context of the inspected page.
+    pRuntimeRunScriptExecutionContextId :: Maybe RuntimeExecutionContextId,
+    -- | Symbolic group name that can be used to release multiple objects.
+    pRuntimeRunScriptObjectGroup :: Maybe T.Text,
+    -- | In silent mode exceptions thrown during evaluation are not reported and do not pause
+    --   execution. Overrides `setPauseOnException` state.
+    pRuntimeRunScriptSilent :: Maybe Bool,
+    -- | Determines whether Command Line API should be available during the evaluation.
+    pRuntimeRunScriptIncludeCommandLineAPI :: Maybe Bool,
+    -- | Whether the result is expected to be a JSON object which should be sent by value.
+    pRuntimeRunScriptReturnByValue :: Maybe Bool,
+    -- | Whether preview should be generated for the result.
+    pRuntimeRunScriptGeneratePreview :: Maybe Bool,
+    -- | Whether execution should `await` for resulting value and return once awaited promise is
+    --   resolved.
+    pRuntimeRunScriptAwaitPromise :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pRuntimeRunScript
+  {-
+  -- | Id of the script to run.
+  -}
+  :: RuntimeScriptId
+  -> PRuntimeRunScript
+pRuntimeRunScript
+  arg_pRuntimeRunScriptScriptId
+  = PRuntimeRunScript
+    arg_pRuntimeRunScriptScriptId
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PRuntimeRunScript where
+  toJSON p = A.object $ catMaybes [
+    ("scriptId" A..=) <$> Just (pRuntimeRunScriptScriptId p),
+    ("executionContextId" A..=) <$> (pRuntimeRunScriptExecutionContextId p),
+    ("objectGroup" A..=) <$> (pRuntimeRunScriptObjectGroup p),
+    ("silent" A..=) <$> (pRuntimeRunScriptSilent p),
+    ("includeCommandLineAPI" A..=) <$> (pRuntimeRunScriptIncludeCommandLineAPI p),
+    ("returnByValue" A..=) <$> (pRuntimeRunScriptReturnByValue p),
+    ("generatePreview" A..=) <$> (pRuntimeRunScriptGeneratePreview p),
+    ("awaitPromise" A..=) <$> (pRuntimeRunScriptAwaitPromise p)
+    ]
+data RuntimeRunScript = RuntimeRunScript
+  {
+    -- | Run result.
+    runtimeRunScriptResult :: RuntimeRemoteObject,
+    -- | Exception details.
+    runtimeRunScriptExceptionDetails :: Maybe RuntimeExceptionDetails
+  }
+  deriving (Eq, Show)
+instance FromJSON RuntimeRunScript where
+  parseJSON = A.withObject "RuntimeRunScript" $ \o -> RuntimeRunScript
+    <$> o A..: "result"
+    <*> o A..:? "exceptionDetails"
+instance Command PRuntimeRunScript where
+  type CommandResponse PRuntimeRunScript = RuntimeRunScript
+  commandName _ = "Runtime.runScript"
+
+-- | Enables or disables async call stacks tracking.
+
+-- | Parameters of the 'Runtime.setAsyncCallStackDepth' command.
+data PRuntimeSetAsyncCallStackDepth = PRuntimeSetAsyncCallStackDepth
+  {
+    -- | Maximum depth of async call stacks. Setting to `0` will effectively disable collecting async
+    --   call stacks (default).
+    pRuntimeSetAsyncCallStackDepthMaxDepth :: Int
+  }
+  deriving (Eq, Show)
+pRuntimeSetAsyncCallStackDepth
+  {-
+  -- | Maximum depth of async call stacks. Setting to `0` will effectively disable collecting async
+  --   call stacks (default).
+  -}
+  :: Int
+  -> PRuntimeSetAsyncCallStackDepth
+pRuntimeSetAsyncCallStackDepth
+  arg_pRuntimeSetAsyncCallStackDepthMaxDepth
+  = PRuntimeSetAsyncCallStackDepth
+    arg_pRuntimeSetAsyncCallStackDepthMaxDepth
+instance ToJSON PRuntimeSetAsyncCallStackDepth where
+  toJSON p = A.object $ catMaybes [
+    ("maxDepth" A..=) <$> Just (pRuntimeSetAsyncCallStackDepthMaxDepth p)
+    ]
+instance Command PRuntimeSetAsyncCallStackDepth where
+  type CommandResponse PRuntimeSetAsyncCallStackDepth = ()
+  commandName _ = "Runtime.setAsyncCallStackDepth"
+  fromJSON = const . A.Success . const ()
+
+
+-- | Parameters of the 'Runtime.setCustomObjectFormatterEnabled' command.
+data PRuntimeSetCustomObjectFormatterEnabled = PRuntimeSetCustomObjectFormatterEnabled
+  {
+    pRuntimeSetCustomObjectFormatterEnabledEnabled :: Bool
+  }
+  deriving (Eq, Show)
+pRuntimeSetCustomObjectFormatterEnabled
+  :: Bool
+  -> PRuntimeSetCustomObjectFormatterEnabled
+pRuntimeSetCustomObjectFormatterEnabled
+  arg_pRuntimeSetCustomObjectFormatterEnabledEnabled
+  = PRuntimeSetCustomObjectFormatterEnabled
+    arg_pRuntimeSetCustomObjectFormatterEnabledEnabled
+instance ToJSON PRuntimeSetCustomObjectFormatterEnabled where
+  toJSON p = A.object $ catMaybes [
+    ("enabled" A..=) <$> Just (pRuntimeSetCustomObjectFormatterEnabledEnabled p)
+    ]
+instance Command PRuntimeSetCustomObjectFormatterEnabled where
+  type CommandResponse PRuntimeSetCustomObjectFormatterEnabled = ()
+  commandName _ = "Runtime.setCustomObjectFormatterEnabled"
+  fromJSON = const . A.Success . const ()
+
+
+-- | Parameters of the 'Runtime.setMaxCallStackSizeToCapture' command.
+data PRuntimeSetMaxCallStackSizeToCapture = PRuntimeSetMaxCallStackSizeToCapture
+  {
+    pRuntimeSetMaxCallStackSizeToCaptureSize :: Int
+  }
+  deriving (Eq, Show)
+pRuntimeSetMaxCallStackSizeToCapture
+  :: Int
+  -> PRuntimeSetMaxCallStackSizeToCapture
+pRuntimeSetMaxCallStackSizeToCapture
+  arg_pRuntimeSetMaxCallStackSizeToCaptureSize
+  = PRuntimeSetMaxCallStackSizeToCapture
+    arg_pRuntimeSetMaxCallStackSizeToCaptureSize
+instance ToJSON PRuntimeSetMaxCallStackSizeToCapture where
+  toJSON p = A.object $ catMaybes [
+    ("size" A..=) <$> Just (pRuntimeSetMaxCallStackSizeToCaptureSize p)
+    ]
+instance Command PRuntimeSetMaxCallStackSizeToCapture where
+  type CommandResponse PRuntimeSetMaxCallStackSizeToCapture = ()
+  commandName _ = "Runtime.setMaxCallStackSizeToCapture"
+  fromJSON = const . A.Success . const ()
+
+-- | Terminate current or next JavaScript execution.
+--   Will cancel the termination when the outer-most script execution ends.
+
+-- | Parameters of the 'Runtime.terminateExecution' command.
+data PRuntimeTerminateExecution = PRuntimeTerminateExecution
+  deriving (Eq, Show)
+pRuntimeTerminateExecution
+  :: PRuntimeTerminateExecution
+pRuntimeTerminateExecution
+  = PRuntimeTerminateExecution
+instance ToJSON PRuntimeTerminateExecution where
+  toJSON _ = A.Null
+instance Command PRuntimeTerminateExecution where
+  type CommandResponse PRuntimeTerminateExecution = ()
+  commandName _ = "Runtime.terminateExecution"
+  fromJSON = const . A.Success . const ()
+
+-- | If executionContextId is empty, adds binding with the given name on the
+--   global objects of all inspected contexts, including those created later,
+--   bindings survive reloads.
+--   Binding function takes exactly one argument, this argument should be string,
+--   in case of any other input, function throws an exception.
+--   Each binding function call produces Runtime.bindingCalled notification.
+
+-- | Parameters of the 'Runtime.addBinding' command.
+data PRuntimeAddBinding = PRuntimeAddBinding
+  {
+    pRuntimeAddBindingName :: T.Text,
+    -- | If specified, the binding is exposed to the executionContext with
+    --   matching name, even for contexts created after the binding is added.
+    --   See also `ExecutionContext.name` and `worldName` parameter to
+    --   `Page.addScriptToEvaluateOnNewDocument`.
+    --   This parameter is mutually exclusive with `executionContextId`.
+    pRuntimeAddBindingExecutionContextName :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+pRuntimeAddBinding
+  :: T.Text
+  -> PRuntimeAddBinding
+pRuntimeAddBinding
+  arg_pRuntimeAddBindingName
+  = PRuntimeAddBinding
+    arg_pRuntimeAddBindingName
+    Nothing
+instance ToJSON PRuntimeAddBinding where
+  toJSON p = A.object $ catMaybes [
+    ("name" A..=) <$> Just (pRuntimeAddBindingName p),
+    ("executionContextName" A..=) <$> (pRuntimeAddBindingExecutionContextName p)
+    ]
+instance Command PRuntimeAddBinding where
+  type CommandResponse PRuntimeAddBinding = ()
+  commandName _ = "Runtime.addBinding"
+  fromJSON = const . A.Success . const ()
+
+-- | This method does not remove binding function from global object but
+--   unsubscribes current runtime agent from Runtime.bindingCalled notifications.
+
+-- | Parameters of the 'Runtime.removeBinding' command.
+data PRuntimeRemoveBinding = PRuntimeRemoveBinding
+  {
+    pRuntimeRemoveBindingName :: T.Text
+  }
+  deriving (Eq, Show)
+pRuntimeRemoveBinding
+  :: T.Text
+  -> PRuntimeRemoveBinding
+pRuntimeRemoveBinding
+  arg_pRuntimeRemoveBindingName
+  = PRuntimeRemoveBinding
+    arg_pRuntimeRemoveBindingName
+instance ToJSON PRuntimeRemoveBinding where
+  toJSON p = A.object $ catMaybes [
+    ("name" A..=) <$> Just (pRuntimeRemoveBindingName p)
+    ]
+instance Command PRuntimeRemoveBinding where
+  type CommandResponse PRuntimeRemoveBinding = ()
+  commandName _ = "Runtime.removeBinding"
+  fromJSON = const . A.Success . const ()
+
+-- | This method tries to lookup and populate exception details for a
+--   JavaScript Error object.
+--   Note that the stackTrace portion of the resulting exceptionDetails will
+--   only be populated if the Runtime domain was enabled at the time when the
+--   Error was thrown.
+
+-- | Parameters of the 'Runtime.getExceptionDetails' command.
+data PRuntimeGetExceptionDetails = PRuntimeGetExceptionDetails
+  {
+    -- | The error object for which to resolve the exception details.
+    pRuntimeGetExceptionDetailsErrorObjectId :: RuntimeRemoteObjectId
+  }
+  deriving (Eq, Show)
+pRuntimeGetExceptionDetails
+  {-
+  -- | The error object for which to resolve the exception details.
+  -}
+  :: RuntimeRemoteObjectId
+  -> PRuntimeGetExceptionDetails
+pRuntimeGetExceptionDetails
+  arg_pRuntimeGetExceptionDetailsErrorObjectId
+  = PRuntimeGetExceptionDetails
+    arg_pRuntimeGetExceptionDetailsErrorObjectId
+instance ToJSON PRuntimeGetExceptionDetails where
+  toJSON p = A.object $ catMaybes [
+    ("errorObjectId" A..=) <$> Just (pRuntimeGetExceptionDetailsErrorObjectId p)
+    ]
+data RuntimeGetExceptionDetails = RuntimeGetExceptionDetails
+  {
+    runtimeGetExceptionDetailsExceptionDetails :: Maybe RuntimeExceptionDetails
+  }
+  deriving (Eq, Show)
+instance FromJSON RuntimeGetExceptionDetails where
+  parseJSON = A.withObject "RuntimeGetExceptionDetails" $ \o -> RuntimeGetExceptionDetails
+    <$> o A..:? "exceptionDetails"
+instance Command PRuntimeGetExceptionDetails where
+  type CommandResponse PRuntimeGetExceptionDetails = RuntimeGetExceptionDetails
+  commandName _ = "Runtime.getExceptionDetails"
+
diff --git a/src/CDP/Domains/ServiceWorker.hs b/src/CDP/Domains/ServiceWorker.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains/ServiceWorker.hs
@@ -0,0 +1,530 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+
+
+{- |
+= ServiceWorker
+
+-}
+
+
+module CDP.Domains.ServiceWorker (module CDP.Domains.ServiceWorker) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+
+import CDP.Domains.BrowserTarget as BrowserTarget
+
+
+-- | Type 'ServiceWorker.RegistrationID'.
+type ServiceWorkerRegistrationID = T.Text
+
+-- | Type 'ServiceWorker.ServiceWorkerRegistration'.
+--   ServiceWorker registration.
+data ServiceWorkerServiceWorkerRegistration = ServiceWorkerServiceWorkerRegistration
+  {
+    serviceWorkerServiceWorkerRegistrationRegistrationId :: ServiceWorkerRegistrationID,
+    serviceWorkerServiceWorkerRegistrationScopeURL :: T.Text,
+    serviceWorkerServiceWorkerRegistrationIsDeleted :: Bool
+  }
+  deriving (Eq, Show)
+instance FromJSON ServiceWorkerServiceWorkerRegistration where
+  parseJSON = A.withObject "ServiceWorkerServiceWorkerRegistration" $ \o -> ServiceWorkerServiceWorkerRegistration
+    <$> o A..: "registrationId"
+    <*> o A..: "scopeURL"
+    <*> o A..: "isDeleted"
+instance ToJSON ServiceWorkerServiceWorkerRegistration where
+  toJSON p = A.object $ catMaybes [
+    ("registrationId" A..=) <$> Just (serviceWorkerServiceWorkerRegistrationRegistrationId p),
+    ("scopeURL" A..=) <$> Just (serviceWorkerServiceWorkerRegistrationScopeURL p),
+    ("isDeleted" A..=) <$> Just (serviceWorkerServiceWorkerRegistrationIsDeleted p)
+    ]
+
+-- | Type 'ServiceWorker.ServiceWorkerVersionRunningStatus'.
+data ServiceWorkerServiceWorkerVersionRunningStatus = ServiceWorkerServiceWorkerVersionRunningStatusStopped | ServiceWorkerServiceWorkerVersionRunningStatusStarting | ServiceWorkerServiceWorkerVersionRunningStatusRunning | ServiceWorkerServiceWorkerVersionRunningStatusStopping
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON ServiceWorkerServiceWorkerVersionRunningStatus where
+  parseJSON = A.withText "ServiceWorkerServiceWorkerVersionRunningStatus" $ \v -> case v of
+    "stopped" -> pure ServiceWorkerServiceWorkerVersionRunningStatusStopped
+    "starting" -> pure ServiceWorkerServiceWorkerVersionRunningStatusStarting
+    "running" -> pure ServiceWorkerServiceWorkerVersionRunningStatusRunning
+    "stopping" -> pure ServiceWorkerServiceWorkerVersionRunningStatusStopping
+    "_" -> fail "failed to parse ServiceWorkerServiceWorkerVersionRunningStatus"
+instance ToJSON ServiceWorkerServiceWorkerVersionRunningStatus where
+  toJSON v = A.String $ case v of
+    ServiceWorkerServiceWorkerVersionRunningStatusStopped -> "stopped"
+    ServiceWorkerServiceWorkerVersionRunningStatusStarting -> "starting"
+    ServiceWorkerServiceWorkerVersionRunningStatusRunning -> "running"
+    ServiceWorkerServiceWorkerVersionRunningStatusStopping -> "stopping"
+
+-- | Type 'ServiceWorker.ServiceWorkerVersionStatus'.
+data ServiceWorkerServiceWorkerVersionStatus = ServiceWorkerServiceWorkerVersionStatusNew | ServiceWorkerServiceWorkerVersionStatusInstalling | ServiceWorkerServiceWorkerVersionStatusInstalled | ServiceWorkerServiceWorkerVersionStatusActivating | ServiceWorkerServiceWorkerVersionStatusActivated | ServiceWorkerServiceWorkerVersionStatusRedundant
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON ServiceWorkerServiceWorkerVersionStatus where
+  parseJSON = A.withText "ServiceWorkerServiceWorkerVersionStatus" $ \v -> case v of
+    "new" -> pure ServiceWorkerServiceWorkerVersionStatusNew
+    "installing" -> pure ServiceWorkerServiceWorkerVersionStatusInstalling
+    "installed" -> pure ServiceWorkerServiceWorkerVersionStatusInstalled
+    "activating" -> pure ServiceWorkerServiceWorkerVersionStatusActivating
+    "activated" -> pure ServiceWorkerServiceWorkerVersionStatusActivated
+    "redundant" -> pure ServiceWorkerServiceWorkerVersionStatusRedundant
+    "_" -> fail "failed to parse ServiceWorkerServiceWorkerVersionStatus"
+instance ToJSON ServiceWorkerServiceWorkerVersionStatus where
+  toJSON v = A.String $ case v of
+    ServiceWorkerServiceWorkerVersionStatusNew -> "new"
+    ServiceWorkerServiceWorkerVersionStatusInstalling -> "installing"
+    ServiceWorkerServiceWorkerVersionStatusInstalled -> "installed"
+    ServiceWorkerServiceWorkerVersionStatusActivating -> "activating"
+    ServiceWorkerServiceWorkerVersionStatusActivated -> "activated"
+    ServiceWorkerServiceWorkerVersionStatusRedundant -> "redundant"
+
+-- | Type 'ServiceWorker.ServiceWorkerVersion'.
+--   ServiceWorker version.
+data ServiceWorkerServiceWorkerVersion = ServiceWorkerServiceWorkerVersion
+  {
+    serviceWorkerServiceWorkerVersionVersionId :: T.Text,
+    serviceWorkerServiceWorkerVersionRegistrationId :: ServiceWorkerRegistrationID,
+    serviceWorkerServiceWorkerVersionScriptURL :: T.Text,
+    serviceWorkerServiceWorkerVersionRunningStatus :: ServiceWorkerServiceWorkerVersionRunningStatus,
+    serviceWorkerServiceWorkerVersionStatus :: ServiceWorkerServiceWorkerVersionStatus,
+    -- | The Last-Modified header value of the main script.
+    serviceWorkerServiceWorkerVersionScriptLastModified :: Maybe Double,
+    -- | The time at which the response headers of the main script were received from the server.
+    --   For cached script it is the last time the cache entry was validated.
+    serviceWorkerServiceWorkerVersionScriptResponseTime :: Maybe Double,
+    serviceWorkerServiceWorkerVersionControlledClients :: Maybe [BrowserTarget.TargetTargetID],
+    serviceWorkerServiceWorkerVersionTargetId :: Maybe BrowserTarget.TargetTargetID
+  }
+  deriving (Eq, Show)
+instance FromJSON ServiceWorkerServiceWorkerVersion where
+  parseJSON = A.withObject "ServiceWorkerServiceWorkerVersion" $ \o -> ServiceWorkerServiceWorkerVersion
+    <$> o A..: "versionId"
+    <*> o A..: "registrationId"
+    <*> o A..: "scriptURL"
+    <*> o A..: "runningStatus"
+    <*> o A..: "status"
+    <*> o A..:? "scriptLastModified"
+    <*> o A..:? "scriptResponseTime"
+    <*> o A..:? "controlledClients"
+    <*> o A..:? "targetId"
+instance ToJSON ServiceWorkerServiceWorkerVersion where
+  toJSON p = A.object $ catMaybes [
+    ("versionId" A..=) <$> Just (serviceWorkerServiceWorkerVersionVersionId p),
+    ("registrationId" A..=) <$> Just (serviceWorkerServiceWorkerVersionRegistrationId p),
+    ("scriptURL" A..=) <$> Just (serviceWorkerServiceWorkerVersionScriptURL p),
+    ("runningStatus" A..=) <$> Just (serviceWorkerServiceWorkerVersionRunningStatus p),
+    ("status" A..=) <$> Just (serviceWorkerServiceWorkerVersionStatus p),
+    ("scriptLastModified" A..=) <$> (serviceWorkerServiceWorkerVersionScriptLastModified p),
+    ("scriptResponseTime" A..=) <$> (serviceWorkerServiceWorkerVersionScriptResponseTime p),
+    ("controlledClients" A..=) <$> (serviceWorkerServiceWorkerVersionControlledClients p),
+    ("targetId" A..=) <$> (serviceWorkerServiceWorkerVersionTargetId p)
+    ]
+
+-- | Type 'ServiceWorker.ServiceWorkerErrorMessage'.
+--   ServiceWorker error message.
+data ServiceWorkerServiceWorkerErrorMessage = ServiceWorkerServiceWorkerErrorMessage
+  {
+    serviceWorkerServiceWorkerErrorMessageErrorMessage :: T.Text,
+    serviceWorkerServiceWorkerErrorMessageRegistrationId :: ServiceWorkerRegistrationID,
+    serviceWorkerServiceWorkerErrorMessageVersionId :: T.Text,
+    serviceWorkerServiceWorkerErrorMessageSourceURL :: T.Text,
+    serviceWorkerServiceWorkerErrorMessageLineNumber :: Int,
+    serviceWorkerServiceWorkerErrorMessageColumnNumber :: Int
+  }
+  deriving (Eq, Show)
+instance FromJSON ServiceWorkerServiceWorkerErrorMessage where
+  parseJSON = A.withObject "ServiceWorkerServiceWorkerErrorMessage" $ \o -> ServiceWorkerServiceWorkerErrorMessage
+    <$> o A..: "errorMessage"
+    <*> o A..: "registrationId"
+    <*> o A..: "versionId"
+    <*> o A..: "sourceURL"
+    <*> o A..: "lineNumber"
+    <*> o A..: "columnNumber"
+instance ToJSON ServiceWorkerServiceWorkerErrorMessage where
+  toJSON p = A.object $ catMaybes [
+    ("errorMessage" A..=) <$> Just (serviceWorkerServiceWorkerErrorMessageErrorMessage p),
+    ("registrationId" A..=) <$> Just (serviceWorkerServiceWorkerErrorMessageRegistrationId p),
+    ("versionId" A..=) <$> Just (serviceWorkerServiceWorkerErrorMessageVersionId p),
+    ("sourceURL" A..=) <$> Just (serviceWorkerServiceWorkerErrorMessageSourceURL p),
+    ("lineNumber" A..=) <$> Just (serviceWorkerServiceWorkerErrorMessageLineNumber p),
+    ("columnNumber" A..=) <$> Just (serviceWorkerServiceWorkerErrorMessageColumnNumber p)
+    ]
+
+-- | Type of the 'ServiceWorker.workerErrorReported' event.
+data ServiceWorkerWorkerErrorReported = ServiceWorkerWorkerErrorReported
+  {
+    serviceWorkerWorkerErrorReportedErrorMessage :: ServiceWorkerServiceWorkerErrorMessage
+  }
+  deriving (Eq, Show)
+instance FromJSON ServiceWorkerWorkerErrorReported where
+  parseJSON = A.withObject "ServiceWorkerWorkerErrorReported" $ \o -> ServiceWorkerWorkerErrorReported
+    <$> o A..: "errorMessage"
+instance Event ServiceWorkerWorkerErrorReported where
+  eventName _ = "ServiceWorker.workerErrorReported"
+
+-- | Type of the 'ServiceWorker.workerRegistrationUpdated' event.
+data ServiceWorkerWorkerRegistrationUpdated = ServiceWorkerWorkerRegistrationUpdated
+  {
+    serviceWorkerWorkerRegistrationUpdatedRegistrations :: [ServiceWorkerServiceWorkerRegistration]
+  }
+  deriving (Eq, Show)
+instance FromJSON ServiceWorkerWorkerRegistrationUpdated where
+  parseJSON = A.withObject "ServiceWorkerWorkerRegistrationUpdated" $ \o -> ServiceWorkerWorkerRegistrationUpdated
+    <$> o A..: "registrations"
+instance Event ServiceWorkerWorkerRegistrationUpdated where
+  eventName _ = "ServiceWorker.workerRegistrationUpdated"
+
+-- | Type of the 'ServiceWorker.workerVersionUpdated' event.
+data ServiceWorkerWorkerVersionUpdated = ServiceWorkerWorkerVersionUpdated
+  {
+    serviceWorkerWorkerVersionUpdatedVersions :: [ServiceWorkerServiceWorkerVersion]
+  }
+  deriving (Eq, Show)
+instance FromJSON ServiceWorkerWorkerVersionUpdated where
+  parseJSON = A.withObject "ServiceWorkerWorkerVersionUpdated" $ \o -> ServiceWorkerWorkerVersionUpdated
+    <$> o A..: "versions"
+instance Event ServiceWorkerWorkerVersionUpdated where
+  eventName _ = "ServiceWorker.workerVersionUpdated"
+
+
+-- | Parameters of the 'ServiceWorker.deliverPushMessage' command.
+data PServiceWorkerDeliverPushMessage = PServiceWorkerDeliverPushMessage
+  {
+    pServiceWorkerDeliverPushMessageOrigin :: T.Text,
+    pServiceWorkerDeliverPushMessageRegistrationId :: ServiceWorkerRegistrationID,
+    pServiceWorkerDeliverPushMessageData :: T.Text
+  }
+  deriving (Eq, Show)
+pServiceWorkerDeliverPushMessage
+  :: T.Text
+  -> ServiceWorkerRegistrationID
+  -> T.Text
+  -> PServiceWorkerDeliverPushMessage
+pServiceWorkerDeliverPushMessage
+  arg_pServiceWorkerDeliverPushMessageOrigin
+  arg_pServiceWorkerDeliverPushMessageRegistrationId
+  arg_pServiceWorkerDeliverPushMessageData
+  = PServiceWorkerDeliverPushMessage
+    arg_pServiceWorkerDeliverPushMessageOrigin
+    arg_pServiceWorkerDeliverPushMessageRegistrationId
+    arg_pServiceWorkerDeliverPushMessageData
+instance ToJSON PServiceWorkerDeliverPushMessage where
+  toJSON p = A.object $ catMaybes [
+    ("origin" A..=) <$> Just (pServiceWorkerDeliverPushMessageOrigin p),
+    ("registrationId" A..=) <$> Just (pServiceWorkerDeliverPushMessageRegistrationId p),
+    ("data" A..=) <$> Just (pServiceWorkerDeliverPushMessageData p)
+    ]
+instance Command PServiceWorkerDeliverPushMessage where
+  type CommandResponse PServiceWorkerDeliverPushMessage = ()
+  commandName _ = "ServiceWorker.deliverPushMessage"
+  fromJSON = const . A.Success . const ()
+
+
+-- | Parameters of the 'ServiceWorker.disable' command.
+data PServiceWorkerDisable = PServiceWorkerDisable
+  deriving (Eq, Show)
+pServiceWorkerDisable
+  :: PServiceWorkerDisable
+pServiceWorkerDisable
+  = PServiceWorkerDisable
+instance ToJSON PServiceWorkerDisable where
+  toJSON _ = A.Null
+instance Command PServiceWorkerDisable where
+  type CommandResponse PServiceWorkerDisable = ()
+  commandName _ = "ServiceWorker.disable"
+  fromJSON = const . A.Success . const ()
+
+
+-- | Parameters of the 'ServiceWorker.dispatchSyncEvent' command.
+data PServiceWorkerDispatchSyncEvent = PServiceWorkerDispatchSyncEvent
+  {
+    pServiceWorkerDispatchSyncEventOrigin :: T.Text,
+    pServiceWorkerDispatchSyncEventRegistrationId :: ServiceWorkerRegistrationID,
+    pServiceWorkerDispatchSyncEventTag :: T.Text,
+    pServiceWorkerDispatchSyncEventLastChance :: Bool
+  }
+  deriving (Eq, Show)
+pServiceWorkerDispatchSyncEvent
+  :: T.Text
+  -> ServiceWorkerRegistrationID
+  -> T.Text
+  -> Bool
+  -> PServiceWorkerDispatchSyncEvent
+pServiceWorkerDispatchSyncEvent
+  arg_pServiceWorkerDispatchSyncEventOrigin
+  arg_pServiceWorkerDispatchSyncEventRegistrationId
+  arg_pServiceWorkerDispatchSyncEventTag
+  arg_pServiceWorkerDispatchSyncEventLastChance
+  = PServiceWorkerDispatchSyncEvent
+    arg_pServiceWorkerDispatchSyncEventOrigin
+    arg_pServiceWorkerDispatchSyncEventRegistrationId
+    arg_pServiceWorkerDispatchSyncEventTag
+    arg_pServiceWorkerDispatchSyncEventLastChance
+instance ToJSON PServiceWorkerDispatchSyncEvent where
+  toJSON p = A.object $ catMaybes [
+    ("origin" A..=) <$> Just (pServiceWorkerDispatchSyncEventOrigin p),
+    ("registrationId" A..=) <$> Just (pServiceWorkerDispatchSyncEventRegistrationId p),
+    ("tag" A..=) <$> Just (pServiceWorkerDispatchSyncEventTag p),
+    ("lastChance" A..=) <$> Just (pServiceWorkerDispatchSyncEventLastChance p)
+    ]
+instance Command PServiceWorkerDispatchSyncEvent where
+  type CommandResponse PServiceWorkerDispatchSyncEvent = ()
+  commandName _ = "ServiceWorker.dispatchSyncEvent"
+  fromJSON = const . A.Success . const ()
+
+
+-- | Parameters of the 'ServiceWorker.dispatchPeriodicSyncEvent' command.
+data PServiceWorkerDispatchPeriodicSyncEvent = PServiceWorkerDispatchPeriodicSyncEvent
+  {
+    pServiceWorkerDispatchPeriodicSyncEventOrigin :: T.Text,
+    pServiceWorkerDispatchPeriodicSyncEventRegistrationId :: ServiceWorkerRegistrationID,
+    pServiceWorkerDispatchPeriodicSyncEventTag :: T.Text
+  }
+  deriving (Eq, Show)
+pServiceWorkerDispatchPeriodicSyncEvent
+  :: T.Text
+  -> ServiceWorkerRegistrationID
+  -> T.Text
+  -> PServiceWorkerDispatchPeriodicSyncEvent
+pServiceWorkerDispatchPeriodicSyncEvent
+  arg_pServiceWorkerDispatchPeriodicSyncEventOrigin
+  arg_pServiceWorkerDispatchPeriodicSyncEventRegistrationId
+  arg_pServiceWorkerDispatchPeriodicSyncEventTag
+  = PServiceWorkerDispatchPeriodicSyncEvent
+    arg_pServiceWorkerDispatchPeriodicSyncEventOrigin
+    arg_pServiceWorkerDispatchPeriodicSyncEventRegistrationId
+    arg_pServiceWorkerDispatchPeriodicSyncEventTag
+instance ToJSON PServiceWorkerDispatchPeriodicSyncEvent where
+  toJSON p = A.object $ catMaybes [
+    ("origin" A..=) <$> Just (pServiceWorkerDispatchPeriodicSyncEventOrigin p),
+    ("registrationId" A..=) <$> Just (pServiceWorkerDispatchPeriodicSyncEventRegistrationId p),
+    ("tag" A..=) <$> Just (pServiceWorkerDispatchPeriodicSyncEventTag p)
+    ]
+instance Command PServiceWorkerDispatchPeriodicSyncEvent where
+  type CommandResponse PServiceWorkerDispatchPeriodicSyncEvent = ()
+  commandName _ = "ServiceWorker.dispatchPeriodicSyncEvent"
+  fromJSON = const . A.Success . const ()
+
+
+-- | Parameters of the 'ServiceWorker.enable' command.
+data PServiceWorkerEnable = PServiceWorkerEnable
+  deriving (Eq, Show)
+pServiceWorkerEnable
+  :: PServiceWorkerEnable
+pServiceWorkerEnable
+  = PServiceWorkerEnable
+instance ToJSON PServiceWorkerEnable where
+  toJSON _ = A.Null
+instance Command PServiceWorkerEnable where
+  type CommandResponse PServiceWorkerEnable = ()
+  commandName _ = "ServiceWorker.enable"
+  fromJSON = const . A.Success . const ()
+
+
+-- | Parameters of the 'ServiceWorker.inspectWorker' command.
+data PServiceWorkerInspectWorker = PServiceWorkerInspectWorker
+  {
+    pServiceWorkerInspectWorkerVersionId :: T.Text
+  }
+  deriving (Eq, Show)
+pServiceWorkerInspectWorker
+  :: T.Text
+  -> PServiceWorkerInspectWorker
+pServiceWorkerInspectWorker
+  arg_pServiceWorkerInspectWorkerVersionId
+  = PServiceWorkerInspectWorker
+    arg_pServiceWorkerInspectWorkerVersionId
+instance ToJSON PServiceWorkerInspectWorker where
+  toJSON p = A.object $ catMaybes [
+    ("versionId" A..=) <$> Just (pServiceWorkerInspectWorkerVersionId p)
+    ]
+instance Command PServiceWorkerInspectWorker where
+  type CommandResponse PServiceWorkerInspectWorker = ()
+  commandName _ = "ServiceWorker.inspectWorker"
+  fromJSON = const . A.Success . const ()
+
+
+-- | Parameters of the 'ServiceWorker.setForceUpdateOnPageLoad' command.
+data PServiceWorkerSetForceUpdateOnPageLoad = PServiceWorkerSetForceUpdateOnPageLoad
+  {
+    pServiceWorkerSetForceUpdateOnPageLoadForceUpdateOnPageLoad :: Bool
+  }
+  deriving (Eq, Show)
+pServiceWorkerSetForceUpdateOnPageLoad
+  :: Bool
+  -> PServiceWorkerSetForceUpdateOnPageLoad
+pServiceWorkerSetForceUpdateOnPageLoad
+  arg_pServiceWorkerSetForceUpdateOnPageLoadForceUpdateOnPageLoad
+  = PServiceWorkerSetForceUpdateOnPageLoad
+    arg_pServiceWorkerSetForceUpdateOnPageLoadForceUpdateOnPageLoad
+instance ToJSON PServiceWorkerSetForceUpdateOnPageLoad where
+  toJSON p = A.object $ catMaybes [
+    ("forceUpdateOnPageLoad" A..=) <$> Just (pServiceWorkerSetForceUpdateOnPageLoadForceUpdateOnPageLoad p)
+    ]
+instance Command PServiceWorkerSetForceUpdateOnPageLoad where
+  type CommandResponse PServiceWorkerSetForceUpdateOnPageLoad = ()
+  commandName _ = "ServiceWorker.setForceUpdateOnPageLoad"
+  fromJSON = const . A.Success . const ()
+
+
+-- | Parameters of the 'ServiceWorker.skipWaiting' command.
+data PServiceWorkerSkipWaiting = PServiceWorkerSkipWaiting
+  {
+    pServiceWorkerSkipWaitingScopeURL :: T.Text
+  }
+  deriving (Eq, Show)
+pServiceWorkerSkipWaiting
+  :: T.Text
+  -> PServiceWorkerSkipWaiting
+pServiceWorkerSkipWaiting
+  arg_pServiceWorkerSkipWaitingScopeURL
+  = PServiceWorkerSkipWaiting
+    arg_pServiceWorkerSkipWaitingScopeURL
+instance ToJSON PServiceWorkerSkipWaiting where
+  toJSON p = A.object $ catMaybes [
+    ("scopeURL" A..=) <$> Just (pServiceWorkerSkipWaitingScopeURL p)
+    ]
+instance Command PServiceWorkerSkipWaiting where
+  type CommandResponse PServiceWorkerSkipWaiting = ()
+  commandName _ = "ServiceWorker.skipWaiting"
+  fromJSON = const . A.Success . const ()
+
+
+-- | Parameters of the 'ServiceWorker.startWorker' command.
+data PServiceWorkerStartWorker = PServiceWorkerStartWorker
+  {
+    pServiceWorkerStartWorkerScopeURL :: T.Text
+  }
+  deriving (Eq, Show)
+pServiceWorkerStartWorker
+  :: T.Text
+  -> PServiceWorkerStartWorker
+pServiceWorkerStartWorker
+  arg_pServiceWorkerStartWorkerScopeURL
+  = PServiceWorkerStartWorker
+    arg_pServiceWorkerStartWorkerScopeURL
+instance ToJSON PServiceWorkerStartWorker where
+  toJSON p = A.object $ catMaybes [
+    ("scopeURL" A..=) <$> Just (pServiceWorkerStartWorkerScopeURL p)
+    ]
+instance Command PServiceWorkerStartWorker where
+  type CommandResponse PServiceWorkerStartWorker = ()
+  commandName _ = "ServiceWorker.startWorker"
+  fromJSON = const . A.Success . const ()
+
+
+-- | Parameters of the 'ServiceWorker.stopAllWorkers' command.
+data PServiceWorkerStopAllWorkers = PServiceWorkerStopAllWorkers
+  deriving (Eq, Show)
+pServiceWorkerStopAllWorkers
+  :: PServiceWorkerStopAllWorkers
+pServiceWorkerStopAllWorkers
+  = PServiceWorkerStopAllWorkers
+instance ToJSON PServiceWorkerStopAllWorkers where
+  toJSON _ = A.Null
+instance Command PServiceWorkerStopAllWorkers where
+  type CommandResponse PServiceWorkerStopAllWorkers = ()
+  commandName _ = "ServiceWorker.stopAllWorkers"
+  fromJSON = const . A.Success . const ()
+
+
+-- | Parameters of the 'ServiceWorker.stopWorker' command.
+data PServiceWorkerStopWorker = PServiceWorkerStopWorker
+  {
+    pServiceWorkerStopWorkerVersionId :: T.Text
+  }
+  deriving (Eq, Show)
+pServiceWorkerStopWorker
+  :: T.Text
+  -> PServiceWorkerStopWorker
+pServiceWorkerStopWorker
+  arg_pServiceWorkerStopWorkerVersionId
+  = PServiceWorkerStopWorker
+    arg_pServiceWorkerStopWorkerVersionId
+instance ToJSON PServiceWorkerStopWorker where
+  toJSON p = A.object $ catMaybes [
+    ("versionId" A..=) <$> Just (pServiceWorkerStopWorkerVersionId p)
+    ]
+instance Command PServiceWorkerStopWorker where
+  type CommandResponse PServiceWorkerStopWorker = ()
+  commandName _ = "ServiceWorker.stopWorker"
+  fromJSON = const . A.Success . const ()
+
+
+-- | Parameters of the 'ServiceWorker.unregister' command.
+data PServiceWorkerUnregister = PServiceWorkerUnregister
+  {
+    pServiceWorkerUnregisterScopeURL :: T.Text
+  }
+  deriving (Eq, Show)
+pServiceWorkerUnregister
+  :: T.Text
+  -> PServiceWorkerUnregister
+pServiceWorkerUnregister
+  arg_pServiceWorkerUnregisterScopeURL
+  = PServiceWorkerUnregister
+    arg_pServiceWorkerUnregisterScopeURL
+instance ToJSON PServiceWorkerUnregister where
+  toJSON p = A.object $ catMaybes [
+    ("scopeURL" A..=) <$> Just (pServiceWorkerUnregisterScopeURL p)
+    ]
+instance Command PServiceWorkerUnregister where
+  type CommandResponse PServiceWorkerUnregister = ()
+  commandName _ = "ServiceWorker.unregister"
+  fromJSON = const . A.Success . const ()
+
+
+-- | Parameters of the 'ServiceWorker.updateRegistration' command.
+data PServiceWorkerUpdateRegistration = PServiceWorkerUpdateRegistration
+  {
+    pServiceWorkerUpdateRegistrationScopeURL :: T.Text
+  }
+  deriving (Eq, Show)
+pServiceWorkerUpdateRegistration
+  :: T.Text
+  -> PServiceWorkerUpdateRegistration
+pServiceWorkerUpdateRegistration
+  arg_pServiceWorkerUpdateRegistrationScopeURL
+  = PServiceWorkerUpdateRegistration
+    arg_pServiceWorkerUpdateRegistrationScopeURL
+instance ToJSON PServiceWorkerUpdateRegistration where
+  toJSON p = A.object $ catMaybes [
+    ("scopeURL" A..=) <$> Just (pServiceWorkerUpdateRegistrationScopeURL p)
+    ]
+instance Command PServiceWorkerUpdateRegistration where
+  type CommandResponse PServiceWorkerUpdateRegistration = ()
+  commandName _ = "ServiceWorker.updateRegistration"
+  fromJSON = const . A.Success . const ()
+
diff --git a/src/CDP/Domains/Storage.hs b/src/CDP/Domains/Storage.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains/Storage.hs
@@ -0,0 +1,857 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+
+
+{- |
+= Storage
+
+-}
+
+
+module CDP.Domains.Storage (module CDP.Domains.Storage) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+
+import CDP.Domains.BrowserTarget as BrowserTarget
+import CDP.Domains.DOMPageNetworkEmulationSecurity as DOMPageNetworkEmulationSecurity
+
+
+-- | Type 'Storage.SerializedStorageKey'.
+type StorageSerializedStorageKey = T.Text
+
+-- | Type 'Storage.StorageType'.
+--   Enum of possible storage types.
+data StorageStorageType = StorageStorageTypeAppcache | StorageStorageTypeCookies | StorageStorageTypeFile_systems | StorageStorageTypeIndexeddb | StorageStorageTypeLocal_storage | StorageStorageTypeShader_cache | StorageStorageTypeWebsql | StorageStorageTypeService_workers | StorageStorageTypeCache_storage | StorageStorageTypeInterest_groups | StorageStorageTypeAll | StorageStorageTypeOther
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON StorageStorageType where
+  parseJSON = A.withText "StorageStorageType" $ \v -> case v of
+    "appcache" -> pure StorageStorageTypeAppcache
+    "cookies" -> pure StorageStorageTypeCookies
+    "file_systems" -> pure StorageStorageTypeFile_systems
+    "indexeddb" -> pure StorageStorageTypeIndexeddb
+    "local_storage" -> pure StorageStorageTypeLocal_storage
+    "shader_cache" -> pure StorageStorageTypeShader_cache
+    "websql" -> pure StorageStorageTypeWebsql
+    "service_workers" -> pure StorageStorageTypeService_workers
+    "cache_storage" -> pure StorageStorageTypeCache_storage
+    "interest_groups" -> pure StorageStorageTypeInterest_groups
+    "all" -> pure StorageStorageTypeAll
+    "other" -> pure StorageStorageTypeOther
+    "_" -> fail "failed to parse StorageStorageType"
+instance ToJSON StorageStorageType where
+  toJSON v = A.String $ case v of
+    StorageStorageTypeAppcache -> "appcache"
+    StorageStorageTypeCookies -> "cookies"
+    StorageStorageTypeFile_systems -> "file_systems"
+    StorageStorageTypeIndexeddb -> "indexeddb"
+    StorageStorageTypeLocal_storage -> "local_storage"
+    StorageStorageTypeShader_cache -> "shader_cache"
+    StorageStorageTypeWebsql -> "websql"
+    StorageStorageTypeService_workers -> "service_workers"
+    StorageStorageTypeCache_storage -> "cache_storage"
+    StorageStorageTypeInterest_groups -> "interest_groups"
+    StorageStorageTypeAll -> "all"
+    StorageStorageTypeOther -> "other"
+
+-- | Type 'Storage.UsageForType'.
+--   Usage for a storage type.
+data StorageUsageForType = StorageUsageForType
+  {
+    -- | Name of storage type.
+    storageUsageForTypeStorageType :: StorageStorageType,
+    -- | Storage usage (bytes).
+    storageUsageForTypeUsage :: Double
+  }
+  deriving (Eq, Show)
+instance FromJSON StorageUsageForType where
+  parseJSON = A.withObject "StorageUsageForType" $ \o -> StorageUsageForType
+    <$> o A..: "storageType"
+    <*> o A..: "usage"
+instance ToJSON StorageUsageForType where
+  toJSON p = A.object $ catMaybes [
+    ("storageType" A..=) <$> Just (storageUsageForTypeStorageType p),
+    ("usage" A..=) <$> Just (storageUsageForTypeUsage p)
+    ]
+
+-- | Type 'Storage.TrustTokens'.
+--   Pair of issuer origin and number of available (signed, but not used) Trust
+--   Tokens from that issuer.
+data StorageTrustTokens = StorageTrustTokens
+  {
+    storageTrustTokensIssuerOrigin :: T.Text,
+    storageTrustTokensCount :: Double
+  }
+  deriving (Eq, Show)
+instance FromJSON StorageTrustTokens where
+  parseJSON = A.withObject "StorageTrustTokens" $ \o -> StorageTrustTokens
+    <$> o A..: "issuerOrigin"
+    <*> o A..: "count"
+instance ToJSON StorageTrustTokens where
+  toJSON p = A.object $ catMaybes [
+    ("issuerOrigin" A..=) <$> Just (storageTrustTokensIssuerOrigin p),
+    ("count" A..=) <$> Just (storageTrustTokensCount p)
+    ]
+
+-- | Type 'Storage.InterestGroupAccessType'.
+--   Enum of interest group access types.
+data StorageInterestGroupAccessType = StorageInterestGroupAccessTypeJoin | StorageInterestGroupAccessTypeLeave | StorageInterestGroupAccessTypeUpdate | StorageInterestGroupAccessTypeBid | StorageInterestGroupAccessTypeWin
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON StorageInterestGroupAccessType where
+  parseJSON = A.withText "StorageInterestGroupAccessType" $ \v -> case v of
+    "join" -> pure StorageInterestGroupAccessTypeJoin
+    "leave" -> pure StorageInterestGroupAccessTypeLeave
+    "update" -> pure StorageInterestGroupAccessTypeUpdate
+    "bid" -> pure StorageInterestGroupAccessTypeBid
+    "win" -> pure StorageInterestGroupAccessTypeWin
+    "_" -> fail "failed to parse StorageInterestGroupAccessType"
+instance ToJSON StorageInterestGroupAccessType where
+  toJSON v = A.String $ case v of
+    StorageInterestGroupAccessTypeJoin -> "join"
+    StorageInterestGroupAccessTypeLeave -> "leave"
+    StorageInterestGroupAccessTypeUpdate -> "update"
+    StorageInterestGroupAccessTypeBid -> "bid"
+    StorageInterestGroupAccessTypeWin -> "win"
+
+-- | Type 'Storage.InterestGroupAd'.
+--   Ad advertising element inside an interest group.
+data StorageInterestGroupAd = StorageInterestGroupAd
+  {
+    storageInterestGroupAdRenderUrl :: T.Text,
+    storageInterestGroupAdMetadata :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON StorageInterestGroupAd where
+  parseJSON = A.withObject "StorageInterestGroupAd" $ \o -> StorageInterestGroupAd
+    <$> o A..: "renderUrl"
+    <*> o A..:? "metadata"
+instance ToJSON StorageInterestGroupAd where
+  toJSON p = A.object $ catMaybes [
+    ("renderUrl" A..=) <$> Just (storageInterestGroupAdRenderUrl p),
+    ("metadata" A..=) <$> (storageInterestGroupAdMetadata p)
+    ]
+
+-- | Type 'Storage.InterestGroupDetails'.
+--   The full details of an interest group.
+data StorageInterestGroupDetails = StorageInterestGroupDetails
+  {
+    storageInterestGroupDetailsOwnerOrigin :: T.Text,
+    storageInterestGroupDetailsName :: T.Text,
+    storageInterestGroupDetailsExpirationTime :: DOMPageNetworkEmulationSecurity.NetworkTimeSinceEpoch,
+    storageInterestGroupDetailsJoiningOrigin :: T.Text,
+    storageInterestGroupDetailsBiddingUrl :: Maybe T.Text,
+    storageInterestGroupDetailsBiddingWasmHelperUrl :: Maybe T.Text,
+    storageInterestGroupDetailsUpdateUrl :: Maybe T.Text,
+    storageInterestGroupDetailsTrustedBiddingSignalsUrl :: Maybe T.Text,
+    storageInterestGroupDetailsTrustedBiddingSignalsKeys :: [T.Text],
+    storageInterestGroupDetailsUserBiddingSignals :: Maybe T.Text,
+    storageInterestGroupDetailsAds :: [StorageInterestGroupAd],
+    storageInterestGroupDetailsAdComponents :: [StorageInterestGroupAd]
+  }
+  deriving (Eq, Show)
+instance FromJSON StorageInterestGroupDetails where
+  parseJSON = A.withObject "StorageInterestGroupDetails" $ \o -> StorageInterestGroupDetails
+    <$> o A..: "ownerOrigin"
+    <*> o A..: "name"
+    <*> o A..: "expirationTime"
+    <*> o A..: "joiningOrigin"
+    <*> o A..:? "biddingUrl"
+    <*> o A..:? "biddingWasmHelperUrl"
+    <*> o A..:? "updateUrl"
+    <*> o A..:? "trustedBiddingSignalsUrl"
+    <*> o A..: "trustedBiddingSignalsKeys"
+    <*> o A..:? "userBiddingSignals"
+    <*> o A..: "ads"
+    <*> o A..: "adComponents"
+instance ToJSON StorageInterestGroupDetails where
+  toJSON p = A.object $ catMaybes [
+    ("ownerOrigin" A..=) <$> Just (storageInterestGroupDetailsOwnerOrigin p),
+    ("name" A..=) <$> Just (storageInterestGroupDetailsName p),
+    ("expirationTime" A..=) <$> Just (storageInterestGroupDetailsExpirationTime p),
+    ("joiningOrigin" A..=) <$> Just (storageInterestGroupDetailsJoiningOrigin p),
+    ("biddingUrl" A..=) <$> (storageInterestGroupDetailsBiddingUrl p),
+    ("biddingWasmHelperUrl" A..=) <$> (storageInterestGroupDetailsBiddingWasmHelperUrl p),
+    ("updateUrl" A..=) <$> (storageInterestGroupDetailsUpdateUrl p),
+    ("trustedBiddingSignalsUrl" A..=) <$> (storageInterestGroupDetailsTrustedBiddingSignalsUrl p),
+    ("trustedBiddingSignalsKeys" A..=) <$> Just (storageInterestGroupDetailsTrustedBiddingSignalsKeys p),
+    ("userBiddingSignals" A..=) <$> (storageInterestGroupDetailsUserBiddingSignals p),
+    ("ads" A..=) <$> Just (storageInterestGroupDetailsAds p),
+    ("adComponents" A..=) <$> Just (storageInterestGroupDetailsAdComponents p)
+    ]
+
+-- | Type of the 'Storage.cacheStorageContentUpdated' event.
+data StorageCacheStorageContentUpdated = StorageCacheStorageContentUpdated
+  {
+    -- | Origin to update.
+    storageCacheStorageContentUpdatedOrigin :: T.Text,
+    -- | Name of cache in origin.
+    storageCacheStorageContentUpdatedCacheName :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON StorageCacheStorageContentUpdated where
+  parseJSON = A.withObject "StorageCacheStorageContentUpdated" $ \o -> StorageCacheStorageContentUpdated
+    <$> o A..: "origin"
+    <*> o A..: "cacheName"
+instance Event StorageCacheStorageContentUpdated where
+  eventName _ = "Storage.cacheStorageContentUpdated"
+
+-- | Type of the 'Storage.cacheStorageListUpdated' event.
+data StorageCacheStorageListUpdated = StorageCacheStorageListUpdated
+  {
+    -- | Origin to update.
+    storageCacheStorageListUpdatedOrigin :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON StorageCacheStorageListUpdated where
+  parseJSON = A.withObject "StorageCacheStorageListUpdated" $ \o -> StorageCacheStorageListUpdated
+    <$> o A..: "origin"
+instance Event StorageCacheStorageListUpdated where
+  eventName _ = "Storage.cacheStorageListUpdated"
+
+-- | Type of the 'Storage.indexedDBContentUpdated' event.
+data StorageIndexedDBContentUpdated = StorageIndexedDBContentUpdated
+  {
+    -- | Origin to update.
+    storageIndexedDBContentUpdatedOrigin :: T.Text,
+    -- | Storage key to update.
+    storageIndexedDBContentUpdatedStorageKey :: T.Text,
+    -- | Database to update.
+    storageIndexedDBContentUpdatedDatabaseName :: T.Text,
+    -- | ObjectStore to update.
+    storageIndexedDBContentUpdatedObjectStoreName :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON StorageIndexedDBContentUpdated where
+  parseJSON = A.withObject "StorageIndexedDBContentUpdated" $ \o -> StorageIndexedDBContentUpdated
+    <$> o A..: "origin"
+    <*> o A..: "storageKey"
+    <*> o A..: "databaseName"
+    <*> o A..: "objectStoreName"
+instance Event StorageIndexedDBContentUpdated where
+  eventName _ = "Storage.indexedDBContentUpdated"
+
+-- | Type of the 'Storage.indexedDBListUpdated' event.
+data StorageIndexedDBListUpdated = StorageIndexedDBListUpdated
+  {
+    -- | Origin to update.
+    storageIndexedDBListUpdatedOrigin :: T.Text,
+    -- | Storage key to update.
+    storageIndexedDBListUpdatedStorageKey :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON StorageIndexedDBListUpdated where
+  parseJSON = A.withObject "StorageIndexedDBListUpdated" $ \o -> StorageIndexedDBListUpdated
+    <$> o A..: "origin"
+    <*> o A..: "storageKey"
+instance Event StorageIndexedDBListUpdated where
+  eventName _ = "Storage.indexedDBListUpdated"
+
+-- | Type of the 'Storage.interestGroupAccessed' event.
+data StorageInterestGroupAccessed = StorageInterestGroupAccessed
+  {
+    storageInterestGroupAccessedAccessTime :: DOMPageNetworkEmulationSecurity.NetworkTimeSinceEpoch,
+    storageInterestGroupAccessedType :: StorageInterestGroupAccessType,
+    storageInterestGroupAccessedOwnerOrigin :: T.Text,
+    storageInterestGroupAccessedName :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON StorageInterestGroupAccessed where
+  parseJSON = A.withObject "StorageInterestGroupAccessed" $ \o -> StorageInterestGroupAccessed
+    <$> o A..: "accessTime"
+    <*> o A..: "type"
+    <*> o A..: "ownerOrigin"
+    <*> o A..: "name"
+instance Event StorageInterestGroupAccessed where
+  eventName _ = "Storage.interestGroupAccessed"
+
+-- | Returns a storage key given a frame id.
+
+-- | Parameters of the 'Storage.getStorageKeyForFrame' command.
+data PStorageGetStorageKeyForFrame = PStorageGetStorageKeyForFrame
+  {
+    pStorageGetStorageKeyForFrameFrameId :: DOMPageNetworkEmulationSecurity.PageFrameId
+  }
+  deriving (Eq, Show)
+pStorageGetStorageKeyForFrame
+  :: DOMPageNetworkEmulationSecurity.PageFrameId
+  -> PStorageGetStorageKeyForFrame
+pStorageGetStorageKeyForFrame
+  arg_pStorageGetStorageKeyForFrameFrameId
+  = PStorageGetStorageKeyForFrame
+    arg_pStorageGetStorageKeyForFrameFrameId
+instance ToJSON PStorageGetStorageKeyForFrame where
+  toJSON p = A.object $ catMaybes [
+    ("frameId" A..=) <$> Just (pStorageGetStorageKeyForFrameFrameId p)
+    ]
+data StorageGetStorageKeyForFrame = StorageGetStorageKeyForFrame
+  {
+    storageGetStorageKeyForFrameStorageKey :: StorageSerializedStorageKey
+  }
+  deriving (Eq, Show)
+instance FromJSON StorageGetStorageKeyForFrame where
+  parseJSON = A.withObject "StorageGetStorageKeyForFrame" $ \o -> StorageGetStorageKeyForFrame
+    <$> o A..: "storageKey"
+instance Command PStorageGetStorageKeyForFrame where
+  type CommandResponse PStorageGetStorageKeyForFrame = StorageGetStorageKeyForFrame
+  commandName _ = "Storage.getStorageKeyForFrame"
+
+-- | Clears storage for origin.
+
+-- | Parameters of the 'Storage.clearDataForOrigin' command.
+data PStorageClearDataForOrigin = PStorageClearDataForOrigin
+  {
+    -- | Security origin.
+    pStorageClearDataForOriginOrigin :: T.Text,
+    -- | Comma separated list of StorageType to clear.
+    pStorageClearDataForOriginStorageTypes :: T.Text
+  }
+  deriving (Eq, Show)
+pStorageClearDataForOrigin
+  {-
+  -- | Security origin.
+  -}
+  :: T.Text
+  {-
+  -- | Comma separated list of StorageType to clear.
+  -}
+  -> T.Text
+  -> PStorageClearDataForOrigin
+pStorageClearDataForOrigin
+  arg_pStorageClearDataForOriginOrigin
+  arg_pStorageClearDataForOriginStorageTypes
+  = PStorageClearDataForOrigin
+    arg_pStorageClearDataForOriginOrigin
+    arg_pStorageClearDataForOriginStorageTypes
+instance ToJSON PStorageClearDataForOrigin where
+  toJSON p = A.object $ catMaybes [
+    ("origin" A..=) <$> Just (pStorageClearDataForOriginOrigin p),
+    ("storageTypes" A..=) <$> Just (pStorageClearDataForOriginStorageTypes p)
+    ]
+instance Command PStorageClearDataForOrigin where
+  type CommandResponse PStorageClearDataForOrigin = ()
+  commandName _ = "Storage.clearDataForOrigin"
+  fromJSON = const . A.Success . const ()
+
+-- | Clears storage for storage key.
+
+-- | Parameters of the 'Storage.clearDataForStorageKey' command.
+data PStorageClearDataForStorageKey = PStorageClearDataForStorageKey
+  {
+    -- | Storage key.
+    pStorageClearDataForStorageKeyStorageKey :: T.Text,
+    -- | Comma separated list of StorageType to clear.
+    pStorageClearDataForStorageKeyStorageTypes :: T.Text
+  }
+  deriving (Eq, Show)
+pStorageClearDataForStorageKey
+  {-
+  -- | Storage key.
+  -}
+  :: T.Text
+  {-
+  -- | Comma separated list of StorageType to clear.
+  -}
+  -> T.Text
+  -> PStorageClearDataForStorageKey
+pStorageClearDataForStorageKey
+  arg_pStorageClearDataForStorageKeyStorageKey
+  arg_pStorageClearDataForStorageKeyStorageTypes
+  = PStorageClearDataForStorageKey
+    arg_pStorageClearDataForStorageKeyStorageKey
+    arg_pStorageClearDataForStorageKeyStorageTypes
+instance ToJSON PStorageClearDataForStorageKey where
+  toJSON p = A.object $ catMaybes [
+    ("storageKey" A..=) <$> Just (pStorageClearDataForStorageKeyStorageKey p),
+    ("storageTypes" A..=) <$> Just (pStorageClearDataForStorageKeyStorageTypes p)
+    ]
+instance Command PStorageClearDataForStorageKey where
+  type CommandResponse PStorageClearDataForStorageKey = ()
+  commandName _ = "Storage.clearDataForStorageKey"
+  fromJSON = const . A.Success . const ()
+
+-- | Returns all browser cookies.
+
+-- | Parameters of the 'Storage.getCookies' command.
+data PStorageGetCookies = PStorageGetCookies
+  {
+    -- | Browser context to use when called on the browser endpoint.
+    pStorageGetCookiesBrowserContextId :: Maybe BrowserTarget.BrowserBrowserContextID
+  }
+  deriving (Eq, Show)
+pStorageGetCookies
+  :: PStorageGetCookies
+pStorageGetCookies
+  = PStorageGetCookies
+    Nothing
+instance ToJSON PStorageGetCookies where
+  toJSON p = A.object $ catMaybes [
+    ("browserContextId" A..=) <$> (pStorageGetCookiesBrowserContextId p)
+    ]
+data StorageGetCookies = StorageGetCookies
+  {
+    -- | Array of cookie objects.
+    storageGetCookiesCookies :: [DOMPageNetworkEmulationSecurity.NetworkCookie]
+  }
+  deriving (Eq, Show)
+instance FromJSON StorageGetCookies where
+  parseJSON = A.withObject "StorageGetCookies" $ \o -> StorageGetCookies
+    <$> o A..: "cookies"
+instance Command PStorageGetCookies where
+  type CommandResponse PStorageGetCookies = StorageGetCookies
+  commandName _ = "Storage.getCookies"
+
+-- | Sets given cookies.
+
+-- | Parameters of the 'Storage.setCookies' command.
+data PStorageSetCookies = PStorageSetCookies
+  {
+    -- | Cookies to be set.
+    pStorageSetCookiesCookies :: [DOMPageNetworkEmulationSecurity.NetworkCookieParam],
+    -- | Browser context to use when called on the browser endpoint.
+    pStorageSetCookiesBrowserContextId :: Maybe BrowserTarget.BrowserBrowserContextID
+  }
+  deriving (Eq, Show)
+pStorageSetCookies
+  {-
+  -- | Cookies to be set.
+  -}
+  :: [DOMPageNetworkEmulationSecurity.NetworkCookieParam]
+  -> PStorageSetCookies
+pStorageSetCookies
+  arg_pStorageSetCookiesCookies
+  = PStorageSetCookies
+    arg_pStorageSetCookiesCookies
+    Nothing
+instance ToJSON PStorageSetCookies where
+  toJSON p = A.object $ catMaybes [
+    ("cookies" A..=) <$> Just (pStorageSetCookiesCookies p),
+    ("browserContextId" A..=) <$> (pStorageSetCookiesBrowserContextId p)
+    ]
+instance Command PStorageSetCookies where
+  type CommandResponse PStorageSetCookies = ()
+  commandName _ = "Storage.setCookies"
+  fromJSON = const . A.Success . const ()
+
+-- | Clears cookies.
+
+-- | Parameters of the 'Storage.clearCookies' command.
+data PStorageClearCookies = PStorageClearCookies
+  {
+    -- | Browser context to use when called on the browser endpoint.
+    pStorageClearCookiesBrowserContextId :: Maybe BrowserTarget.BrowserBrowserContextID
+  }
+  deriving (Eq, Show)
+pStorageClearCookies
+  :: PStorageClearCookies
+pStorageClearCookies
+  = PStorageClearCookies
+    Nothing
+instance ToJSON PStorageClearCookies where
+  toJSON p = A.object $ catMaybes [
+    ("browserContextId" A..=) <$> (pStorageClearCookiesBrowserContextId p)
+    ]
+instance Command PStorageClearCookies where
+  type CommandResponse PStorageClearCookies = ()
+  commandName _ = "Storage.clearCookies"
+  fromJSON = const . A.Success . const ()
+
+-- | Returns usage and quota in bytes.
+
+-- | Parameters of the 'Storage.getUsageAndQuota' command.
+data PStorageGetUsageAndQuota = PStorageGetUsageAndQuota
+  {
+    -- | Security origin.
+    pStorageGetUsageAndQuotaOrigin :: T.Text
+  }
+  deriving (Eq, Show)
+pStorageGetUsageAndQuota
+  {-
+  -- | Security origin.
+  -}
+  :: T.Text
+  -> PStorageGetUsageAndQuota
+pStorageGetUsageAndQuota
+  arg_pStorageGetUsageAndQuotaOrigin
+  = PStorageGetUsageAndQuota
+    arg_pStorageGetUsageAndQuotaOrigin
+instance ToJSON PStorageGetUsageAndQuota where
+  toJSON p = A.object $ catMaybes [
+    ("origin" A..=) <$> Just (pStorageGetUsageAndQuotaOrigin p)
+    ]
+data StorageGetUsageAndQuota = StorageGetUsageAndQuota
+  {
+    -- | Storage usage (bytes).
+    storageGetUsageAndQuotaUsage :: Double,
+    -- | Storage quota (bytes).
+    storageGetUsageAndQuotaQuota :: Double,
+    -- | Whether or not the origin has an active storage quota override
+    storageGetUsageAndQuotaOverrideActive :: Bool,
+    -- | Storage usage per type (bytes).
+    storageGetUsageAndQuotaUsageBreakdown :: [StorageUsageForType]
+  }
+  deriving (Eq, Show)
+instance FromJSON StorageGetUsageAndQuota where
+  parseJSON = A.withObject "StorageGetUsageAndQuota" $ \o -> StorageGetUsageAndQuota
+    <$> o A..: "usage"
+    <*> o A..: "quota"
+    <*> o A..: "overrideActive"
+    <*> o A..: "usageBreakdown"
+instance Command PStorageGetUsageAndQuota where
+  type CommandResponse PStorageGetUsageAndQuota = StorageGetUsageAndQuota
+  commandName _ = "Storage.getUsageAndQuota"
+
+-- | Override quota for the specified origin
+
+-- | Parameters of the 'Storage.overrideQuotaForOrigin' command.
+data PStorageOverrideQuotaForOrigin = PStorageOverrideQuotaForOrigin
+  {
+    -- | Security origin.
+    pStorageOverrideQuotaForOriginOrigin :: T.Text,
+    -- | The quota size (in bytes) to override the original quota with.
+    --   If this is called multiple times, the overridden quota will be equal to
+    --   the quotaSize provided in the final call. If this is called without
+    --   specifying a quotaSize, the quota will be reset to the default value for
+    --   the specified origin. If this is called multiple times with different
+    --   origins, the override will be maintained for each origin until it is
+    --   disabled (called without a quotaSize).
+    pStorageOverrideQuotaForOriginQuotaSize :: Maybe Double
+  }
+  deriving (Eq, Show)
+pStorageOverrideQuotaForOrigin
+  {-
+  -- | Security origin.
+  -}
+  :: T.Text
+  -> PStorageOverrideQuotaForOrigin
+pStorageOverrideQuotaForOrigin
+  arg_pStorageOverrideQuotaForOriginOrigin
+  = PStorageOverrideQuotaForOrigin
+    arg_pStorageOverrideQuotaForOriginOrigin
+    Nothing
+instance ToJSON PStorageOverrideQuotaForOrigin where
+  toJSON p = A.object $ catMaybes [
+    ("origin" A..=) <$> Just (pStorageOverrideQuotaForOriginOrigin p),
+    ("quotaSize" A..=) <$> (pStorageOverrideQuotaForOriginQuotaSize p)
+    ]
+instance Command PStorageOverrideQuotaForOrigin where
+  type CommandResponse PStorageOverrideQuotaForOrigin = ()
+  commandName _ = "Storage.overrideQuotaForOrigin"
+  fromJSON = const . A.Success . const ()
+
+-- | Registers origin to be notified when an update occurs to its cache storage list.
+
+-- | Parameters of the 'Storage.trackCacheStorageForOrigin' command.
+data PStorageTrackCacheStorageForOrigin = PStorageTrackCacheStorageForOrigin
+  {
+    -- | Security origin.
+    pStorageTrackCacheStorageForOriginOrigin :: T.Text
+  }
+  deriving (Eq, Show)
+pStorageTrackCacheStorageForOrigin
+  {-
+  -- | Security origin.
+  -}
+  :: T.Text
+  -> PStorageTrackCacheStorageForOrigin
+pStorageTrackCacheStorageForOrigin
+  arg_pStorageTrackCacheStorageForOriginOrigin
+  = PStorageTrackCacheStorageForOrigin
+    arg_pStorageTrackCacheStorageForOriginOrigin
+instance ToJSON PStorageTrackCacheStorageForOrigin where
+  toJSON p = A.object $ catMaybes [
+    ("origin" A..=) <$> Just (pStorageTrackCacheStorageForOriginOrigin p)
+    ]
+instance Command PStorageTrackCacheStorageForOrigin where
+  type CommandResponse PStorageTrackCacheStorageForOrigin = ()
+  commandName _ = "Storage.trackCacheStorageForOrigin"
+  fromJSON = const . A.Success . const ()
+
+-- | Registers origin to be notified when an update occurs to its IndexedDB.
+
+-- | Parameters of the 'Storage.trackIndexedDBForOrigin' command.
+data PStorageTrackIndexedDBForOrigin = PStorageTrackIndexedDBForOrigin
+  {
+    -- | Security origin.
+    pStorageTrackIndexedDBForOriginOrigin :: T.Text
+  }
+  deriving (Eq, Show)
+pStorageTrackIndexedDBForOrigin
+  {-
+  -- | Security origin.
+  -}
+  :: T.Text
+  -> PStorageTrackIndexedDBForOrigin
+pStorageTrackIndexedDBForOrigin
+  arg_pStorageTrackIndexedDBForOriginOrigin
+  = PStorageTrackIndexedDBForOrigin
+    arg_pStorageTrackIndexedDBForOriginOrigin
+instance ToJSON PStorageTrackIndexedDBForOrigin where
+  toJSON p = A.object $ catMaybes [
+    ("origin" A..=) <$> Just (pStorageTrackIndexedDBForOriginOrigin p)
+    ]
+instance Command PStorageTrackIndexedDBForOrigin where
+  type CommandResponse PStorageTrackIndexedDBForOrigin = ()
+  commandName _ = "Storage.trackIndexedDBForOrigin"
+  fromJSON = const . A.Success . const ()
+
+-- | Registers storage key to be notified when an update occurs to its IndexedDB.
+
+-- | Parameters of the 'Storage.trackIndexedDBForStorageKey' command.
+data PStorageTrackIndexedDBForStorageKey = PStorageTrackIndexedDBForStorageKey
+  {
+    -- | Storage key.
+    pStorageTrackIndexedDBForStorageKeyStorageKey :: T.Text
+  }
+  deriving (Eq, Show)
+pStorageTrackIndexedDBForStorageKey
+  {-
+  -- | Storage key.
+  -}
+  :: T.Text
+  -> PStorageTrackIndexedDBForStorageKey
+pStorageTrackIndexedDBForStorageKey
+  arg_pStorageTrackIndexedDBForStorageKeyStorageKey
+  = PStorageTrackIndexedDBForStorageKey
+    arg_pStorageTrackIndexedDBForStorageKeyStorageKey
+instance ToJSON PStorageTrackIndexedDBForStorageKey where
+  toJSON p = A.object $ catMaybes [
+    ("storageKey" A..=) <$> Just (pStorageTrackIndexedDBForStorageKeyStorageKey p)
+    ]
+instance Command PStorageTrackIndexedDBForStorageKey where
+  type CommandResponse PStorageTrackIndexedDBForStorageKey = ()
+  commandName _ = "Storage.trackIndexedDBForStorageKey"
+  fromJSON = const . A.Success . const ()
+
+-- | Unregisters origin from receiving notifications for cache storage.
+
+-- | Parameters of the 'Storage.untrackCacheStorageForOrigin' command.
+data PStorageUntrackCacheStorageForOrigin = PStorageUntrackCacheStorageForOrigin
+  {
+    -- | Security origin.
+    pStorageUntrackCacheStorageForOriginOrigin :: T.Text
+  }
+  deriving (Eq, Show)
+pStorageUntrackCacheStorageForOrigin
+  {-
+  -- | Security origin.
+  -}
+  :: T.Text
+  -> PStorageUntrackCacheStorageForOrigin
+pStorageUntrackCacheStorageForOrigin
+  arg_pStorageUntrackCacheStorageForOriginOrigin
+  = PStorageUntrackCacheStorageForOrigin
+    arg_pStorageUntrackCacheStorageForOriginOrigin
+instance ToJSON PStorageUntrackCacheStorageForOrigin where
+  toJSON p = A.object $ catMaybes [
+    ("origin" A..=) <$> Just (pStorageUntrackCacheStorageForOriginOrigin p)
+    ]
+instance Command PStorageUntrackCacheStorageForOrigin where
+  type CommandResponse PStorageUntrackCacheStorageForOrigin = ()
+  commandName _ = "Storage.untrackCacheStorageForOrigin"
+  fromJSON = const . A.Success . const ()
+
+-- | Unregisters origin from receiving notifications for IndexedDB.
+
+-- | Parameters of the 'Storage.untrackIndexedDBForOrigin' command.
+data PStorageUntrackIndexedDBForOrigin = PStorageUntrackIndexedDBForOrigin
+  {
+    -- | Security origin.
+    pStorageUntrackIndexedDBForOriginOrigin :: T.Text
+  }
+  deriving (Eq, Show)
+pStorageUntrackIndexedDBForOrigin
+  {-
+  -- | Security origin.
+  -}
+  :: T.Text
+  -> PStorageUntrackIndexedDBForOrigin
+pStorageUntrackIndexedDBForOrigin
+  arg_pStorageUntrackIndexedDBForOriginOrigin
+  = PStorageUntrackIndexedDBForOrigin
+    arg_pStorageUntrackIndexedDBForOriginOrigin
+instance ToJSON PStorageUntrackIndexedDBForOrigin where
+  toJSON p = A.object $ catMaybes [
+    ("origin" A..=) <$> Just (pStorageUntrackIndexedDBForOriginOrigin p)
+    ]
+instance Command PStorageUntrackIndexedDBForOrigin where
+  type CommandResponse PStorageUntrackIndexedDBForOrigin = ()
+  commandName _ = "Storage.untrackIndexedDBForOrigin"
+  fromJSON = const . A.Success . const ()
+
+-- | Unregisters storage key from receiving notifications for IndexedDB.
+
+-- | Parameters of the 'Storage.untrackIndexedDBForStorageKey' command.
+data PStorageUntrackIndexedDBForStorageKey = PStorageUntrackIndexedDBForStorageKey
+  {
+    -- | Storage key.
+    pStorageUntrackIndexedDBForStorageKeyStorageKey :: T.Text
+  }
+  deriving (Eq, Show)
+pStorageUntrackIndexedDBForStorageKey
+  {-
+  -- | Storage key.
+  -}
+  :: T.Text
+  -> PStorageUntrackIndexedDBForStorageKey
+pStorageUntrackIndexedDBForStorageKey
+  arg_pStorageUntrackIndexedDBForStorageKeyStorageKey
+  = PStorageUntrackIndexedDBForStorageKey
+    arg_pStorageUntrackIndexedDBForStorageKeyStorageKey
+instance ToJSON PStorageUntrackIndexedDBForStorageKey where
+  toJSON p = A.object $ catMaybes [
+    ("storageKey" A..=) <$> Just (pStorageUntrackIndexedDBForStorageKeyStorageKey p)
+    ]
+instance Command PStorageUntrackIndexedDBForStorageKey where
+  type CommandResponse PStorageUntrackIndexedDBForStorageKey = ()
+  commandName _ = "Storage.untrackIndexedDBForStorageKey"
+  fromJSON = const . A.Success . const ()
+
+-- | Returns the number of stored Trust Tokens per issuer for the
+--   current browsing context.
+
+-- | Parameters of the 'Storage.getTrustTokens' command.
+data PStorageGetTrustTokens = PStorageGetTrustTokens
+  deriving (Eq, Show)
+pStorageGetTrustTokens
+  :: PStorageGetTrustTokens
+pStorageGetTrustTokens
+  = PStorageGetTrustTokens
+instance ToJSON PStorageGetTrustTokens where
+  toJSON _ = A.Null
+data StorageGetTrustTokens = StorageGetTrustTokens
+  {
+    storageGetTrustTokensTokens :: [StorageTrustTokens]
+  }
+  deriving (Eq, Show)
+instance FromJSON StorageGetTrustTokens where
+  parseJSON = A.withObject "StorageGetTrustTokens" $ \o -> StorageGetTrustTokens
+    <$> o A..: "tokens"
+instance Command PStorageGetTrustTokens where
+  type CommandResponse PStorageGetTrustTokens = StorageGetTrustTokens
+  commandName _ = "Storage.getTrustTokens"
+
+-- | Removes all Trust Tokens issued by the provided issuerOrigin.
+--   Leaves other stored data, including the issuer's Redemption Records, intact.
+
+-- | Parameters of the 'Storage.clearTrustTokens' command.
+data PStorageClearTrustTokens = PStorageClearTrustTokens
+  {
+    pStorageClearTrustTokensIssuerOrigin :: T.Text
+  }
+  deriving (Eq, Show)
+pStorageClearTrustTokens
+  :: T.Text
+  -> PStorageClearTrustTokens
+pStorageClearTrustTokens
+  arg_pStorageClearTrustTokensIssuerOrigin
+  = PStorageClearTrustTokens
+    arg_pStorageClearTrustTokensIssuerOrigin
+instance ToJSON PStorageClearTrustTokens where
+  toJSON p = A.object $ catMaybes [
+    ("issuerOrigin" A..=) <$> Just (pStorageClearTrustTokensIssuerOrigin p)
+    ]
+data StorageClearTrustTokens = StorageClearTrustTokens
+  {
+    -- | True if any tokens were deleted, false otherwise.
+    storageClearTrustTokensDidDeleteTokens :: Bool
+  }
+  deriving (Eq, Show)
+instance FromJSON StorageClearTrustTokens where
+  parseJSON = A.withObject "StorageClearTrustTokens" $ \o -> StorageClearTrustTokens
+    <$> o A..: "didDeleteTokens"
+instance Command PStorageClearTrustTokens where
+  type CommandResponse PStorageClearTrustTokens = StorageClearTrustTokens
+  commandName _ = "Storage.clearTrustTokens"
+
+-- | Gets details for a named interest group.
+
+-- | Parameters of the 'Storage.getInterestGroupDetails' command.
+data PStorageGetInterestGroupDetails = PStorageGetInterestGroupDetails
+  {
+    pStorageGetInterestGroupDetailsOwnerOrigin :: T.Text,
+    pStorageGetInterestGroupDetailsName :: T.Text
+  }
+  deriving (Eq, Show)
+pStorageGetInterestGroupDetails
+  :: T.Text
+  -> T.Text
+  -> PStorageGetInterestGroupDetails
+pStorageGetInterestGroupDetails
+  arg_pStorageGetInterestGroupDetailsOwnerOrigin
+  arg_pStorageGetInterestGroupDetailsName
+  = PStorageGetInterestGroupDetails
+    arg_pStorageGetInterestGroupDetailsOwnerOrigin
+    arg_pStorageGetInterestGroupDetailsName
+instance ToJSON PStorageGetInterestGroupDetails where
+  toJSON p = A.object $ catMaybes [
+    ("ownerOrigin" A..=) <$> Just (pStorageGetInterestGroupDetailsOwnerOrigin p),
+    ("name" A..=) <$> Just (pStorageGetInterestGroupDetailsName p)
+    ]
+data StorageGetInterestGroupDetails = StorageGetInterestGroupDetails
+  {
+    storageGetInterestGroupDetailsDetails :: StorageInterestGroupDetails
+  }
+  deriving (Eq, Show)
+instance FromJSON StorageGetInterestGroupDetails where
+  parseJSON = A.withObject "StorageGetInterestGroupDetails" $ \o -> StorageGetInterestGroupDetails
+    <$> o A..: "details"
+instance Command PStorageGetInterestGroupDetails where
+  type CommandResponse PStorageGetInterestGroupDetails = StorageGetInterestGroupDetails
+  commandName _ = "Storage.getInterestGroupDetails"
+
+-- | Enables/Disables issuing of interestGroupAccessed events.
+
+-- | Parameters of the 'Storage.setInterestGroupTracking' command.
+data PStorageSetInterestGroupTracking = PStorageSetInterestGroupTracking
+  {
+    pStorageSetInterestGroupTrackingEnable :: Bool
+  }
+  deriving (Eq, Show)
+pStorageSetInterestGroupTracking
+  :: Bool
+  -> PStorageSetInterestGroupTracking
+pStorageSetInterestGroupTracking
+  arg_pStorageSetInterestGroupTrackingEnable
+  = PStorageSetInterestGroupTracking
+    arg_pStorageSetInterestGroupTrackingEnable
+instance ToJSON PStorageSetInterestGroupTracking where
+  toJSON p = A.object $ catMaybes [
+    ("enable" A..=) <$> Just (pStorageSetInterestGroupTrackingEnable p)
+    ]
+instance Command PStorageSetInterestGroupTracking where
+  type CommandResponse PStorageSetInterestGroupTracking = ()
+  commandName _ = "Storage.setInterestGroupTracking"
+  fromJSON = const . A.Success . const ()
+
diff --git a/src/CDP/Domains/SystemInfo.hs b/src/CDP/Domains/SystemInfo.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains/SystemInfo.hs
@@ -0,0 +1,355 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+
+
+{- |
+= SystemInfo
+
+The SystemInfo domain defines methods and events for querying low-level system information.
+-}
+
+
+module CDP.Domains.SystemInfo (module CDP.Domains.SystemInfo) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+
+
+
+-- | Type 'SystemInfo.GPUDevice'.
+--   Describes a single graphics processor (GPU).
+data SystemInfoGPUDevice = SystemInfoGPUDevice
+  {
+    -- | PCI ID of the GPU vendor, if available; 0 otherwise.
+    systemInfoGPUDeviceVendorId :: Double,
+    -- | PCI ID of the GPU device, if available; 0 otherwise.
+    systemInfoGPUDeviceDeviceId :: Double,
+    -- | Sub sys ID of the GPU, only available on Windows.
+    systemInfoGPUDeviceSubSysId :: Maybe Double,
+    -- | Revision of the GPU, only available on Windows.
+    systemInfoGPUDeviceRevision :: Maybe Double,
+    -- | String description of the GPU vendor, if the PCI ID is not available.
+    systemInfoGPUDeviceVendorString :: T.Text,
+    -- | String description of the GPU device, if the PCI ID is not available.
+    systemInfoGPUDeviceDeviceString :: T.Text,
+    -- | String description of the GPU driver vendor.
+    systemInfoGPUDeviceDriverVendor :: T.Text,
+    -- | String description of the GPU driver version.
+    systemInfoGPUDeviceDriverVersion :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON SystemInfoGPUDevice where
+  parseJSON = A.withObject "SystemInfoGPUDevice" $ \o -> SystemInfoGPUDevice
+    <$> o A..: "vendorId"
+    <*> o A..: "deviceId"
+    <*> o A..:? "subSysId"
+    <*> o A..:? "revision"
+    <*> o A..: "vendorString"
+    <*> o A..: "deviceString"
+    <*> o A..: "driverVendor"
+    <*> o A..: "driverVersion"
+instance ToJSON SystemInfoGPUDevice where
+  toJSON p = A.object $ catMaybes [
+    ("vendorId" A..=) <$> Just (systemInfoGPUDeviceVendorId p),
+    ("deviceId" A..=) <$> Just (systemInfoGPUDeviceDeviceId p),
+    ("subSysId" A..=) <$> (systemInfoGPUDeviceSubSysId p),
+    ("revision" A..=) <$> (systemInfoGPUDeviceRevision p),
+    ("vendorString" A..=) <$> Just (systemInfoGPUDeviceVendorString p),
+    ("deviceString" A..=) <$> Just (systemInfoGPUDeviceDeviceString p),
+    ("driverVendor" A..=) <$> Just (systemInfoGPUDeviceDriverVendor p),
+    ("driverVersion" A..=) <$> Just (systemInfoGPUDeviceDriverVersion p)
+    ]
+
+-- | Type 'SystemInfo.Size'.
+--   Describes the width and height dimensions of an entity.
+data SystemInfoSize = SystemInfoSize
+  {
+    -- | Width in pixels.
+    systemInfoSizeWidth :: Int,
+    -- | Height in pixels.
+    systemInfoSizeHeight :: Int
+  }
+  deriving (Eq, Show)
+instance FromJSON SystemInfoSize where
+  parseJSON = A.withObject "SystemInfoSize" $ \o -> SystemInfoSize
+    <$> o A..: "width"
+    <*> o A..: "height"
+instance ToJSON SystemInfoSize where
+  toJSON p = A.object $ catMaybes [
+    ("width" A..=) <$> Just (systemInfoSizeWidth p),
+    ("height" A..=) <$> Just (systemInfoSizeHeight p)
+    ]
+
+-- | Type 'SystemInfo.VideoDecodeAcceleratorCapability'.
+--   Describes a supported video decoding profile with its associated minimum and
+--   maximum resolutions.
+data SystemInfoVideoDecodeAcceleratorCapability = SystemInfoVideoDecodeAcceleratorCapability
+  {
+    -- | Video codec profile that is supported, e.g. VP9 Profile 2.
+    systemInfoVideoDecodeAcceleratorCapabilityProfile :: T.Text,
+    -- | Maximum video dimensions in pixels supported for this |profile|.
+    systemInfoVideoDecodeAcceleratorCapabilityMaxResolution :: SystemInfoSize,
+    -- | Minimum video dimensions in pixels supported for this |profile|.
+    systemInfoVideoDecodeAcceleratorCapabilityMinResolution :: SystemInfoSize
+  }
+  deriving (Eq, Show)
+instance FromJSON SystemInfoVideoDecodeAcceleratorCapability where
+  parseJSON = A.withObject "SystemInfoVideoDecodeAcceleratorCapability" $ \o -> SystemInfoVideoDecodeAcceleratorCapability
+    <$> o A..: "profile"
+    <*> o A..: "maxResolution"
+    <*> o A..: "minResolution"
+instance ToJSON SystemInfoVideoDecodeAcceleratorCapability where
+  toJSON p = A.object $ catMaybes [
+    ("profile" A..=) <$> Just (systemInfoVideoDecodeAcceleratorCapabilityProfile p),
+    ("maxResolution" A..=) <$> Just (systemInfoVideoDecodeAcceleratorCapabilityMaxResolution p),
+    ("minResolution" A..=) <$> Just (systemInfoVideoDecodeAcceleratorCapabilityMinResolution p)
+    ]
+
+-- | Type 'SystemInfo.VideoEncodeAcceleratorCapability'.
+--   Describes a supported video encoding profile with its associated maximum
+--   resolution and maximum framerate.
+data SystemInfoVideoEncodeAcceleratorCapability = SystemInfoVideoEncodeAcceleratorCapability
+  {
+    -- | Video codec profile that is supported, e.g H264 Main.
+    systemInfoVideoEncodeAcceleratorCapabilityProfile :: T.Text,
+    -- | Maximum video dimensions in pixels supported for this |profile|.
+    systemInfoVideoEncodeAcceleratorCapabilityMaxResolution :: SystemInfoSize,
+    -- | Maximum encoding framerate in frames per second supported for this
+    --   |profile|, as fraction's numerator and denominator, e.g. 24/1 fps,
+    --   24000/1001 fps, etc.
+    systemInfoVideoEncodeAcceleratorCapabilityMaxFramerateNumerator :: Int,
+    systemInfoVideoEncodeAcceleratorCapabilityMaxFramerateDenominator :: Int
+  }
+  deriving (Eq, Show)
+instance FromJSON SystemInfoVideoEncodeAcceleratorCapability where
+  parseJSON = A.withObject "SystemInfoVideoEncodeAcceleratorCapability" $ \o -> SystemInfoVideoEncodeAcceleratorCapability
+    <$> o A..: "profile"
+    <*> o A..: "maxResolution"
+    <*> o A..: "maxFramerateNumerator"
+    <*> o A..: "maxFramerateDenominator"
+instance ToJSON SystemInfoVideoEncodeAcceleratorCapability where
+  toJSON p = A.object $ catMaybes [
+    ("profile" A..=) <$> Just (systemInfoVideoEncodeAcceleratorCapabilityProfile p),
+    ("maxResolution" A..=) <$> Just (systemInfoVideoEncodeAcceleratorCapabilityMaxResolution p),
+    ("maxFramerateNumerator" A..=) <$> Just (systemInfoVideoEncodeAcceleratorCapabilityMaxFramerateNumerator p),
+    ("maxFramerateDenominator" A..=) <$> Just (systemInfoVideoEncodeAcceleratorCapabilityMaxFramerateDenominator p)
+    ]
+
+-- | Type 'SystemInfo.SubsamplingFormat'.
+--   YUV subsampling type of the pixels of a given image.
+data SystemInfoSubsamplingFormat = SystemInfoSubsamplingFormatYuv420 | SystemInfoSubsamplingFormatYuv422 | SystemInfoSubsamplingFormatYuv444
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON SystemInfoSubsamplingFormat where
+  parseJSON = A.withText "SystemInfoSubsamplingFormat" $ \v -> case v of
+    "yuv420" -> pure SystemInfoSubsamplingFormatYuv420
+    "yuv422" -> pure SystemInfoSubsamplingFormatYuv422
+    "yuv444" -> pure SystemInfoSubsamplingFormatYuv444
+    "_" -> fail "failed to parse SystemInfoSubsamplingFormat"
+instance ToJSON SystemInfoSubsamplingFormat where
+  toJSON v = A.String $ case v of
+    SystemInfoSubsamplingFormatYuv420 -> "yuv420"
+    SystemInfoSubsamplingFormatYuv422 -> "yuv422"
+    SystemInfoSubsamplingFormatYuv444 -> "yuv444"
+
+-- | Type 'SystemInfo.ImageType'.
+--   Image format of a given image.
+data SystemInfoImageType = SystemInfoImageTypeJpeg | SystemInfoImageTypeWebp | SystemInfoImageTypeUnknown
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON SystemInfoImageType where
+  parseJSON = A.withText "SystemInfoImageType" $ \v -> case v of
+    "jpeg" -> pure SystemInfoImageTypeJpeg
+    "webp" -> pure SystemInfoImageTypeWebp
+    "unknown" -> pure SystemInfoImageTypeUnknown
+    "_" -> fail "failed to parse SystemInfoImageType"
+instance ToJSON SystemInfoImageType where
+  toJSON v = A.String $ case v of
+    SystemInfoImageTypeJpeg -> "jpeg"
+    SystemInfoImageTypeWebp -> "webp"
+    SystemInfoImageTypeUnknown -> "unknown"
+
+-- | Type 'SystemInfo.ImageDecodeAcceleratorCapability'.
+--   Describes a supported image decoding profile with its associated minimum and
+--   maximum resolutions and subsampling.
+data SystemInfoImageDecodeAcceleratorCapability = SystemInfoImageDecodeAcceleratorCapability
+  {
+    -- | Image coded, e.g. Jpeg.
+    systemInfoImageDecodeAcceleratorCapabilityImageType :: SystemInfoImageType,
+    -- | Maximum supported dimensions of the image in pixels.
+    systemInfoImageDecodeAcceleratorCapabilityMaxDimensions :: SystemInfoSize,
+    -- | Minimum supported dimensions of the image in pixels.
+    systemInfoImageDecodeAcceleratorCapabilityMinDimensions :: SystemInfoSize,
+    -- | Optional array of supported subsampling formats, e.g. 4:2:0, if known.
+    systemInfoImageDecodeAcceleratorCapabilitySubsamplings :: [SystemInfoSubsamplingFormat]
+  }
+  deriving (Eq, Show)
+instance FromJSON SystemInfoImageDecodeAcceleratorCapability where
+  parseJSON = A.withObject "SystemInfoImageDecodeAcceleratorCapability" $ \o -> SystemInfoImageDecodeAcceleratorCapability
+    <$> o A..: "imageType"
+    <*> o A..: "maxDimensions"
+    <*> o A..: "minDimensions"
+    <*> o A..: "subsamplings"
+instance ToJSON SystemInfoImageDecodeAcceleratorCapability where
+  toJSON p = A.object $ catMaybes [
+    ("imageType" A..=) <$> Just (systemInfoImageDecodeAcceleratorCapabilityImageType p),
+    ("maxDimensions" A..=) <$> Just (systemInfoImageDecodeAcceleratorCapabilityMaxDimensions p),
+    ("minDimensions" A..=) <$> Just (systemInfoImageDecodeAcceleratorCapabilityMinDimensions p),
+    ("subsamplings" A..=) <$> Just (systemInfoImageDecodeAcceleratorCapabilitySubsamplings p)
+    ]
+
+-- | Type 'SystemInfo.GPUInfo'.
+--   Provides information about the GPU(s) on the system.
+data SystemInfoGPUInfo = SystemInfoGPUInfo
+  {
+    -- | The graphics devices on the system. Element 0 is the primary GPU.
+    systemInfoGPUInfoDevices :: [SystemInfoGPUDevice],
+    -- | An optional dictionary of additional GPU related attributes.
+    systemInfoGPUInfoAuxAttributes :: Maybe [(T.Text, T.Text)],
+    -- | An optional dictionary of graphics features and their status.
+    systemInfoGPUInfoFeatureStatus :: Maybe [(T.Text, T.Text)],
+    -- | An optional array of GPU driver bug workarounds.
+    systemInfoGPUInfoDriverBugWorkarounds :: [T.Text],
+    -- | Supported accelerated video decoding capabilities.
+    systemInfoGPUInfoVideoDecoding :: [SystemInfoVideoDecodeAcceleratorCapability],
+    -- | Supported accelerated video encoding capabilities.
+    systemInfoGPUInfoVideoEncoding :: [SystemInfoVideoEncodeAcceleratorCapability],
+    -- | Supported accelerated image decoding capabilities.
+    systemInfoGPUInfoImageDecoding :: [SystemInfoImageDecodeAcceleratorCapability]
+  }
+  deriving (Eq, Show)
+instance FromJSON SystemInfoGPUInfo where
+  parseJSON = A.withObject "SystemInfoGPUInfo" $ \o -> SystemInfoGPUInfo
+    <$> o A..: "devices"
+    <*> o A..:? "auxAttributes"
+    <*> o A..:? "featureStatus"
+    <*> o A..: "driverBugWorkarounds"
+    <*> o A..: "videoDecoding"
+    <*> o A..: "videoEncoding"
+    <*> o A..: "imageDecoding"
+instance ToJSON SystemInfoGPUInfo where
+  toJSON p = A.object $ catMaybes [
+    ("devices" A..=) <$> Just (systemInfoGPUInfoDevices p),
+    ("auxAttributes" A..=) <$> (systemInfoGPUInfoAuxAttributes p),
+    ("featureStatus" A..=) <$> (systemInfoGPUInfoFeatureStatus p),
+    ("driverBugWorkarounds" A..=) <$> Just (systemInfoGPUInfoDriverBugWorkarounds p),
+    ("videoDecoding" A..=) <$> Just (systemInfoGPUInfoVideoDecoding p),
+    ("videoEncoding" A..=) <$> Just (systemInfoGPUInfoVideoEncoding p),
+    ("imageDecoding" A..=) <$> Just (systemInfoGPUInfoImageDecoding p)
+    ]
+
+-- | Type 'SystemInfo.ProcessInfo'.
+--   Represents process info.
+data SystemInfoProcessInfo = SystemInfoProcessInfo
+  {
+    -- | Specifies process type.
+    systemInfoProcessInfoType :: T.Text,
+    -- | Specifies process id.
+    systemInfoProcessInfoId :: Int,
+    -- | Specifies cumulative CPU usage in seconds across all threads of the
+    --   process since the process start.
+    systemInfoProcessInfoCpuTime :: Double
+  }
+  deriving (Eq, Show)
+instance FromJSON SystemInfoProcessInfo where
+  parseJSON = A.withObject "SystemInfoProcessInfo" $ \o -> SystemInfoProcessInfo
+    <$> o A..: "type"
+    <*> o A..: "id"
+    <*> o A..: "cpuTime"
+instance ToJSON SystemInfoProcessInfo where
+  toJSON p = A.object $ catMaybes [
+    ("type" A..=) <$> Just (systemInfoProcessInfoType p),
+    ("id" A..=) <$> Just (systemInfoProcessInfoId p),
+    ("cpuTime" A..=) <$> Just (systemInfoProcessInfoCpuTime p)
+    ]
+
+-- | Returns information about the system.
+
+-- | Parameters of the 'SystemInfo.getInfo' command.
+data PSystemInfoGetInfo = PSystemInfoGetInfo
+  deriving (Eq, Show)
+pSystemInfoGetInfo
+  :: PSystemInfoGetInfo
+pSystemInfoGetInfo
+  = PSystemInfoGetInfo
+instance ToJSON PSystemInfoGetInfo where
+  toJSON _ = A.Null
+data SystemInfoGetInfo = SystemInfoGetInfo
+  {
+    -- | Information about the GPUs on the system.
+    systemInfoGetInfoGpu :: SystemInfoGPUInfo,
+    -- | A platform-dependent description of the model of the machine. On Mac OS, this is, for
+    --   example, 'MacBookPro'. Will be the empty string if not supported.
+    systemInfoGetInfoModelName :: T.Text,
+    -- | A platform-dependent description of the version of the machine. On Mac OS, this is, for
+    --   example, '10.1'. Will be the empty string if not supported.
+    systemInfoGetInfoModelVersion :: T.Text,
+    -- | The command line string used to launch the browser. Will be the empty string if not
+    --   supported.
+    systemInfoGetInfoCommandLine :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON SystemInfoGetInfo where
+  parseJSON = A.withObject "SystemInfoGetInfo" $ \o -> SystemInfoGetInfo
+    <$> o A..: "gpu"
+    <*> o A..: "modelName"
+    <*> o A..: "modelVersion"
+    <*> o A..: "commandLine"
+instance Command PSystemInfoGetInfo where
+  type CommandResponse PSystemInfoGetInfo = SystemInfoGetInfo
+  commandName _ = "SystemInfo.getInfo"
+
+-- | Returns information about all running processes.
+
+-- | Parameters of the 'SystemInfo.getProcessInfo' command.
+data PSystemInfoGetProcessInfo = PSystemInfoGetProcessInfo
+  deriving (Eq, Show)
+pSystemInfoGetProcessInfo
+  :: PSystemInfoGetProcessInfo
+pSystemInfoGetProcessInfo
+  = PSystemInfoGetProcessInfo
+instance ToJSON PSystemInfoGetProcessInfo where
+  toJSON _ = A.Null
+data SystemInfoGetProcessInfo = SystemInfoGetProcessInfo
+  {
+    -- | An array of process info blocks.
+    systemInfoGetProcessInfoProcessInfo :: [SystemInfoProcessInfo]
+  }
+  deriving (Eq, Show)
+instance FromJSON SystemInfoGetProcessInfo where
+  parseJSON = A.withObject "SystemInfoGetProcessInfo" $ \o -> SystemInfoGetProcessInfo
+    <$> o A..: "processInfo"
+instance Command PSystemInfoGetProcessInfo where
+  type CommandResponse PSystemInfoGetProcessInfo = SystemInfoGetProcessInfo
+  commandName _ = "SystemInfo.getProcessInfo"
+
diff --git a/src/CDP/Domains/Tethering.hs b/src/CDP/Domains/Tethering.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains/Tethering.hs
@@ -0,0 +1,122 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+
+
+{- |
+= Tethering
+
+The Tethering domain defines methods and events for browser port binding.
+-}
+
+
+module CDP.Domains.Tethering (module CDP.Domains.Tethering) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+
+
+
+-- | Type of the 'Tethering.accepted' event.
+data TetheringAccepted = TetheringAccepted
+  {
+    -- | Port number that was successfully bound.
+    tetheringAcceptedPort :: Int,
+    -- | Connection id to be used.
+    tetheringAcceptedConnectionId :: T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON TetheringAccepted where
+  parseJSON = A.withObject "TetheringAccepted" $ \o -> TetheringAccepted
+    <$> o A..: "port"
+    <*> o A..: "connectionId"
+instance Event TetheringAccepted where
+  eventName _ = "Tethering.accepted"
+
+-- | Request browser port binding.
+
+-- | Parameters of the 'Tethering.bind' command.
+data PTetheringBind = PTetheringBind
+  {
+    -- | Port number to bind.
+    pTetheringBindPort :: Int
+  }
+  deriving (Eq, Show)
+pTetheringBind
+  {-
+  -- | Port number to bind.
+  -}
+  :: Int
+  -> PTetheringBind
+pTetheringBind
+  arg_pTetheringBindPort
+  = PTetheringBind
+    arg_pTetheringBindPort
+instance ToJSON PTetheringBind where
+  toJSON p = A.object $ catMaybes [
+    ("port" A..=) <$> Just (pTetheringBindPort p)
+    ]
+instance Command PTetheringBind where
+  type CommandResponse PTetheringBind = ()
+  commandName _ = "Tethering.bind"
+  fromJSON = const . A.Success . const ()
+
+-- | Request browser port unbinding.
+
+-- | Parameters of the 'Tethering.unbind' command.
+data PTetheringUnbind = PTetheringUnbind
+  {
+    -- | Port number to unbind.
+    pTetheringUnbindPort :: Int
+  }
+  deriving (Eq, Show)
+pTetheringUnbind
+  {-
+  -- | Port number to unbind.
+  -}
+  :: Int
+  -> PTetheringUnbind
+pTetheringUnbind
+  arg_pTetheringUnbindPort
+  = PTetheringUnbind
+    arg_pTetheringUnbindPort
+instance ToJSON PTetheringUnbind where
+  toJSON p = A.object $ catMaybes [
+    ("port" A..=) <$> Just (pTetheringUnbindPort p)
+    ]
+instance Command PTetheringUnbind where
+  type CommandResponse PTetheringUnbind = ()
+  commandName _ = "Tethering.unbind"
+  fromJSON = const . A.Success . const ()
+
diff --git a/src/CDP/Domains/Tracing.hs b/src/CDP/Domains/Tracing.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains/Tracing.hs
@@ -0,0 +1,408 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+
+
+{- |
+= Tracing
+
+-}
+
+
+module CDP.Domains.Tracing (module CDP.Domains.Tracing) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+
+import CDP.Domains.IO as IO
+
+
+-- | Type 'Tracing.MemoryDumpConfig'.
+--   Configuration for memory dump. Used only when "memory-infra" category is enabled.
+type TracingMemoryDumpConfig = [(T.Text, T.Text)]
+
+-- | Type 'Tracing.TraceConfig'.
+data TracingTraceConfigRecordMode = TracingTraceConfigRecordModeRecordUntilFull | TracingTraceConfigRecordModeRecordContinuously | TracingTraceConfigRecordModeRecordAsMuchAsPossible | TracingTraceConfigRecordModeEchoToConsole
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON TracingTraceConfigRecordMode where
+  parseJSON = A.withText "TracingTraceConfigRecordMode" $ \v -> case v of
+    "recordUntilFull" -> pure TracingTraceConfigRecordModeRecordUntilFull
+    "recordContinuously" -> pure TracingTraceConfigRecordModeRecordContinuously
+    "recordAsMuchAsPossible" -> pure TracingTraceConfigRecordModeRecordAsMuchAsPossible
+    "echoToConsole" -> pure TracingTraceConfigRecordModeEchoToConsole
+    "_" -> fail "failed to parse TracingTraceConfigRecordMode"
+instance ToJSON TracingTraceConfigRecordMode where
+  toJSON v = A.String $ case v of
+    TracingTraceConfigRecordModeRecordUntilFull -> "recordUntilFull"
+    TracingTraceConfigRecordModeRecordContinuously -> "recordContinuously"
+    TracingTraceConfigRecordModeRecordAsMuchAsPossible -> "recordAsMuchAsPossible"
+    TracingTraceConfigRecordModeEchoToConsole -> "echoToConsole"
+data TracingTraceConfig = TracingTraceConfig
+  {
+    -- | Controls how the trace buffer stores data.
+    tracingTraceConfigRecordMode :: Maybe TracingTraceConfigRecordMode,
+    -- | Size of the trace buffer in kilobytes. If not specified or zero is passed, a default value
+    --   of 200 MB would be used.
+    tracingTraceConfigTraceBufferSizeInKb :: Maybe Double,
+    -- | Turns on JavaScript stack sampling.
+    tracingTraceConfigEnableSampling :: Maybe Bool,
+    -- | Turns on system tracing.
+    tracingTraceConfigEnableSystrace :: Maybe Bool,
+    -- | Turns on argument filter.
+    tracingTraceConfigEnableArgumentFilter :: Maybe Bool,
+    -- | Included category filters.
+    tracingTraceConfigIncludedCategories :: Maybe [T.Text],
+    -- | Excluded category filters.
+    tracingTraceConfigExcludedCategories :: Maybe [T.Text],
+    -- | Configuration to synthesize the delays in tracing.
+    tracingTraceConfigSyntheticDelays :: Maybe [T.Text],
+    -- | Configuration for memory dump triggers. Used only when "memory-infra" category is enabled.
+    tracingTraceConfigMemoryDumpConfig :: Maybe TracingMemoryDumpConfig
+  }
+  deriving (Eq, Show)
+instance FromJSON TracingTraceConfig where
+  parseJSON = A.withObject "TracingTraceConfig" $ \o -> TracingTraceConfig
+    <$> o A..:? "recordMode"
+    <*> o A..:? "traceBufferSizeInKb"
+    <*> o A..:? "enableSampling"
+    <*> o A..:? "enableSystrace"
+    <*> o A..:? "enableArgumentFilter"
+    <*> o A..:? "includedCategories"
+    <*> o A..:? "excludedCategories"
+    <*> o A..:? "syntheticDelays"
+    <*> o A..:? "memoryDumpConfig"
+instance ToJSON TracingTraceConfig where
+  toJSON p = A.object $ catMaybes [
+    ("recordMode" A..=) <$> (tracingTraceConfigRecordMode p),
+    ("traceBufferSizeInKb" A..=) <$> (tracingTraceConfigTraceBufferSizeInKb p),
+    ("enableSampling" A..=) <$> (tracingTraceConfigEnableSampling p),
+    ("enableSystrace" A..=) <$> (tracingTraceConfigEnableSystrace p),
+    ("enableArgumentFilter" A..=) <$> (tracingTraceConfigEnableArgumentFilter p),
+    ("includedCategories" A..=) <$> (tracingTraceConfigIncludedCategories p),
+    ("excludedCategories" A..=) <$> (tracingTraceConfigExcludedCategories p),
+    ("syntheticDelays" A..=) <$> (tracingTraceConfigSyntheticDelays p),
+    ("memoryDumpConfig" A..=) <$> (tracingTraceConfigMemoryDumpConfig p)
+    ]
+
+-- | Type 'Tracing.StreamFormat'.
+--   Data format of a trace. Can be either the legacy JSON format or the
+--   protocol buffer format. Note that the JSON format will be deprecated soon.
+data TracingStreamFormat = TracingStreamFormatJson | TracingStreamFormatProto
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON TracingStreamFormat where
+  parseJSON = A.withText "TracingStreamFormat" $ \v -> case v of
+    "json" -> pure TracingStreamFormatJson
+    "proto" -> pure TracingStreamFormatProto
+    "_" -> fail "failed to parse TracingStreamFormat"
+instance ToJSON TracingStreamFormat where
+  toJSON v = A.String $ case v of
+    TracingStreamFormatJson -> "json"
+    TracingStreamFormatProto -> "proto"
+
+-- | Type 'Tracing.StreamCompression'.
+--   Compression type to use for traces returned via streams.
+data TracingStreamCompression = TracingStreamCompressionNone | TracingStreamCompressionGzip
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON TracingStreamCompression where
+  parseJSON = A.withText "TracingStreamCompression" $ \v -> case v of
+    "none" -> pure TracingStreamCompressionNone
+    "gzip" -> pure TracingStreamCompressionGzip
+    "_" -> fail "failed to parse TracingStreamCompression"
+instance ToJSON TracingStreamCompression where
+  toJSON v = A.String $ case v of
+    TracingStreamCompressionNone -> "none"
+    TracingStreamCompressionGzip -> "gzip"
+
+-- | Type 'Tracing.MemoryDumpLevelOfDetail'.
+--   Details exposed when memory request explicitly declared.
+--   Keep consistent with memory_dump_request_args.h and
+--   memory_instrumentation.mojom
+data TracingMemoryDumpLevelOfDetail = TracingMemoryDumpLevelOfDetailBackground | TracingMemoryDumpLevelOfDetailLight | TracingMemoryDumpLevelOfDetailDetailed
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON TracingMemoryDumpLevelOfDetail where
+  parseJSON = A.withText "TracingMemoryDumpLevelOfDetail" $ \v -> case v of
+    "background" -> pure TracingMemoryDumpLevelOfDetailBackground
+    "light" -> pure TracingMemoryDumpLevelOfDetailLight
+    "detailed" -> pure TracingMemoryDumpLevelOfDetailDetailed
+    "_" -> fail "failed to parse TracingMemoryDumpLevelOfDetail"
+instance ToJSON TracingMemoryDumpLevelOfDetail where
+  toJSON v = A.String $ case v of
+    TracingMemoryDumpLevelOfDetailBackground -> "background"
+    TracingMemoryDumpLevelOfDetailLight -> "light"
+    TracingMemoryDumpLevelOfDetailDetailed -> "detailed"
+
+-- | Type 'Tracing.TracingBackend'.
+--   Backend type to use for tracing. `chrome` uses the Chrome-integrated
+--   tracing service and is supported on all platforms. `system` is only
+--   supported on Chrome OS and uses the Perfetto system tracing service.
+--   `auto` chooses `system` when the perfettoConfig provided to Tracing.start
+--   specifies at least one non-Chrome data source; otherwise uses `chrome`.
+data TracingTracingBackend = TracingTracingBackendAuto | TracingTracingBackendChrome | TracingTracingBackendSystem
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON TracingTracingBackend where
+  parseJSON = A.withText "TracingTracingBackend" $ \v -> case v of
+    "auto" -> pure TracingTracingBackendAuto
+    "chrome" -> pure TracingTracingBackendChrome
+    "system" -> pure TracingTracingBackendSystem
+    "_" -> fail "failed to parse TracingTracingBackend"
+instance ToJSON TracingTracingBackend where
+  toJSON v = A.String $ case v of
+    TracingTracingBackendAuto -> "auto"
+    TracingTracingBackendChrome -> "chrome"
+    TracingTracingBackendSystem -> "system"
+
+-- | Type of the 'Tracing.bufferUsage' event.
+data TracingBufferUsage = TracingBufferUsage
+  {
+    -- | A number in range [0..1] that indicates the used size of event buffer as a fraction of its
+    --   total size.
+    tracingBufferUsagePercentFull :: Maybe Double,
+    -- | An approximate number of events in the trace log.
+    tracingBufferUsageEventCount :: Maybe Double,
+    -- | A number in range [0..1] that indicates the used size of event buffer as a fraction of its
+    --   total size.
+    tracingBufferUsageValue :: Maybe Double
+  }
+  deriving (Eq, Show)
+instance FromJSON TracingBufferUsage where
+  parseJSON = A.withObject "TracingBufferUsage" $ \o -> TracingBufferUsage
+    <$> o A..:? "percentFull"
+    <*> o A..:? "eventCount"
+    <*> o A..:? "value"
+instance Event TracingBufferUsage where
+  eventName _ = "Tracing.bufferUsage"
+
+-- | Type of the 'Tracing.dataCollected' event.
+data TracingDataCollected = TracingDataCollected
+  {
+    tracingDataCollectedValue :: [[(T.Text, T.Text)]]
+  }
+  deriving (Eq, Show)
+instance FromJSON TracingDataCollected where
+  parseJSON = A.withObject "TracingDataCollected" $ \o -> TracingDataCollected
+    <$> o A..: "value"
+instance Event TracingDataCollected where
+  eventName _ = "Tracing.dataCollected"
+
+-- | Type of the 'Tracing.tracingComplete' event.
+data TracingTracingComplete = TracingTracingComplete
+  {
+    -- | Indicates whether some trace data is known to have been lost, e.g. because the trace ring
+    --   buffer wrapped around.
+    tracingTracingCompleteDataLossOccurred :: Bool,
+    -- | A handle of the stream that holds resulting trace data.
+    tracingTracingCompleteStream :: Maybe IO.IOStreamHandle,
+    -- | Trace data format of returned stream.
+    tracingTracingCompleteTraceFormat :: Maybe TracingStreamFormat,
+    -- | Compression format of returned stream.
+    tracingTracingCompleteStreamCompression :: Maybe TracingStreamCompression
+  }
+  deriving (Eq, Show)
+instance FromJSON TracingTracingComplete where
+  parseJSON = A.withObject "TracingTracingComplete" $ \o -> TracingTracingComplete
+    <$> o A..: "dataLossOccurred"
+    <*> o A..:? "stream"
+    <*> o A..:? "traceFormat"
+    <*> o A..:? "streamCompression"
+instance Event TracingTracingComplete where
+  eventName _ = "Tracing.tracingComplete"
+
+-- | Stop trace events collection.
+
+-- | Parameters of the 'Tracing.end' command.
+data PTracingEnd = PTracingEnd
+  deriving (Eq, Show)
+pTracingEnd
+  :: PTracingEnd
+pTracingEnd
+  = PTracingEnd
+instance ToJSON PTracingEnd where
+  toJSON _ = A.Null
+instance Command PTracingEnd where
+  type CommandResponse PTracingEnd = ()
+  commandName _ = "Tracing.end"
+  fromJSON = const . A.Success . const ()
+
+-- | Gets supported tracing categories.
+
+-- | Parameters of the 'Tracing.getCategories' command.
+data PTracingGetCategories = PTracingGetCategories
+  deriving (Eq, Show)
+pTracingGetCategories
+  :: PTracingGetCategories
+pTracingGetCategories
+  = PTracingGetCategories
+instance ToJSON PTracingGetCategories where
+  toJSON _ = A.Null
+data TracingGetCategories = TracingGetCategories
+  {
+    -- | A list of supported tracing categories.
+    tracingGetCategoriesCategories :: [T.Text]
+  }
+  deriving (Eq, Show)
+instance FromJSON TracingGetCategories where
+  parseJSON = A.withObject "TracingGetCategories" $ \o -> TracingGetCategories
+    <$> o A..: "categories"
+instance Command PTracingGetCategories where
+  type CommandResponse PTracingGetCategories = TracingGetCategories
+  commandName _ = "Tracing.getCategories"
+
+-- | Record a clock sync marker in the trace.
+
+-- | Parameters of the 'Tracing.recordClockSyncMarker' command.
+data PTracingRecordClockSyncMarker = PTracingRecordClockSyncMarker
+  {
+    -- | The ID of this clock sync marker
+    pTracingRecordClockSyncMarkerSyncId :: T.Text
+  }
+  deriving (Eq, Show)
+pTracingRecordClockSyncMarker
+  {-
+  -- | The ID of this clock sync marker
+  -}
+  :: T.Text
+  -> PTracingRecordClockSyncMarker
+pTracingRecordClockSyncMarker
+  arg_pTracingRecordClockSyncMarkerSyncId
+  = PTracingRecordClockSyncMarker
+    arg_pTracingRecordClockSyncMarkerSyncId
+instance ToJSON PTracingRecordClockSyncMarker where
+  toJSON p = A.object $ catMaybes [
+    ("syncId" A..=) <$> Just (pTracingRecordClockSyncMarkerSyncId p)
+    ]
+instance Command PTracingRecordClockSyncMarker where
+  type CommandResponse PTracingRecordClockSyncMarker = ()
+  commandName _ = "Tracing.recordClockSyncMarker"
+  fromJSON = const . A.Success . const ()
+
+-- | Request a global memory dump.
+
+-- | Parameters of the 'Tracing.requestMemoryDump' command.
+data PTracingRequestMemoryDump = PTracingRequestMemoryDump
+  {
+    -- | Enables more deterministic results by forcing garbage collection
+    pTracingRequestMemoryDumpDeterministic :: Maybe Bool,
+    -- | Specifies level of details in memory dump. Defaults to "detailed".
+    pTracingRequestMemoryDumpLevelOfDetail :: Maybe TracingMemoryDumpLevelOfDetail
+  }
+  deriving (Eq, Show)
+pTracingRequestMemoryDump
+  :: PTracingRequestMemoryDump
+pTracingRequestMemoryDump
+  = PTracingRequestMemoryDump
+    Nothing
+    Nothing
+instance ToJSON PTracingRequestMemoryDump where
+  toJSON p = A.object $ catMaybes [
+    ("deterministic" A..=) <$> (pTracingRequestMemoryDumpDeterministic p),
+    ("levelOfDetail" A..=) <$> (pTracingRequestMemoryDumpLevelOfDetail p)
+    ]
+data TracingRequestMemoryDump = TracingRequestMemoryDump
+  {
+    -- | GUID of the resulting global memory dump.
+    tracingRequestMemoryDumpDumpGuid :: T.Text,
+    -- | True iff the global memory dump succeeded.
+    tracingRequestMemoryDumpSuccess :: Bool
+  }
+  deriving (Eq, Show)
+instance FromJSON TracingRequestMemoryDump where
+  parseJSON = A.withObject "TracingRequestMemoryDump" $ \o -> TracingRequestMemoryDump
+    <$> o A..: "dumpGuid"
+    <*> o A..: "success"
+instance Command PTracingRequestMemoryDump where
+  type CommandResponse PTracingRequestMemoryDump = TracingRequestMemoryDump
+  commandName _ = "Tracing.requestMemoryDump"
+
+-- | Start trace events collection.
+
+-- | Parameters of the 'Tracing.start' command.
+data PTracingStartTransferMode = PTracingStartTransferModeReportEvents | PTracingStartTransferModeReturnAsStream
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON PTracingStartTransferMode where
+  parseJSON = A.withText "PTracingStartTransferMode" $ \v -> case v of
+    "ReportEvents" -> pure PTracingStartTransferModeReportEvents
+    "ReturnAsStream" -> pure PTracingStartTransferModeReturnAsStream
+    "_" -> fail "failed to parse PTracingStartTransferMode"
+instance ToJSON PTracingStartTransferMode where
+  toJSON v = A.String $ case v of
+    PTracingStartTransferModeReportEvents -> "ReportEvents"
+    PTracingStartTransferModeReturnAsStream -> "ReturnAsStream"
+data PTracingStart = PTracingStart
+  {
+    -- | If set, the agent will issue bufferUsage events at this interval, specified in milliseconds
+    pTracingStartBufferUsageReportingInterval :: Maybe Double,
+    -- | Whether to report trace events as series of dataCollected events or to save trace to a
+    --   stream (defaults to `ReportEvents`).
+    pTracingStartTransferMode :: Maybe PTracingStartTransferMode,
+    -- | Trace data format to use. This only applies when using `ReturnAsStream`
+    --   transfer mode (defaults to `json`).
+    pTracingStartStreamFormat :: Maybe TracingStreamFormat,
+    -- | Compression format to use. This only applies when using `ReturnAsStream`
+    --   transfer mode (defaults to `none`)
+    pTracingStartStreamCompression :: Maybe TracingStreamCompression,
+    pTracingStartTraceConfig :: Maybe TracingTraceConfig,
+    -- | Base64-encoded serialized perfetto.protos.TraceConfig protobuf message
+    --   When specified, the parameters `categories`, `options`, `traceConfig`
+    --   are ignored. (Encoded as a base64 string when passed over JSON)
+    pTracingStartPerfettoConfig :: Maybe T.Text,
+    -- | Backend type (defaults to `auto`)
+    pTracingStartTracingBackend :: Maybe TracingTracingBackend
+  }
+  deriving (Eq, Show)
+pTracingStart
+  :: PTracingStart
+pTracingStart
+  = PTracingStart
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+    Nothing
+instance ToJSON PTracingStart where
+  toJSON p = A.object $ catMaybes [
+    ("bufferUsageReportingInterval" A..=) <$> (pTracingStartBufferUsageReportingInterval p),
+    ("transferMode" A..=) <$> (pTracingStartTransferMode p),
+    ("streamFormat" A..=) <$> (pTracingStartStreamFormat p),
+    ("streamCompression" A..=) <$> (pTracingStartStreamCompression p),
+    ("traceConfig" A..=) <$> (pTracingStartTraceConfig p),
+    ("perfettoConfig" A..=) <$> (pTracingStartPerfettoConfig p),
+    ("tracingBackend" A..=) <$> (pTracingStartTracingBackend p)
+    ]
+instance Command PTracingStart where
+  type CommandResponse PTracingStart = ()
+  commandName _ = "Tracing.start"
+  fromJSON = const . A.Success . const ()
+
diff --git a/src/CDP/Domains/WebAudio.hs b/src/CDP/Domains/WebAudio.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains/WebAudio.hs
@@ -0,0 +1,548 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+
+
+{- |
+= WebAudio
+
+This domain allows inspection of Web Audio API.
+https://webaudio.github.io/web-audio-api/
+-}
+
+
+module CDP.Domains.WebAudio (module CDP.Domains.WebAudio) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+
+
+
+-- | Type 'WebAudio.GraphObjectId'.
+--   An unique ID for a graph object (AudioContext, AudioNode, AudioParam) in Web Audio API
+type WebAudioGraphObjectId = T.Text
+
+-- | Type 'WebAudio.ContextType'.
+--   Enum of BaseAudioContext types
+data WebAudioContextType = WebAudioContextTypeRealtime | WebAudioContextTypeOffline
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON WebAudioContextType where
+  parseJSON = A.withText "WebAudioContextType" $ \v -> case v of
+    "realtime" -> pure WebAudioContextTypeRealtime
+    "offline" -> pure WebAudioContextTypeOffline
+    "_" -> fail "failed to parse WebAudioContextType"
+instance ToJSON WebAudioContextType where
+  toJSON v = A.String $ case v of
+    WebAudioContextTypeRealtime -> "realtime"
+    WebAudioContextTypeOffline -> "offline"
+
+-- | Type 'WebAudio.ContextState'.
+--   Enum of AudioContextState from the spec
+data WebAudioContextState = WebAudioContextStateSuspended | WebAudioContextStateRunning | WebAudioContextStateClosed
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON WebAudioContextState where
+  parseJSON = A.withText "WebAudioContextState" $ \v -> case v of
+    "suspended" -> pure WebAudioContextStateSuspended
+    "running" -> pure WebAudioContextStateRunning
+    "closed" -> pure WebAudioContextStateClosed
+    "_" -> fail "failed to parse WebAudioContextState"
+instance ToJSON WebAudioContextState where
+  toJSON v = A.String $ case v of
+    WebAudioContextStateSuspended -> "suspended"
+    WebAudioContextStateRunning -> "running"
+    WebAudioContextStateClosed -> "closed"
+
+-- | Type 'WebAudio.NodeType'.
+--   Enum of AudioNode types
+type WebAudioNodeType = T.Text
+
+-- | Type 'WebAudio.ChannelCountMode'.
+--   Enum of AudioNode::ChannelCountMode from the spec
+data WebAudioChannelCountMode = WebAudioChannelCountModeClampedMax | WebAudioChannelCountModeExplicit | WebAudioChannelCountModeMax
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON WebAudioChannelCountMode where
+  parseJSON = A.withText "WebAudioChannelCountMode" $ \v -> case v of
+    "clamped-max" -> pure WebAudioChannelCountModeClampedMax
+    "explicit" -> pure WebAudioChannelCountModeExplicit
+    "max" -> pure WebAudioChannelCountModeMax
+    "_" -> fail "failed to parse WebAudioChannelCountMode"
+instance ToJSON WebAudioChannelCountMode where
+  toJSON v = A.String $ case v of
+    WebAudioChannelCountModeClampedMax -> "clamped-max"
+    WebAudioChannelCountModeExplicit -> "explicit"
+    WebAudioChannelCountModeMax -> "max"
+
+-- | Type 'WebAudio.ChannelInterpretation'.
+--   Enum of AudioNode::ChannelInterpretation from the spec
+data WebAudioChannelInterpretation = WebAudioChannelInterpretationDiscrete | WebAudioChannelInterpretationSpeakers
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON WebAudioChannelInterpretation where
+  parseJSON = A.withText "WebAudioChannelInterpretation" $ \v -> case v of
+    "discrete" -> pure WebAudioChannelInterpretationDiscrete
+    "speakers" -> pure WebAudioChannelInterpretationSpeakers
+    "_" -> fail "failed to parse WebAudioChannelInterpretation"
+instance ToJSON WebAudioChannelInterpretation where
+  toJSON v = A.String $ case v of
+    WebAudioChannelInterpretationDiscrete -> "discrete"
+    WebAudioChannelInterpretationSpeakers -> "speakers"
+
+-- | Type 'WebAudio.ParamType'.
+--   Enum of AudioParam types
+type WebAudioParamType = T.Text
+
+-- | Type 'WebAudio.AutomationRate'.
+--   Enum of AudioParam::AutomationRate from the spec
+data WebAudioAutomationRate = WebAudioAutomationRateARate | WebAudioAutomationRateKRate
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON WebAudioAutomationRate where
+  parseJSON = A.withText "WebAudioAutomationRate" $ \v -> case v of
+    "a-rate" -> pure WebAudioAutomationRateARate
+    "k-rate" -> pure WebAudioAutomationRateKRate
+    "_" -> fail "failed to parse WebAudioAutomationRate"
+instance ToJSON WebAudioAutomationRate where
+  toJSON v = A.String $ case v of
+    WebAudioAutomationRateARate -> "a-rate"
+    WebAudioAutomationRateKRate -> "k-rate"
+
+-- | Type 'WebAudio.ContextRealtimeData'.
+--   Fields in AudioContext that change in real-time.
+data WebAudioContextRealtimeData = WebAudioContextRealtimeData
+  {
+    -- | The current context time in second in BaseAudioContext.
+    webAudioContextRealtimeDataCurrentTime :: Double,
+    -- | The time spent on rendering graph divided by render quantum duration,
+    --   and multiplied by 100. 100 means the audio renderer reached the full
+    --   capacity and glitch may occur.
+    webAudioContextRealtimeDataRenderCapacity :: Double,
+    -- | A running mean of callback interval.
+    webAudioContextRealtimeDataCallbackIntervalMean :: Double,
+    -- | A running variance of callback interval.
+    webAudioContextRealtimeDataCallbackIntervalVariance :: Double
+  }
+  deriving (Eq, Show)
+instance FromJSON WebAudioContextRealtimeData where
+  parseJSON = A.withObject "WebAudioContextRealtimeData" $ \o -> WebAudioContextRealtimeData
+    <$> o A..: "currentTime"
+    <*> o A..: "renderCapacity"
+    <*> o A..: "callbackIntervalMean"
+    <*> o A..: "callbackIntervalVariance"
+instance ToJSON WebAudioContextRealtimeData where
+  toJSON p = A.object $ catMaybes [
+    ("currentTime" A..=) <$> Just (webAudioContextRealtimeDataCurrentTime p),
+    ("renderCapacity" A..=) <$> Just (webAudioContextRealtimeDataRenderCapacity p),
+    ("callbackIntervalMean" A..=) <$> Just (webAudioContextRealtimeDataCallbackIntervalMean p),
+    ("callbackIntervalVariance" A..=) <$> Just (webAudioContextRealtimeDataCallbackIntervalVariance p)
+    ]
+
+-- | Type 'WebAudio.BaseAudioContext'.
+--   Protocol object for BaseAudioContext
+data WebAudioBaseAudioContext = WebAudioBaseAudioContext
+  {
+    webAudioBaseAudioContextContextId :: WebAudioGraphObjectId,
+    webAudioBaseAudioContextContextType :: WebAudioContextType,
+    webAudioBaseAudioContextContextState :: WebAudioContextState,
+    webAudioBaseAudioContextRealtimeData :: Maybe WebAudioContextRealtimeData,
+    -- | Platform-dependent callback buffer size.
+    webAudioBaseAudioContextCallbackBufferSize :: Double,
+    -- | Number of output channels supported by audio hardware in use.
+    webAudioBaseAudioContextMaxOutputChannelCount :: Double,
+    -- | Context sample rate.
+    webAudioBaseAudioContextSampleRate :: Double
+  }
+  deriving (Eq, Show)
+instance FromJSON WebAudioBaseAudioContext where
+  parseJSON = A.withObject "WebAudioBaseAudioContext" $ \o -> WebAudioBaseAudioContext
+    <$> o A..: "contextId"
+    <*> o A..: "contextType"
+    <*> o A..: "contextState"
+    <*> o A..:? "realtimeData"
+    <*> o A..: "callbackBufferSize"
+    <*> o A..: "maxOutputChannelCount"
+    <*> o A..: "sampleRate"
+instance ToJSON WebAudioBaseAudioContext where
+  toJSON p = A.object $ catMaybes [
+    ("contextId" A..=) <$> Just (webAudioBaseAudioContextContextId p),
+    ("contextType" A..=) <$> Just (webAudioBaseAudioContextContextType p),
+    ("contextState" A..=) <$> Just (webAudioBaseAudioContextContextState p),
+    ("realtimeData" A..=) <$> (webAudioBaseAudioContextRealtimeData p),
+    ("callbackBufferSize" A..=) <$> Just (webAudioBaseAudioContextCallbackBufferSize p),
+    ("maxOutputChannelCount" A..=) <$> Just (webAudioBaseAudioContextMaxOutputChannelCount p),
+    ("sampleRate" A..=) <$> Just (webAudioBaseAudioContextSampleRate p)
+    ]
+
+-- | Type 'WebAudio.AudioListener'.
+--   Protocol object for AudioListener
+data WebAudioAudioListener = WebAudioAudioListener
+  {
+    webAudioAudioListenerListenerId :: WebAudioGraphObjectId,
+    webAudioAudioListenerContextId :: WebAudioGraphObjectId
+  }
+  deriving (Eq, Show)
+instance FromJSON WebAudioAudioListener where
+  parseJSON = A.withObject "WebAudioAudioListener" $ \o -> WebAudioAudioListener
+    <$> o A..: "listenerId"
+    <*> o A..: "contextId"
+instance ToJSON WebAudioAudioListener where
+  toJSON p = A.object $ catMaybes [
+    ("listenerId" A..=) <$> Just (webAudioAudioListenerListenerId p),
+    ("contextId" A..=) <$> Just (webAudioAudioListenerContextId p)
+    ]
+
+-- | Type 'WebAudio.AudioNode'.
+--   Protocol object for AudioNode
+data WebAudioAudioNode = WebAudioAudioNode
+  {
+    webAudioAudioNodeNodeId :: WebAudioGraphObjectId,
+    webAudioAudioNodeContextId :: WebAudioGraphObjectId,
+    webAudioAudioNodeNodeType :: WebAudioNodeType,
+    webAudioAudioNodeNumberOfInputs :: Double,
+    webAudioAudioNodeNumberOfOutputs :: Double,
+    webAudioAudioNodeChannelCount :: Double,
+    webAudioAudioNodeChannelCountMode :: WebAudioChannelCountMode,
+    webAudioAudioNodeChannelInterpretation :: WebAudioChannelInterpretation
+  }
+  deriving (Eq, Show)
+instance FromJSON WebAudioAudioNode where
+  parseJSON = A.withObject "WebAudioAudioNode" $ \o -> WebAudioAudioNode
+    <$> o A..: "nodeId"
+    <*> o A..: "contextId"
+    <*> o A..: "nodeType"
+    <*> o A..: "numberOfInputs"
+    <*> o A..: "numberOfOutputs"
+    <*> o A..: "channelCount"
+    <*> o A..: "channelCountMode"
+    <*> o A..: "channelInterpretation"
+instance ToJSON WebAudioAudioNode where
+  toJSON p = A.object $ catMaybes [
+    ("nodeId" A..=) <$> Just (webAudioAudioNodeNodeId p),
+    ("contextId" A..=) <$> Just (webAudioAudioNodeContextId p),
+    ("nodeType" A..=) <$> Just (webAudioAudioNodeNodeType p),
+    ("numberOfInputs" A..=) <$> Just (webAudioAudioNodeNumberOfInputs p),
+    ("numberOfOutputs" A..=) <$> Just (webAudioAudioNodeNumberOfOutputs p),
+    ("channelCount" A..=) <$> Just (webAudioAudioNodeChannelCount p),
+    ("channelCountMode" A..=) <$> Just (webAudioAudioNodeChannelCountMode p),
+    ("channelInterpretation" A..=) <$> Just (webAudioAudioNodeChannelInterpretation p)
+    ]
+
+-- | Type 'WebAudio.AudioParam'.
+--   Protocol object for AudioParam
+data WebAudioAudioParam = WebAudioAudioParam
+  {
+    webAudioAudioParamParamId :: WebAudioGraphObjectId,
+    webAudioAudioParamNodeId :: WebAudioGraphObjectId,
+    webAudioAudioParamContextId :: WebAudioGraphObjectId,
+    webAudioAudioParamParamType :: WebAudioParamType,
+    webAudioAudioParamRate :: WebAudioAutomationRate,
+    webAudioAudioParamDefaultValue :: Double,
+    webAudioAudioParamMinValue :: Double,
+    webAudioAudioParamMaxValue :: Double
+  }
+  deriving (Eq, Show)
+instance FromJSON WebAudioAudioParam where
+  parseJSON = A.withObject "WebAudioAudioParam" $ \o -> WebAudioAudioParam
+    <$> o A..: "paramId"
+    <*> o A..: "nodeId"
+    <*> o A..: "contextId"
+    <*> o A..: "paramType"
+    <*> o A..: "rate"
+    <*> o A..: "defaultValue"
+    <*> o A..: "minValue"
+    <*> o A..: "maxValue"
+instance ToJSON WebAudioAudioParam where
+  toJSON p = A.object $ catMaybes [
+    ("paramId" A..=) <$> Just (webAudioAudioParamParamId p),
+    ("nodeId" A..=) <$> Just (webAudioAudioParamNodeId p),
+    ("contextId" A..=) <$> Just (webAudioAudioParamContextId p),
+    ("paramType" A..=) <$> Just (webAudioAudioParamParamType p),
+    ("rate" A..=) <$> Just (webAudioAudioParamRate p),
+    ("defaultValue" A..=) <$> Just (webAudioAudioParamDefaultValue p),
+    ("minValue" A..=) <$> Just (webAudioAudioParamMinValue p),
+    ("maxValue" A..=) <$> Just (webAudioAudioParamMaxValue p)
+    ]
+
+-- | Type of the 'WebAudio.contextCreated' event.
+data WebAudioContextCreated = WebAudioContextCreated
+  {
+    webAudioContextCreatedContext :: WebAudioBaseAudioContext
+  }
+  deriving (Eq, Show)
+instance FromJSON WebAudioContextCreated where
+  parseJSON = A.withObject "WebAudioContextCreated" $ \o -> WebAudioContextCreated
+    <$> o A..: "context"
+instance Event WebAudioContextCreated where
+  eventName _ = "WebAudio.contextCreated"
+
+-- | Type of the 'WebAudio.contextWillBeDestroyed' event.
+data WebAudioContextWillBeDestroyed = WebAudioContextWillBeDestroyed
+  {
+    webAudioContextWillBeDestroyedContextId :: WebAudioGraphObjectId
+  }
+  deriving (Eq, Show)
+instance FromJSON WebAudioContextWillBeDestroyed where
+  parseJSON = A.withObject "WebAudioContextWillBeDestroyed" $ \o -> WebAudioContextWillBeDestroyed
+    <$> o A..: "contextId"
+instance Event WebAudioContextWillBeDestroyed where
+  eventName _ = "WebAudio.contextWillBeDestroyed"
+
+-- | Type of the 'WebAudio.contextChanged' event.
+data WebAudioContextChanged = WebAudioContextChanged
+  {
+    webAudioContextChangedContext :: WebAudioBaseAudioContext
+  }
+  deriving (Eq, Show)
+instance FromJSON WebAudioContextChanged where
+  parseJSON = A.withObject "WebAudioContextChanged" $ \o -> WebAudioContextChanged
+    <$> o A..: "context"
+instance Event WebAudioContextChanged where
+  eventName _ = "WebAudio.contextChanged"
+
+-- | Type of the 'WebAudio.audioListenerCreated' event.
+data WebAudioAudioListenerCreated = WebAudioAudioListenerCreated
+  {
+    webAudioAudioListenerCreatedListener :: WebAudioAudioListener
+  }
+  deriving (Eq, Show)
+instance FromJSON WebAudioAudioListenerCreated where
+  parseJSON = A.withObject "WebAudioAudioListenerCreated" $ \o -> WebAudioAudioListenerCreated
+    <$> o A..: "listener"
+instance Event WebAudioAudioListenerCreated where
+  eventName _ = "WebAudio.audioListenerCreated"
+
+-- | Type of the 'WebAudio.audioListenerWillBeDestroyed' event.
+data WebAudioAudioListenerWillBeDestroyed = WebAudioAudioListenerWillBeDestroyed
+  {
+    webAudioAudioListenerWillBeDestroyedContextId :: WebAudioGraphObjectId,
+    webAudioAudioListenerWillBeDestroyedListenerId :: WebAudioGraphObjectId
+  }
+  deriving (Eq, Show)
+instance FromJSON WebAudioAudioListenerWillBeDestroyed where
+  parseJSON = A.withObject "WebAudioAudioListenerWillBeDestroyed" $ \o -> WebAudioAudioListenerWillBeDestroyed
+    <$> o A..: "contextId"
+    <*> o A..: "listenerId"
+instance Event WebAudioAudioListenerWillBeDestroyed where
+  eventName _ = "WebAudio.audioListenerWillBeDestroyed"
+
+-- | Type of the 'WebAudio.audioNodeCreated' event.
+data WebAudioAudioNodeCreated = WebAudioAudioNodeCreated
+  {
+    webAudioAudioNodeCreatedNode :: WebAudioAudioNode
+  }
+  deriving (Eq, Show)
+instance FromJSON WebAudioAudioNodeCreated where
+  parseJSON = A.withObject "WebAudioAudioNodeCreated" $ \o -> WebAudioAudioNodeCreated
+    <$> o A..: "node"
+instance Event WebAudioAudioNodeCreated where
+  eventName _ = "WebAudio.audioNodeCreated"
+
+-- | Type of the 'WebAudio.audioNodeWillBeDestroyed' event.
+data WebAudioAudioNodeWillBeDestroyed = WebAudioAudioNodeWillBeDestroyed
+  {
+    webAudioAudioNodeWillBeDestroyedContextId :: WebAudioGraphObjectId,
+    webAudioAudioNodeWillBeDestroyedNodeId :: WebAudioGraphObjectId
+  }
+  deriving (Eq, Show)
+instance FromJSON WebAudioAudioNodeWillBeDestroyed where
+  parseJSON = A.withObject "WebAudioAudioNodeWillBeDestroyed" $ \o -> WebAudioAudioNodeWillBeDestroyed
+    <$> o A..: "contextId"
+    <*> o A..: "nodeId"
+instance Event WebAudioAudioNodeWillBeDestroyed where
+  eventName _ = "WebAudio.audioNodeWillBeDestroyed"
+
+-- | Type of the 'WebAudio.audioParamCreated' event.
+data WebAudioAudioParamCreated = WebAudioAudioParamCreated
+  {
+    webAudioAudioParamCreatedParam :: WebAudioAudioParam
+  }
+  deriving (Eq, Show)
+instance FromJSON WebAudioAudioParamCreated where
+  parseJSON = A.withObject "WebAudioAudioParamCreated" $ \o -> WebAudioAudioParamCreated
+    <$> o A..: "param"
+instance Event WebAudioAudioParamCreated where
+  eventName _ = "WebAudio.audioParamCreated"
+
+-- | Type of the 'WebAudio.audioParamWillBeDestroyed' event.
+data WebAudioAudioParamWillBeDestroyed = WebAudioAudioParamWillBeDestroyed
+  {
+    webAudioAudioParamWillBeDestroyedContextId :: WebAudioGraphObjectId,
+    webAudioAudioParamWillBeDestroyedNodeId :: WebAudioGraphObjectId,
+    webAudioAudioParamWillBeDestroyedParamId :: WebAudioGraphObjectId
+  }
+  deriving (Eq, Show)
+instance FromJSON WebAudioAudioParamWillBeDestroyed where
+  parseJSON = A.withObject "WebAudioAudioParamWillBeDestroyed" $ \o -> WebAudioAudioParamWillBeDestroyed
+    <$> o A..: "contextId"
+    <*> o A..: "nodeId"
+    <*> o A..: "paramId"
+instance Event WebAudioAudioParamWillBeDestroyed where
+  eventName _ = "WebAudio.audioParamWillBeDestroyed"
+
+-- | Type of the 'WebAudio.nodesConnected' event.
+data WebAudioNodesConnected = WebAudioNodesConnected
+  {
+    webAudioNodesConnectedContextId :: WebAudioGraphObjectId,
+    webAudioNodesConnectedSourceId :: WebAudioGraphObjectId,
+    webAudioNodesConnectedDestinationId :: WebAudioGraphObjectId,
+    webAudioNodesConnectedSourceOutputIndex :: Maybe Double,
+    webAudioNodesConnectedDestinationInputIndex :: Maybe Double
+  }
+  deriving (Eq, Show)
+instance FromJSON WebAudioNodesConnected where
+  parseJSON = A.withObject "WebAudioNodesConnected" $ \o -> WebAudioNodesConnected
+    <$> o A..: "contextId"
+    <*> o A..: "sourceId"
+    <*> o A..: "destinationId"
+    <*> o A..:? "sourceOutputIndex"
+    <*> o A..:? "destinationInputIndex"
+instance Event WebAudioNodesConnected where
+  eventName _ = "WebAudio.nodesConnected"
+
+-- | Type of the 'WebAudio.nodesDisconnected' event.
+data WebAudioNodesDisconnected = WebAudioNodesDisconnected
+  {
+    webAudioNodesDisconnectedContextId :: WebAudioGraphObjectId,
+    webAudioNodesDisconnectedSourceId :: WebAudioGraphObjectId,
+    webAudioNodesDisconnectedDestinationId :: WebAudioGraphObjectId,
+    webAudioNodesDisconnectedSourceOutputIndex :: Maybe Double,
+    webAudioNodesDisconnectedDestinationInputIndex :: Maybe Double
+  }
+  deriving (Eq, Show)
+instance FromJSON WebAudioNodesDisconnected where
+  parseJSON = A.withObject "WebAudioNodesDisconnected" $ \o -> WebAudioNodesDisconnected
+    <$> o A..: "contextId"
+    <*> o A..: "sourceId"
+    <*> o A..: "destinationId"
+    <*> o A..:? "sourceOutputIndex"
+    <*> o A..:? "destinationInputIndex"
+instance Event WebAudioNodesDisconnected where
+  eventName _ = "WebAudio.nodesDisconnected"
+
+-- | Type of the 'WebAudio.nodeParamConnected' event.
+data WebAudioNodeParamConnected = WebAudioNodeParamConnected
+  {
+    webAudioNodeParamConnectedContextId :: WebAudioGraphObjectId,
+    webAudioNodeParamConnectedSourceId :: WebAudioGraphObjectId,
+    webAudioNodeParamConnectedDestinationId :: WebAudioGraphObjectId,
+    webAudioNodeParamConnectedSourceOutputIndex :: Maybe Double
+  }
+  deriving (Eq, Show)
+instance FromJSON WebAudioNodeParamConnected where
+  parseJSON = A.withObject "WebAudioNodeParamConnected" $ \o -> WebAudioNodeParamConnected
+    <$> o A..: "contextId"
+    <*> o A..: "sourceId"
+    <*> o A..: "destinationId"
+    <*> o A..:? "sourceOutputIndex"
+instance Event WebAudioNodeParamConnected where
+  eventName _ = "WebAudio.nodeParamConnected"
+
+-- | Type of the 'WebAudio.nodeParamDisconnected' event.
+data WebAudioNodeParamDisconnected = WebAudioNodeParamDisconnected
+  {
+    webAudioNodeParamDisconnectedContextId :: WebAudioGraphObjectId,
+    webAudioNodeParamDisconnectedSourceId :: WebAudioGraphObjectId,
+    webAudioNodeParamDisconnectedDestinationId :: WebAudioGraphObjectId,
+    webAudioNodeParamDisconnectedSourceOutputIndex :: Maybe Double
+  }
+  deriving (Eq, Show)
+instance FromJSON WebAudioNodeParamDisconnected where
+  parseJSON = A.withObject "WebAudioNodeParamDisconnected" $ \o -> WebAudioNodeParamDisconnected
+    <$> o A..: "contextId"
+    <*> o A..: "sourceId"
+    <*> o A..: "destinationId"
+    <*> o A..:? "sourceOutputIndex"
+instance Event WebAudioNodeParamDisconnected where
+  eventName _ = "WebAudio.nodeParamDisconnected"
+
+-- | Enables the WebAudio domain and starts sending context lifetime events.
+
+-- | Parameters of the 'WebAudio.enable' command.
+data PWebAudioEnable = PWebAudioEnable
+  deriving (Eq, Show)
+pWebAudioEnable
+  :: PWebAudioEnable
+pWebAudioEnable
+  = PWebAudioEnable
+instance ToJSON PWebAudioEnable where
+  toJSON _ = A.Null
+instance Command PWebAudioEnable where
+  type CommandResponse PWebAudioEnable = ()
+  commandName _ = "WebAudio.enable"
+  fromJSON = const . A.Success . const ()
+
+-- | Disables the WebAudio domain.
+
+-- | Parameters of the 'WebAudio.disable' command.
+data PWebAudioDisable = PWebAudioDisable
+  deriving (Eq, Show)
+pWebAudioDisable
+  :: PWebAudioDisable
+pWebAudioDisable
+  = PWebAudioDisable
+instance ToJSON PWebAudioDisable where
+  toJSON _ = A.Null
+instance Command PWebAudioDisable where
+  type CommandResponse PWebAudioDisable = ()
+  commandName _ = "WebAudio.disable"
+  fromJSON = const . A.Success . const ()
+
+-- | Fetch the realtime data from the registered contexts.
+
+-- | Parameters of the 'WebAudio.getRealtimeData' command.
+data PWebAudioGetRealtimeData = PWebAudioGetRealtimeData
+  {
+    pWebAudioGetRealtimeDataContextId :: WebAudioGraphObjectId
+  }
+  deriving (Eq, Show)
+pWebAudioGetRealtimeData
+  :: WebAudioGraphObjectId
+  -> PWebAudioGetRealtimeData
+pWebAudioGetRealtimeData
+  arg_pWebAudioGetRealtimeDataContextId
+  = PWebAudioGetRealtimeData
+    arg_pWebAudioGetRealtimeDataContextId
+instance ToJSON PWebAudioGetRealtimeData where
+  toJSON p = A.object $ catMaybes [
+    ("contextId" A..=) <$> Just (pWebAudioGetRealtimeDataContextId p)
+    ]
+data WebAudioGetRealtimeData = WebAudioGetRealtimeData
+  {
+    webAudioGetRealtimeDataRealtimeData :: WebAudioContextRealtimeData
+  }
+  deriving (Eq, Show)
+instance FromJSON WebAudioGetRealtimeData where
+  parseJSON = A.withObject "WebAudioGetRealtimeData" $ \o -> WebAudioGetRealtimeData
+    <$> o A..: "realtimeData"
+instance Command PWebAudioGetRealtimeData where
+  type CommandResponse PWebAudioGetRealtimeData = WebAudioGetRealtimeData
+  commandName _ = "WebAudio.getRealtimeData"
+
diff --git a/src/CDP/Domains/WebAuthn.hs b/src/CDP/Domains/WebAuthn.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Domains/WebAuthn.hs
@@ -0,0 +1,507 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TypeFamilies #-}
+
+
+{- |
+= WebAuthn
+
+This domain allows configuring virtual authenticators to test the WebAuthn
+API.
+-}
+
+
+module CDP.Domains.WebAuthn (module CDP.Domains.WebAuthn) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe          
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.HTTP.Simple as Http
+import qualified Network.URI          as Uri
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import GHC.Generics
+import Data.Char
+import Data.Default
+
+import CDP.Internal.Utils
+
+
+
+
+-- | Type 'WebAuthn.AuthenticatorId'.
+type WebAuthnAuthenticatorId = T.Text
+
+-- | Type 'WebAuthn.AuthenticatorProtocol'.
+data WebAuthnAuthenticatorProtocol = WebAuthnAuthenticatorProtocolU2f | WebAuthnAuthenticatorProtocolCtap2
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON WebAuthnAuthenticatorProtocol where
+  parseJSON = A.withText "WebAuthnAuthenticatorProtocol" $ \v -> case v of
+    "u2f" -> pure WebAuthnAuthenticatorProtocolU2f
+    "ctap2" -> pure WebAuthnAuthenticatorProtocolCtap2
+    "_" -> fail "failed to parse WebAuthnAuthenticatorProtocol"
+instance ToJSON WebAuthnAuthenticatorProtocol where
+  toJSON v = A.String $ case v of
+    WebAuthnAuthenticatorProtocolU2f -> "u2f"
+    WebAuthnAuthenticatorProtocolCtap2 -> "ctap2"
+
+-- | Type 'WebAuthn.Ctap2Version'.
+data WebAuthnCtap2Version = WebAuthnCtap2VersionCtap2_0 | WebAuthnCtap2VersionCtap2_1
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON WebAuthnCtap2Version where
+  parseJSON = A.withText "WebAuthnCtap2Version" $ \v -> case v of
+    "ctap2_0" -> pure WebAuthnCtap2VersionCtap2_0
+    "ctap2_1" -> pure WebAuthnCtap2VersionCtap2_1
+    "_" -> fail "failed to parse WebAuthnCtap2Version"
+instance ToJSON WebAuthnCtap2Version where
+  toJSON v = A.String $ case v of
+    WebAuthnCtap2VersionCtap2_0 -> "ctap2_0"
+    WebAuthnCtap2VersionCtap2_1 -> "ctap2_1"
+
+-- | Type 'WebAuthn.AuthenticatorTransport'.
+data WebAuthnAuthenticatorTransport = WebAuthnAuthenticatorTransportUsb | WebAuthnAuthenticatorTransportNfc | WebAuthnAuthenticatorTransportBle | WebAuthnAuthenticatorTransportCable | WebAuthnAuthenticatorTransportInternal
+  deriving (Ord, Eq, Show, Read)
+instance FromJSON WebAuthnAuthenticatorTransport where
+  parseJSON = A.withText "WebAuthnAuthenticatorTransport" $ \v -> case v of
+    "usb" -> pure WebAuthnAuthenticatorTransportUsb
+    "nfc" -> pure WebAuthnAuthenticatorTransportNfc
+    "ble" -> pure WebAuthnAuthenticatorTransportBle
+    "cable" -> pure WebAuthnAuthenticatorTransportCable
+    "internal" -> pure WebAuthnAuthenticatorTransportInternal
+    "_" -> fail "failed to parse WebAuthnAuthenticatorTransport"
+instance ToJSON WebAuthnAuthenticatorTransport where
+  toJSON v = A.String $ case v of
+    WebAuthnAuthenticatorTransportUsb -> "usb"
+    WebAuthnAuthenticatorTransportNfc -> "nfc"
+    WebAuthnAuthenticatorTransportBle -> "ble"
+    WebAuthnAuthenticatorTransportCable -> "cable"
+    WebAuthnAuthenticatorTransportInternal -> "internal"
+
+-- | Type 'WebAuthn.VirtualAuthenticatorOptions'.
+data WebAuthnVirtualAuthenticatorOptions = WebAuthnVirtualAuthenticatorOptions
+  {
+    webAuthnVirtualAuthenticatorOptionsProtocol :: WebAuthnAuthenticatorProtocol,
+    -- | Defaults to ctap2_0. Ignored if |protocol| == u2f.
+    webAuthnVirtualAuthenticatorOptionsCtap2Version :: Maybe WebAuthnCtap2Version,
+    webAuthnVirtualAuthenticatorOptionsTransport :: WebAuthnAuthenticatorTransport,
+    -- | Defaults to false.
+    webAuthnVirtualAuthenticatorOptionsHasResidentKey :: Maybe Bool,
+    -- | Defaults to false.
+    webAuthnVirtualAuthenticatorOptionsHasUserVerification :: Maybe Bool,
+    -- | If set to true, the authenticator will support the largeBlob extension.
+    --   https://w3c.github.io/webauthn#largeBlob
+    --   Defaults to false.
+    webAuthnVirtualAuthenticatorOptionsHasLargeBlob :: Maybe Bool,
+    -- | If set to true, the authenticator will support the credBlob extension.
+    --   https://fidoalliance.org/specs/fido-v2.1-rd-20201208/fido-client-to-authenticator-protocol-v2.1-rd-20201208.html#sctn-credBlob-extension
+    --   Defaults to false.
+    webAuthnVirtualAuthenticatorOptionsHasCredBlob :: Maybe Bool,
+    -- | If set to true, the authenticator will support the minPinLength extension.
+    --   https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html#sctn-minpinlength-extension
+    --   Defaults to false.
+    webAuthnVirtualAuthenticatorOptionsHasMinPinLength :: Maybe Bool,
+    -- | If set to true, tests of user presence will succeed immediately.
+    --   Otherwise, they will not be resolved. Defaults to true.
+    webAuthnVirtualAuthenticatorOptionsAutomaticPresenceSimulation :: Maybe Bool,
+    -- | Sets whether User Verification succeeds or fails for an authenticator.
+    --   Defaults to false.
+    webAuthnVirtualAuthenticatorOptionsIsUserVerified :: Maybe Bool
+  }
+  deriving (Eq, Show)
+instance FromJSON WebAuthnVirtualAuthenticatorOptions where
+  parseJSON = A.withObject "WebAuthnVirtualAuthenticatorOptions" $ \o -> WebAuthnVirtualAuthenticatorOptions
+    <$> o A..: "protocol"
+    <*> o A..:? "ctap2Version"
+    <*> o A..: "transport"
+    <*> o A..:? "hasResidentKey"
+    <*> o A..:? "hasUserVerification"
+    <*> o A..:? "hasLargeBlob"
+    <*> o A..:? "hasCredBlob"
+    <*> o A..:? "hasMinPinLength"
+    <*> o A..:? "automaticPresenceSimulation"
+    <*> o A..:? "isUserVerified"
+instance ToJSON WebAuthnVirtualAuthenticatorOptions where
+  toJSON p = A.object $ catMaybes [
+    ("protocol" A..=) <$> Just (webAuthnVirtualAuthenticatorOptionsProtocol p),
+    ("ctap2Version" A..=) <$> (webAuthnVirtualAuthenticatorOptionsCtap2Version p),
+    ("transport" A..=) <$> Just (webAuthnVirtualAuthenticatorOptionsTransport p),
+    ("hasResidentKey" A..=) <$> (webAuthnVirtualAuthenticatorOptionsHasResidentKey p),
+    ("hasUserVerification" A..=) <$> (webAuthnVirtualAuthenticatorOptionsHasUserVerification p),
+    ("hasLargeBlob" A..=) <$> (webAuthnVirtualAuthenticatorOptionsHasLargeBlob p),
+    ("hasCredBlob" A..=) <$> (webAuthnVirtualAuthenticatorOptionsHasCredBlob p),
+    ("hasMinPinLength" A..=) <$> (webAuthnVirtualAuthenticatorOptionsHasMinPinLength p),
+    ("automaticPresenceSimulation" A..=) <$> (webAuthnVirtualAuthenticatorOptionsAutomaticPresenceSimulation p),
+    ("isUserVerified" A..=) <$> (webAuthnVirtualAuthenticatorOptionsIsUserVerified p)
+    ]
+
+-- | Type 'WebAuthn.Credential'.
+data WebAuthnCredential = WebAuthnCredential
+  {
+    webAuthnCredentialCredentialId :: T.Text,
+    webAuthnCredentialIsResidentCredential :: Bool,
+    -- | Relying Party ID the credential is scoped to. Must be set when adding a
+    --   credential.
+    webAuthnCredentialRpId :: Maybe T.Text,
+    -- | The ECDSA P-256 private key in PKCS#8 format. (Encoded as a base64 string when passed over JSON)
+    webAuthnCredentialPrivateKey :: T.Text,
+    -- | An opaque byte sequence with a maximum size of 64 bytes mapping the
+    --   credential to a specific user. (Encoded as a base64 string when passed over JSON)
+    webAuthnCredentialUserHandle :: Maybe T.Text,
+    -- | Signature counter. This is incremented by one for each successful
+    --   assertion.
+    --   See https://w3c.github.io/webauthn/#signature-counter
+    webAuthnCredentialSignCount :: Int,
+    -- | The large blob associated with the credential.
+    --   See https://w3c.github.io/webauthn/#sctn-large-blob-extension (Encoded as a base64 string when passed over JSON)
+    webAuthnCredentialLargeBlob :: Maybe T.Text
+  }
+  deriving (Eq, Show)
+instance FromJSON WebAuthnCredential where
+  parseJSON = A.withObject "WebAuthnCredential" $ \o -> WebAuthnCredential
+    <$> o A..: "credentialId"
+    <*> o A..: "isResidentCredential"
+    <*> o A..:? "rpId"
+    <*> o A..: "privateKey"
+    <*> o A..:? "userHandle"
+    <*> o A..: "signCount"
+    <*> o A..:? "largeBlob"
+instance ToJSON WebAuthnCredential where
+  toJSON p = A.object $ catMaybes [
+    ("credentialId" A..=) <$> Just (webAuthnCredentialCredentialId p),
+    ("isResidentCredential" A..=) <$> Just (webAuthnCredentialIsResidentCredential p),
+    ("rpId" A..=) <$> (webAuthnCredentialRpId p),
+    ("privateKey" A..=) <$> Just (webAuthnCredentialPrivateKey p),
+    ("userHandle" A..=) <$> (webAuthnCredentialUserHandle p),
+    ("signCount" A..=) <$> Just (webAuthnCredentialSignCount p),
+    ("largeBlob" A..=) <$> (webAuthnCredentialLargeBlob p)
+    ]
+
+-- | Enable the WebAuthn domain and start intercepting credential storage and
+--   retrieval with a virtual authenticator.
+
+-- | Parameters of the 'WebAuthn.enable' command.
+data PWebAuthnEnable = PWebAuthnEnable
+  {
+    -- | Whether to enable the WebAuthn user interface. Enabling the UI is
+    --   recommended for debugging and demo purposes, as it is closer to the real
+    --   experience. Disabling the UI is recommended for automated testing.
+    --   Supported at the embedder's discretion if UI is available.
+    --   Defaults to false.
+    pWebAuthnEnableEnableUI :: Maybe Bool
+  }
+  deriving (Eq, Show)
+pWebAuthnEnable
+  :: PWebAuthnEnable
+pWebAuthnEnable
+  = PWebAuthnEnable
+    Nothing
+instance ToJSON PWebAuthnEnable where
+  toJSON p = A.object $ catMaybes [
+    ("enableUI" A..=) <$> (pWebAuthnEnableEnableUI p)
+    ]
+instance Command PWebAuthnEnable where
+  type CommandResponse PWebAuthnEnable = ()
+  commandName _ = "WebAuthn.enable"
+  fromJSON = const . A.Success . const ()
+
+-- | Disable the WebAuthn domain.
+
+-- | Parameters of the 'WebAuthn.disable' command.
+data PWebAuthnDisable = PWebAuthnDisable
+  deriving (Eq, Show)
+pWebAuthnDisable
+  :: PWebAuthnDisable
+pWebAuthnDisable
+  = PWebAuthnDisable
+instance ToJSON PWebAuthnDisable where
+  toJSON _ = A.Null
+instance Command PWebAuthnDisable where
+  type CommandResponse PWebAuthnDisable = ()
+  commandName _ = "WebAuthn.disable"
+  fromJSON = const . A.Success . const ()
+
+-- | Creates and adds a virtual authenticator.
+
+-- | Parameters of the 'WebAuthn.addVirtualAuthenticator' command.
+data PWebAuthnAddVirtualAuthenticator = PWebAuthnAddVirtualAuthenticator
+  {
+    pWebAuthnAddVirtualAuthenticatorOptions :: WebAuthnVirtualAuthenticatorOptions
+  }
+  deriving (Eq, Show)
+pWebAuthnAddVirtualAuthenticator
+  :: WebAuthnVirtualAuthenticatorOptions
+  -> PWebAuthnAddVirtualAuthenticator
+pWebAuthnAddVirtualAuthenticator
+  arg_pWebAuthnAddVirtualAuthenticatorOptions
+  = PWebAuthnAddVirtualAuthenticator
+    arg_pWebAuthnAddVirtualAuthenticatorOptions
+instance ToJSON PWebAuthnAddVirtualAuthenticator where
+  toJSON p = A.object $ catMaybes [
+    ("options" A..=) <$> Just (pWebAuthnAddVirtualAuthenticatorOptions p)
+    ]
+data WebAuthnAddVirtualAuthenticator = WebAuthnAddVirtualAuthenticator
+  {
+    webAuthnAddVirtualAuthenticatorAuthenticatorId :: WebAuthnAuthenticatorId
+  }
+  deriving (Eq, Show)
+instance FromJSON WebAuthnAddVirtualAuthenticator where
+  parseJSON = A.withObject "WebAuthnAddVirtualAuthenticator" $ \o -> WebAuthnAddVirtualAuthenticator
+    <$> o A..: "authenticatorId"
+instance Command PWebAuthnAddVirtualAuthenticator where
+  type CommandResponse PWebAuthnAddVirtualAuthenticator = WebAuthnAddVirtualAuthenticator
+  commandName _ = "WebAuthn.addVirtualAuthenticator"
+
+-- | Removes the given authenticator.
+
+-- | Parameters of the 'WebAuthn.removeVirtualAuthenticator' command.
+data PWebAuthnRemoveVirtualAuthenticator = PWebAuthnRemoveVirtualAuthenticator
+  {
+    pWebAuthnRemoveVirtualAuthenticatorAuthenticatorId :: WebAuthnAuthenticatorId
+  }
+  deriving (Eq, Show)
+pWebAuthnRemoveVirtualAuthenticator
+  :: WebAuthnAuthenticatorId
+  -> PWebAuthnRemoveVirtualAuthenticator
+pWebAuthnRemoveVirtualAuthenticator
+  arg_pWebAuthnRemoveVirtualAuthenticatorAuthenticatorId
+  = PWebAuthnRemoveVirtualAuthenticator
+    arg_pWebAuthnRemoveVirtualAuthenticatorAuthenticatorId
+instance ToJSON PWebAuthnRemoveVirtualAuthenticator where
+  toJSON p = A.object $ catMaybes [
+    ("authenticatorId" A..=) <$> Just (pWebAuthnRemoveVirtualAuthenticatorAuthenticatorId p)
+    ]
+instance Command PWebAuthnRemoveVirtualAuthenticator where
+  type CommandResponse PWebAuthnRemoveVirtualAuthenticator = ()
+  commandName _ = "WebAuthn.removeVirtualAuthenticator"
+  fromJSON = const . A.Success . const ()
+
+-- | Adds the credential to the specified authenticator.
+
+-- | Parameters of the 'WebAuthn.addCredential' command.
+data PWebAuthnAddCredential = PWebAuthnAddCredential
+  {
+    pWebAuthnAddCredentialAuthenticatorId :: WebAuthnAuthenticatorId,
+    pWebAuthnAddCredentialCredential :: WebAuthnCredential
+  }
+  deriving (Eq, Show)
+pWebAuthnAddCredential
+  :: WebAuthnAuthenticatorId
+  -> WebAuthnCredential
+  -> PWebAuthnAddCredential
+pWebAuthnAddCredential
+  arg_pWebAuthnAddCredentialAuthenticatorId
+  arg_pWebAuthnAddCredentialCredential
+  = PWebAuthnAddCredential
+    arg_pWebAuthnAddCredentialAuthenticatorId
+    arg_pWebAuthnAddCredentialCredential
+instance ToJSON PWebAuthnAddCredential where
+  toJSON p = A.object $ catMaybes [
+    ("authenticatorId" A..=) <$> Just (pWebAuthnAddCredentialAuthenticatorId p),
+    ("credential" A..=) <$> Just (pWebAuthnAddCredentialCredential p)
+    ]
+instance Command PWebAuthnAddCredential where
+  type CommandResponse PWebAuthnAddCredential = ()
+  commandName _ = "WebAuthn.addCredential"
+  fromJSON = const . A.Success . const ()
+
+-- | Returns a single credential stored in the given virtual authenticator that
+--   matches the credential ID.
+
+-- | Parameters of the 'WebAuthn.getCredential' command.
+data PWebAuthnGetCredential = PWebAuthnGetCredential
+  {
+    pWebAuthnGetCredentialAuthenticatorId :: WebAuthnAuthenticatorId,
+    pWebAuthnGetCredentialCredentialId :: T.Text
+  }
+  deriving (Eq, Show)
+pWebAuthnGetCredential
+  :: WebAuthnAuthenticatorId
+  -> T.Text
+  -> PWebAuthnGetCredential
+pWebAuthnGetCredential
+  arg_pWebAuthnGetCredentialAuthenticatorId
+  arg_pWebAuthnGetCredentialCredentialId
+  = PWebAuthnGetCredential
+    arg_pWebAuthnGetCredentialAuthenticatorId
+    arg_pWebAuthnGetCredentialCredentialId
+instance ToJSON PWebAuthnGetCredential where
+  toJSON p = A.object $ catMaybes [
+    ("authenticatorId" A..=) <$> Just (pWebAuthnGetCredentialAuthenticatorId p),
+    ("credentialId" A..=) <$> Just (pWebAuthnGetCredentialCredentialId p)
+    ]
+data WebAuthnGetCredential = WebAuthnGetCredential
+  {
+    webAuthnGetCredentialCredential :: WebAuthnCredential
+  }
+  deriving (Eq, Show)
+instance FromJSON WebAuthnGetCredential where
+  parseJSON = A.withObject "WebAuthnGetCredential" $ \o -> WebAuthnGetCredential
+    <$> o A..: "credential"
+instance Command PWebAuthnGetCredential where
+  type CommandResponse PWebAuthnGetCredential = WebAuthnGetCredential
+  commandName _ = "WebAuthn.getCredential"
+
+-- | Returns all the credentials stored in the given virtual authenticator.
+
+-- | Parameters of the 'WebAuthn.getCredentials' command.
+data PWebAuthnGetCredentials = PWebAuthnGetCredentials
+  {
+    pWebAuthnGetCredentialsAuthenticatorId :: WebAuthnAuthenticatorId
+  }
+  deriving (Eq, Show)
+pWebAuthnGetCredentials
+  :: WebAuthnAuthenticatorId
+  -> PWebAuthnGetCredentials
+pWebAuthnGetCredentials
+  arg_pWebAuthnGetCredentialsAuthenticatorId
+  = PWebAuthnGetCredentials
+    arg_pWebAuthnGetCredentialsAuthenticatorId
+instance ToJSON PWebAuthnGetCredentials where
+  toJSON p = A.object $ catMaybes [
+    ("authenticatorId" A..=) <$> Just (pWebAuthnGetCredentialsAuthenticatorId p)
+    ]
+data WebAuthnGetCredentials = WebAuthnGetCredentials
+  {
+    webAuthnGetCredentialsCredentials :: [WebAuthnCredential]
+  }
+  deriving (Eq, Show)
+instance FromJSON WebAuthnGetCredentials where
+  parseJSON = A.withObject "WebAuthnGetCredentials" $ \o -> WebAuthnGetCredentials
+    <$> o A..: "credentials"
+instance Command PWebAuthnGetCredentials where
+  type CommandResponse PWebAuthnGetCredentials = WebAuthnGetCredentials
+  commandName _ = "WebAuthn.getCredentials"
+
+-- | Removes a credential from the authenticator.
+
+-- | Parameters of the 'WebAuthn.removeCredential' command.
+data PWebAuthnRemoveCredential = PWebAuthnRemoveCredential
+  {
+    pWebAuthnRemoveCredentialAuthenticatorId :: WebAuthnAuthenticatorId,
+    pWebAuthnRemoveCredentialCredentialId :: T.Text
+  }
+  deriving (Eq, Show)
+pWebAuthnRemoveCredential
+  :: WebAuthnAuthenticatorId
+  -> T.Text
+  -> PWebAuthnRemoveCredential
+pWebAuthnRemoveCredential
+  arg_pWebAuthnRemoveCredentialAuthenticatorId
+  arg_pWebAuthnRemoveCredentialCredentialId
+  = PWebAuthnRemoveCredential
+    arg_pWebAuthnRemoveCredentialAuthenticatorId
+    arg_pWebAuthnRemoveCredentialCredentialId
+instance ToJSON PWebAuthnRemoveCredential where
+  toJSON p = A.object $ catMaybes [
+    ("authenticatorId" A..=) <$> Just (pWebAuthnRemoveCredentialAuthenticatorId p),
+    ("credentialId" A..=) <$> Just (pWebAuthnRemoveCredentialCredentialId p)
+    ]
+instance Command PWebAuthnRemoveCredential where
+  type CommandResponse PWebAuthnRemoveCredential = ()
+  commandName _ = "WebAuthn.removeCredential"
+  fromJSON = const . A.Success . const ()
+
+-- | Clears all the credentials from the specified device.
+
+-- | Parameters of the 'WebAuthn.clearCredentials' command.
+data PWebAuthnClearCredentials = PWebAuthnClearCredentials
+  {
+    pWebAuthnClearCredentialsAuthenticatorId :: WebAuthnAuthenticatorId
+  }
+  deriving (Eq, Show)
+pWebAuthnClearCredentials
+  :: WebAuthnAuthenticatorId
+  -> PWebAuthnClearCredentials
+pWebAuthnClearCredentials
+  arg_pWebAuthnClearCredentialsAuthenticatorId
+  = PWebAuthnClearCredentials
+    arg_pWebAuthnClearCredentialsAuthenticatorId
+instance ToJSON PWebAuthnClearCredentials where
+  toJSON p = A.object $ catMaybes [
+    ("authenticatorId" A..=) <$> Just (pWebAuthnClearCredentialsAuthenticatorId p)
+    ]
+instance Command PWebAuthnClearCredentials where
+  type CommandResponse PWebAuthnClearCredentials = ()
+  commandName _ = "WebAuthn.clearCredentials"
+  fromJSON = const . A.Success . const ()
+
+-- | Sets whether User Verification succeeds or fails for an authenticator.
+--   The default is true.
+
+-- | Parameters of the 'WebAuthn.setUserVerified' command.
+data PWebAuthnSetUserVerified = PWebAuthnSetUserVerified
+  {
+    pWebAuthnSetUserVerifiedAuthenticatorId :: WebAuthnAuthenticatorId,
+    pWebAuthnSetUserVerifiedIsUserVerified :: Bool
+  }
+  deriving (Eq, Show)
+pWebAuthnSetUserVerified
+  :: WebAuthnAuthenticatorId
+  -> Bool
+  -> PWebAuthnSetUserVerified
+pWebAuthnSetUserVerified
+  arg_pWebAuthnSetUserVerifiedAuthenticatorId
+  arg_pWebAuthnSetUserVerifiedIsUserVerified
+  = PWebAuthnSetUserVerified
+    arg_pWebAuthnSetUserVerifiedAuthenticatorId
+    arg_pWebAuthnSetUserVerifiedIsUserVerified
+instance ToJSON PWebAuthnSetUserVerified where
+  toJSON p = A.object $ catMaybes [
+    ("authenticatorId" A..=) <$> Just (pWebAuthnSetUserVerifiedAuthenticatorId p),
+    ("isUserVerified" A..=) <$> Just (pWebAuthnSetUserVerifiedIsUserVerified p)
+    ]
+instance Command PWebAuthnSetUserVerified where
+  type CommandResponse PWebAuthnSetUserVerified = ()
+  commandName _ = "WebAuthn.setUserVerified"
+  fromJSON = const . A.Success . const ()
+
+-- | Sets whether tests of user presence will succeed immediately (if true) or fail to resolve (if false) for an authenticator.
+--   The default is true.
+
+-- | Parameters of the 'WebAuthn.setAutomaticPresenceSimulation' command.
+data PWebAuthnSetAutomaticPresenceSimulation = PWebAuthnSetAutomaticPresenceSimulation
+  {
+    pWebAuthnSetAutomaticPresenceSimulationAuthenticatorId :: WebAuthnAuthenticatorId,
+    pWebAuthnSetAutomaticPresenceSimulationEnabled :: Bool
+  }
+  deriving (Eq, Show)
+pWebAuthnSetAutomaticPresenceSimulation
+  :: WebAuthnAuthenticatorId
+  -> Bool
+  -> PWebAuthnSetAutomaticPresenceSimulation
+pWebAuthnSetAutomaticPresenceSimulation
+  arg_pWebAuthnSetAutomaticPresenceSimulationAuthenticatorId
+  arg_pWebAuthnSetAutomaticPresenceSimulationEnabled
+  = PWebAuthnSetAutomaticPresenceSimulation
+    arg_pWebAuthnSetAutomaticPresenceSimulationAuthenticatorId
+    arg_pWebAuthnSetAutomaticPresenceSimulationEnabled
+instance ToJSON PWebAuthnSetAutomaticPresenceSimulation where
+  toJSON p = A.object $ catMaybes [
+    ("authenticatorId" A..=) <$> Just (pWebAuthnSetAutomaticPresenceSimulationAuthenticatorId p),
+    ("enabled" A..=) <$> Just (pWebAuthnSetAutomaticPresenceSimulationEnabled p)
+    ]
+instance Command PWebAuthnSetAutomaticPresenceSimulation where
+  type CommandResponse PWebAuthnSetAutomaticPresenceSimulation = ()
+  commandName _ = "WebAuthn.setAutomaticPresenceSimulation"
+  fromJSON = const . A.Success . const ()
+
diff --git a/src/CDP/Endpoints.hs b/src/CDP/Endpoints.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Endpoints.hs
@@ -0,0 +1,157 @@
+{-# LANGUAGE OverloadedStrings    #-}
+{-# LANGUAGE TypeFamilies         #-}
+{-# LANGUAGE ScopedTypeVariables  #-}
+{-# LANGUAGE GADTs                #-}
+{-# LANGUAGE RankNTypes           #-}
+
+module CDP.Endpoints where
+
+import Data.Maybe
+import Data.List
+import Data.Proxy
+import qualified Network.URI          as Uri
+import qualified Network.HTTP.Simple  as Http
+import qualified Data.Aeson           as A
+import qualified Data.ByteString.Lazy as BS
+import Data.Aeson (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Text as T
+import Control.Exception
+
+import CDP.Internal.Utils
+import qualified CDP.Definition
+
+type URL      = T.Text
+type TargetId = T.Text
+
+data EPBrowserVersion   = EPBrowserVersion
+data EPAllTargets       = EPAllTargets
+data EPCurrentProtocol  = EPCurrentProtocol
+data EPOpenNewTab       = EPOpenNewTab       { unOpenNewTab :: URL }
+data EPActivateTarget   = EPActivateTarget   { unActivateTarget :: TargetId }
+data EPCloseTarget      = EPCloseTarget      { unCloseTarget :: TargetId }
+data EPFrontend         = EPFrontend
+
+data SomeEndpoint where
+    SomeEndpoint :: Endpoint ep => ep -> SomeEndpoint
+
+fromSomeEndpoint :: (forall ep. Endpoint ep => ep -> r) -> SomeEndpoint -> r
+fromSomeEndpoint f (SomeEndpoint ep) = f ep
+
+-- | Sends a request with the given parameters to the corresponding endpoint
+endpoint :: Endpoint ep => Config -> ep -> IO (EndpointResponse ep)
+endpoint = getEndpoint . hostPort
+
+-- | Creates a session with a new tab
+connectToTab :: Config -> URL -> IO TargetInfo
+connectToTab cfg url = do
+        targetInfo <- endpoint cfg $ EPOpenNewTab url
+        endpoint cfg $ EPActivateTarget $ tiId targetInfo
+        pure targetInfo
+
+class Endpoint ep where
+    type EndpointResponse ep :: *
+    getEndpoint :: (String, Int) -> ep -> IO (EndpointResponse ep)
+    epDecode :: Proxy ep -> BS.ByteString -> Either String (EndpointResponse ep)
+
+instance Endpoint EPBrowserVersion where
+    type EndpointResponse EPBrowserVersion = BrowserVersion
+    getEndpoint hostPort _ = performRequest (Proxy :: Proxy EPBrowserVersion) $
+        getRequest hostPort ["json", "version"] Nothing
+    epDecode = const A.eitherDecode
+
+instance Endpoint EPAllTargets where
+    type EndpointResponse EPAllTargets = [TargetInfo]
+    getEndpoint hostPort _ = performRequest (Proxy :: Proxy EPAllTargets) $ 
+        getRequest hostPort ["json", "list"] Nothing
+    epDecode = const A.eitherDecode
+
+instance Endpoint EPCurrentProtocol where
+    type EndpointResponse EPCurrentProtocol = CDP.Definition.TopLevel
+    getEndpoint hostPort _ = performRequest (Proxy :: Proxy EPCurrentProtocol) $
+        getRequest hostPort ["json", "protocol"] Nothing
+    epDecode = const A.eitherDecode
+
+instance Endpoint EPOpenNewTab where
+    type EndpointResponse EPOpenNewTab = TargetInfo
+    getEndpoint hostPort (EPOpenNewTab url) = performRequest (Proxy :: Proxy EPOpenNewTab) $
+        getRequest hostPort ["json", "new"] (Just url)
+    epDecode = const A.eitherDecode 
+
+instance Endpoint EPActivateTarget where
+    type EndpointResponse EPActivateTarget = ()
+    getEndpoint hostPort (EPActivateTarget id) = performRequest (Proxy :: Proxy EPActivateTarget) $
+        getRequest hostPort ["json", "activate", id] Nothing
+    epDecode = const . const $ Right ()
+
+instance Endpoint EPCloseTarget where
+    type EndpointResponse EPCloseTarget = ()
+    getEndpoint hostPort (EPCloseTarget id) = performRequest (Proxy :: Proxy EPCloseTarget) $
+        getRequest hostPort ["json", "close", id] Nothing
+    epDecode = const . const $ Right ()
+
+instance Endpoint EPFrontend where
+    type EndpointResponse EPFrontend = BS.ByteString
+    getEndpoint hostPort EPFrontend = performRequest (Proxy :: Proxy EPFrontend) $
+        getRequest hostPort ["devtools", "inspector.html"] Nothing
+    epDecode = const Right
+
+data BrowserVersion = BrowserVersion
+    { bvBrowser              :: T.Text
+    , bvProtocolVersion      :: T.Text
+    , bvUserAgent            :: T.Text
+    , bvV8Version            :: T.Text
+    , bvVebKitVersion        :: T.Text
+    , bvWebSocketDebuggerUrl :: T.Text
+    } deriving (Show, Eq)
+instance FromJSON BrowserVersion where
+    parseJSON = A.withObject "BrowserVersion" $ \v ->
+        BrowserVersion <$> v .: "Browser"
+            <*> v .: "Protocol-Version"
+            <*> v .: "User-Agent"
+            <*> v .: "V8-Version"
+            <*> v .: "WebKit-Version"
+            <*> v .: "webSocketDebuggerUrl"
+
+data TargetInfo = TargetInfo
+    { tiDescription          :: T.Text
+    , tiDevtoolsFrontendUrl  :: T.Text
+    , tiId                   :: T.Text
+    , tiTitle                :: T.Text
+    , tiType                 :: T.Text
+    , tiUrl                  :: T.Text
+    , tiWebSocketDebuggerUrl :: T.Text
+    } deriving Show
+instance FromJSON TargetInfo where
+    parseJSON = A.withObject "TargetInfo" $ \v ->
+        TargetInfo <$> v .: "description"
+            <*> v .: "devtoolsFrontendUrl"
+            <*> v .: "id"
+            <*> v .: "title"
+            <*> v .: "type"
+            <*> v .: "url"
+            <*> v .: "webSocketDebuggerUrl"
+
+browserAddress :: (String, Int) -> IO (String, Int, String)
+browserAddress hostPort = fromMaybe (throw . ERRParse $ "invalid URI when connecting to browser") . 
+    parseUri . T.unpack . bvWebSocketDebuggerUrl <$> getEndpoint hostPort EPBrowserVersion
+
+getRequest :: (String, Int) -> [T.Text] -> Maybe T.Text -> Http.Request
+getRequest (host, port) path mbParam = Http.parseRequest_ . T.unpack $ r
+  where
+    r = mconcat ["GET ", T.pack host, ":", T.pack (show port), "/", T.intercalate "/" path
+                , maybe "" ("?" <>) mbParam 
+                ]
+
+performRequest :: Endpoint ep => Proxy ep -> Http.Request -> IO (EndpointResponse ep)
+performRequest p req = do
+    body <- Http.getResponseBody <$> Http.httpLBS req
+    either (throwIO . ERRParse) pure $ epDecode p body
+
+parseUri :: String -> Maybe (String, Int, String)
+parseUri uri = do
+    u    <- Uri.parseURI $ uri
+    auth <- Uri.uriAuthority u
+    let port = case Uri.uriPort auth of
+            (':':str)   -> read str
+            _           -> 80
+    pure (Uri.uriRegName auth, port, Uri.uriPath u)
diff --git a/src/CDP/Internal/Utils.hs b/src/CDP/Internal/Utils.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Internal/Utils.hs
@@ -0,0 +1,133 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections, GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE GADTs                  #-}
+{-# LANGUAGE ScopedTypeVariables    #-}
+{-# LANGUAGE TypeFamilies           #-}
+{-# LANGUAGE AllowAmbiguousTypes    #-}
+
+module CDP.Internal.Utils where
+
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe
+import Data.Foldable (for_)
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import System.Random
+import Control.Applicative
+import Data.Default
+import Control.Exception
+import System.Timeout
+import Data.Char
+import qualified System.IO as IO
+import qualified Data.IORef as IORef
+
+newtype CommandId = CommandId { unCommandId :: Int }
+    deriving (Eq, Ord, Show, FromJSON, ToJSON)
+
+type CommandResponseBuffer =
+    Map.Map CommandId (MVar (Either ProtocolError A.Value))
+
+type SessionId = T.Text
+
+data Subscriptions = Subscriptions
+    { subscriptionsHandlers :: Map.Map (String, Maybe SessionId) (Map.Map Int (A.Value -> IO ()))
+    , subscriptionsNextId   :: Int
+    }
+ 
+data Handle = Handle
+    { config           :: Config
+    , commandNextId    :: MVar CommandId
+    , subscriptions    :: IORef.IORef Subscriptions
+    , commandBuffer    :: IORef.IORef CommandResponseBuffer
+    , conn             :: WS.Connection
+    , listenThread     :: ThreadId
+    , responseBuffer   :: MVar [(String, BS.ByteString)]
+    }
+
+data Config = Config
+    { hostPort           :: (String, Int)
+      -- | WebSocket path to connect to. 
+      --   If Nothing, the initial connection is made to the browser.
+    , path               :: Maybe String 
+    , doLogResponses     :: Bool
+      -- | Number of microseconds to wait for a command response.
+      --   Waits forever if Nothing.
+    , commandTimeout     :: Maybe Int
+    } deriving Show
+instance Default Config where
+    def = Config{..}
+      where
+        hostPort       = ("http://127.0.0.1", 9222)
+        path           = def
+        doLogResponses = False
+        commandTimeout = def
+
+class FromJSON a => Event a where
+    eventName :: Proxy a -> String
+
+class (ToJSON cmd, FromJSON (CommandResponse cmd)) => Command cmd where
+    type CommandResponse cmd :: *
+    commandName :: Proxy cmd -> String
+    fromJSON :: Proxy cmd -> A.Value -> A.Result (CommandResponse cmd)
+    fromJSON = const A.fromJSON
+
+data ProtocolError = 
+      PEParse          String      -- ^ Invalid JSON was received by the server. An error occurred on the server while parsing the JSON text
+    | PEInvalidRequest String      -- ^ The JSON sent is not a valid Request object
+    | PEMethodNotFound String      -- ^ The method does not exist / is not available
+    | PEInvalidParams  String      -- ^ Invalid method parameter (s)
+    | PEInternalError  String      -- ^ Internal JSON-RPC error
+    | PEServerError    String      -- ^ Server error
+    | PEOther          String      -- ^ An uncategorized error
+    deriving Eq
+instance Exception ProtocolError
+instance Show ProtocolError where
+    show  (PEParse msg)           = unlines ["Server parsing protocol error:", msg] 
+    show (PEInvalidRequest msg)   = unlines ["Invalid request protocol error:", msg]
+    show (PEMethodNotFound msg)   = unlines ["Method not found protocol error:", msg]
+    show (PEInvalidParams msg)    = unlines ["Invalid params protocol error:", msg]
+    show (PEInternalError msg)    = unlines ["Internal protocol error:", msg]
+    show (PEServerError msg)      = unlines ["Server protocol error:", msg]
+    show (PEOther msg)            = unlines ["Other protocol error:", msg]
+instance FromJSON ProtocolError where
+    parseJSON = A.withObject "ProtocolError" $ \obj -> do
+        code <- obj .: "code"
+        msg  <- obj .: "message"
+        pure $ case (code :: Double) of
+            -32700 -> PEParse          msg
+            -32600 -> PEInvalidRequest msg
+            -32601 -> PEMethodNotFound msg
+            -32602 -> PEInvalidParams  msg
+            -32603 -> PEInternalError  msg
+            _      -> if code > -32099 && code < -32000 then PEServerError msg else PEOther msg
+
+data Error = 
+    ERRNoResponse
+    | ERRParse String
+    | ERRProtocol ProtocolError
+    deriving Eq
+instance Exception Error
+instance Show Error where
+    show ERRNoResponse      = "no response received from the browser"
+    show (ERRParse msg)     = unlines ["error in parsing a message received from the browser:", msg]
+    show (ERRProtocol pe)   = unlines ["error encountered by the browser:", show pe] 
+
+uncapitalizeFirst :: String -> String
+uncapitalizeFirst []     = []
+uncapitalizeFirst (x:xs) = toLower x : xs
diff --git a/src/CDP/Runtime.hs b/src/CDP/Runtime.hs
new file mode 100644
--- /dev/null
+++ b/src/CDP/Runtime.hs
@@ -0,0 +1,264 @@
+{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections, GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE GADTs                  #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE ScopedTypeVariables    #-}
+{-# LANGUAGE TypeFamilies           #-}
+{-# LANGUAGE RankNTypes    #-}
+
+module CDP.Runtime 
+    ( module CDP.Runtime
+    , module CDP.Endpoints
+    , module CDP.Internal.Utils
+    ) where
+
+import           Control.Applicative  ((<$>))
+import           Control.Monad
+import           Control.Monad.Loops
+import           Control.Monad.Trans  (liftIO)
+import qualified Data.Map             as M
+import           Data.Maybe
+import Data.Foldable (for_)
+import Data.Functor.Identity
+import Data.String
+import qualified Data.Text as T
+import qualified Data.List as List
+import qualified Data.Text.IO         as TI
+import qualified Data.Vector          as V
+import Data.Aeson.Types (Parser(..))
+import           Data.Aeson           (FromJSON (..), ToJSON (..), (.:), (.:?), (.=), (.!=), (.:!))
+import qualified Data.Aeson           as A
+import qualified Network.WebSockets as WS
+import Control.Concurrent
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.Map as Map
+import Data.Proxy
+import Control.Applicative
+import Data.Default
+import Control.Exception
+import System.Timeout
+import Data.Char
+import qualified System.IO as IO
+import qualified Data.IORef as IORef
+import qualified Network.HTTP.Simple  as Http
+
+import CDP.Internal.Utils
+import CDP.Endpoints
+
+type ClientApp b  = Handle -> IO b
+
+-- | Runs a client application. 
+-- By default, the connection is made to the browser. See the `path` field in `Config`.
+-- The connection is closed once the IO action completes
+runClient :: forall b. Config -> ClientApp b -> IO b
+runClient config app = do
+    commandNextId  <- newMVar (CommandId 0)
+    subscriptions  <- IORef.newIORef $ Subscriptions Map.empty 0
+    commandBuffer  <- IORef.newIORef Map.empty
+    responseBuffer <- newMVar []
+
+    (host, port, path) <- do
+        let hp@(host,port) = hostPort config
+        maybe (browserAddress hp) (\path -> pure (host, port, path)) $ path config
+    WS.runClient host port path $ \conn -> do
+        let listen = forkIO $ do
+                listenThread <- myThreadId
+                forever $ do
+                    bs <- WS.fromDataMessage <$> WS.receiveDataMessage conn
+                    case A.decode bs of
+                        Nothing -> IO.hPutStrLn IO.stderr $
+                            "Could not parse message: " ++ show bs
+                        Just im | Just method <- imMethod im -> do
+                            IO.hPutStrLn IO.stderr $ "dispatching with method " ++ show method
+                            dispatchEvent Handle{..} (imSessionId im) method (imParams im)
+                        Just im | Just id' <- imId im ->
+                            dispatchCommandResponse Handle {..} id'
+                            (imError im) (imResult im)
+          
+        bracket listen killThread (\listenThread -> app Handle{..})
+
+-- | A message from the browser.  We don't know yet if this is a command
+-- response or an event
+data IncomingMessage = IncomingMessage
+    { imMethod    :: Maybe String
+    , imParams    :: Maybe A.Value
+    , imSessionId :: Maybe SessionId
+    , imId        :: Maybe CommandId
+    , imError     :: Maybe ProtocolError
+    , imResult    :: Maybe A.Value
+    }
+
+instance FromJSON IncomingMessage where
+    parseJSON = A.withObject "IncomingMessage" $ \obj -> IncomingMessage
+        <$> obj A..:? "method"
+        <*> obj A..:? "params"
+        <*> obj A..:? "sessionId"
+        <*> obj A..:? "id"
+        <*> obj A..:? "error"
+        <*> obj A..:? "result"
+
+dispatchCommandResponse
+    :: Handle -> CommandId -> Maybe ProtocolError -> Maybe A.Value -> IO ()
+dispatchCommandResponse handle commandId mbErr mbVal = do
+    mbMVar <- IORef.atomicModifyIORef' (commandBuffer handle) $ \buffer ->
+        case M.lookup commandId buffer of
+            Nothing -> (buffer, Nothing)
+            Just mv -> (Map.delete commandId buffer, Just mv)
+    case mbMVar of
+        Nothing -> pure ()
+        Just mv -> putMVar mv $ case mbErr of
+            Just err -> Left err
+            Nothing -> case mbVal of
+                Just val -> Right val
+                Nothing  -> Right A.Null
+
+dispatchEvent :: Handle -> Maybe SessionId -> String -> Maybe A.Value -> IO ()
+dispatchEvent handle mbSessionId method mbParams = do
+    byMethod <- subscriptionsHandlers <$> IORef.readIORef (subscriptions handle)
+    case Map.lookup (method, mbSessionId) byMethod of
+        Nothing -> IO.hPutStrLn IO.stderr $ "No handler for " ++ show method ++ maybe "" ((", " <>) . show) mbSessionId
+        Just byId -> case mbParams of
+            Nothing -> IO.hPutStrLn IO.stderr $ "No params for " ++ show method
+            Just params -> do
+                IO.hPutStrLn IO.stderr $ "Calling handler for " ++ show method
+                for_ byId ($ params)
+
+data Subscription = Subscription
+    { subscriptionEventName :: String
+    , subscriptionSessionId :: Maybe SessionId
+    , subscriptionId        :: Int
+    }
+
+-- | Subscribes to an event
+subscribe :: forall a. Event a => Handle -> (a -> IO ()) -> IO Subscription
+subscribe handle handler = subscribe_ handle Nothing handler
+
+-- | Subscribes to an event for a given session
+subscribeForSession :: forall a. Event a => Handle -> SessionId -> (a -> IO ()) -> IO Subscription
+subscribeForSession handle sessionId handler = subscribe_ handle (Just sessionId) handler
+
+subscribe_ :: forall a. Event a => Handle -> Maybe SessionId -> (a -> IO ()) -> IO Subscription
+subscribe_ handle mbSessionId handler1 = do
+    id' <- IORef.atomicModifyIORef' (subscriptions handle) $ \s ->
+        let id' = subscriptionsNextId s in
+        ( s { subscriptionsNextId   = id' + 1
+            , subscriptionsHandlers = Map.insertWith
+                Map.union
+                (ename, mbSessionId)
+                (Map.singleton id' handler2)
+                (subscriptionsHandlers s)
+            }
+        , id'
+        )
+
+    pure $ Subscription ename mbSessionId id'
+  where
+    ename = eventName (Proxy :: Proxy a)
+
+    handler2 :: A.Value -> IO ()
+    handler2 val = case A.fromJSON val :: A.Result a of
+        A.Error   err -> do
+            IO.hPutStrLn IO.stderr $ "Error parsing JSON: " ++ err
+            IO.hPutStrLn IO.stderr $ "Value: " ++ show val
+        A.Success x   -> handler1 x
+
+-- | Unsubscribes to an event
+unsubscribe :: Handle -> Subscription -> IO ()
+unsubscribe handle (Subscription ename mbSessionId id') =
+    IORef.atomicModifyIORef' (subscriptions handle) $ \s ->
+        ( s { subscriptionsHandlers =
+                Map.adjust (Map.delete id') (ename, mbSessionId) (subscriptionsHandlers s)
+            }
+        , ()
+        )
+
+data Promise a where
+    Promise :: MVar tmp -> (tmp -> Either Error a) -> Promise a
+
+-- | Resolves a promise to its value 
+readPromise :: Promise a -> IO a
+readPromise (Promise mv f) = do
+    x <- readMVar mv
+    either throwIO pure $ f x
+
+nextCommandId :: Handle -> IO CommandId
+nextCommandId handle = modifyMVar (commandNextId handle) (\x -> pure (CommandId . (+1) . unCommandId $ x, x))
+
+data CommandObj a = CommandObj
+    { coSessionId :: Maybe SessionId
+    , coId        :: CommandId
+    , coMethod    :: String
+    , coParams    :: a
+    } deriving Show
+
+instance (ToJSON a) => ToJSON (CommandObj a) where
+    toJSON cmd = A.object . concat $
+        [ maybe [] (\sid -> [ "sessionId" .= sid ]) $ coSessionId cmd
+        , [ "id"     .= coId cmd ]
+        , [ "method" .= coMethod cmd ]
+        , case toJSON (coParams cmd) of
+            A.Null -> []
+            params -> [ "params" .= params ]
+        ]
+
+-- | Sends a command to the browser and waits until a response is received,
+--   for the timeout duration configured
+sendCommandWait
+    :: Command cmd
+    => Handle -> cmd -> IO (CommandResponse cmd)
+sendCommandWait handle params = sendCommandWait_ handle Nothing params
+
+-- | Sends a command to the browser for a given session
+--   and waits until a response is received, for the timeout duration configured
+sendCommandForSessionWait
+    :: Command cmd
+    => Handle -> SessionId -> cmd -> IO (CommandResponse cmd)
+sendCommandForSessionWait handle sessionId params = sendCommandWait_ handle (Just sessionId) params
+
+sendCommandWait_
+    :: Command cmd
+    => Handle -> Maybe SessionId -> cmd -> IO (CommandResponse cmd)
+sendCommandWait_ handle mbSessionId params = do
+    promise <- sendCommand handle params
+    let r = readPromise promise
+    mbRes <- maybe (fmap Just r) (flip timeout r) (commandTimeout . config $ handle)
+    maybe (throwIO ERRNoResponse) pure mbRes
+  where
+    proxy = Proxy :: Proxy cmd
+
+-- | Sends a command to the browser
+sendCommand
+    :: forall cmd. Command cmd
+    => Handle -> cmd -> IO (Promise (CommandResponse cmd))
+sendCommand handle params = sendCommand_ handle Nothing params
+
+-- | Sends a command to the browser for a given session
+sendCommandForSession
+    :: forall cmd. Command cmd
+    => Handle -> SessionId -> cmd -> IO (Promise (CommandResponse cmd))
+sendCommandForSession handle sessionId params = sendCommand_ handle (Just sessionId) params
+
+sendCommand_
+    :: forall cmd. Command cmd
+    => Handle -> Maybe SessionId -> cmd -> IO (Promise (CommandResponse cmd))
+sendCommand_ handle mbSessionId params = do
+    id <- nextCommandId handle
+    let co = CommandObj mbSessionId id (commandName proxy) params
+    mv <- newEmptyMVar
+    IORef.atomicModifyIORef' (commandBuffer handle) $ \buffer ->
+        (M.insert id mv buffer, ())
+    WS.sendTextData (conn handle) . A.encode $ co
+    pure $ Promise mv $ \case
+        Left err -> Left $ ERRProtocol err
+        Right v  -> case fromJSON proxy v of
+            A.Error   err -> Left $ ERRParse err
+            A.Success x   -> Right x
+  where
+    proxy = Proxy :: Proxy cmd
+
+data SomeCommand where
+    SomeCommand :: Command cmd => cmd -> SomeCommand
+
+fromSomeCommand :: (forall cmd. Command cmd => cmd -> r) -> SomeCommand -> r
+fromSomeCommand f (SomeCommand c) = f c
diff --git a/test/Main.hs b/test/Main.hs
new file mode 100644
--- /dev/null
+++ b/test/Main.hs
@@ -0,0 +1,93 @@
+{-# LANGUAGE OverloadedStrings    #-}
+
+module Main (main) where
+
+import Test.Hspec
+import Control.Monad
+import Data.Default
+import Control.Concurrent
+import Data.Maybe
+import qualified Data.Text as T
+
+import qualified CDP as CDP
+
+main :: IO ()
+main = hspec $ do
+    
+    describe "Endpoints responses of the expected type are received" $ do
+        it "sends requests to all endpoints" $ do
+            let cfg = def
+            targetId <- fmap CDP.tiId $ CDP.connectToTab cfg "https://haskell.foundation"
+            void $ mapM (CDP.fromSomeEndpoint $ void . CDP.endpoint cfg)
+                [ CDP.SomeEndpoint CDP.EPBrowserVersion
+                , CDP.SomeEndpoint CDP.EPAllTargets
+                , CDP.SomeEndpoint CDP.EPCurrentProtocol
+                , CDP.SomeEndpoint CDP.EPFrontend
+                , CDP.SomeEndpoint $ CDP.EPCloseTarget targetId
+                ]
+
+    targetInfo <- runIO $ CDP.connectToTab def "https://haskell.foundation"
+    let (host,port,path) = fromMaybe (error "invalid uri") . CDP.parseUri . T.unpack . CDP.tiWebSocketDebuggerUrl $ targetInfo
+        cfg      = def{CDP.hostPort = (host,port), CDP.path = Just path}
+        targetId = CDP.tiId targetInfo
+
+    describe "Command responses of the expected type are received" $ do
+        it "sends commands: w/o params w/o results" $ do
+            CDP.runClient cfg $ \handle -> do
+                CDP.sendCommandForSessionWait handle targetId CDP.PBrowserCrashGpuProcess
+        
+        it "sends commands: w/o params w/ results" $ do
+            void $ CDP.runClient cfg $ \handle -> do
+                mapM (CDP.fromSomeCommand $ void . (CDP.sendCommandWait handle)) $
+                    [ CDP.SomeCommand CDP.PBrowserGetVersion
+                    , CDP.SomeCommand CDP.PEmulationCanEmulate
+                    ]
+
+        it "sends commands: w/ params w/o results" $ do
+            CDP.runClient cfg $ \handle -> 
+                CDP.sendCommandWait handle $
+                    CDP.PEmulationSetGeolocationOverride (Just 90) (Just 90) Nothing
+        
+        it "sends commands: w/ params w/ results" $ do
+            void $ CDP.runClient cfg $ \handle ->
+                CDP.sendCommandWait handle $ CDP.PDOMGetDocument Nothing Nothing
+
+    describe "Commands have the expected behaviour" $ do
+        it "sets a cookie" $ do
+            let name   = "key"
+                value  = "value"
+                domain = "localhost"
+
+            cookies <- CDP.runClient cfg $ \handle -> do
+                CDP.sendCommandWait handle CDP.PNetworkClearBrowserCookies
+                CDP.sendCommandWait handle $
+                    CDP.PNetworkSetCookie name value Nothing (Just domain) Nothing Nothing Nothing Nothing Nothing
+                        Nothing Nothing Nothing Nothing Nothing
+                CDP.sendCommandWait handle CDP.PNetworkGetAllCookies
+    
+            let cks = CDP.networkGetAllCookiesCookies cookies
+            length cks `shouldBe` 1
+        
+            let cookie = head cks
+            CDP.networkCookieName   cookie `shouldBe` name
+            CDP.networkCookieValue  cookie `shouldBe` value
+            CDP.networkCookieDomain cookie `shouldBe` domain
+
+    describe "Expected events are triggered" $ do
+        it "navigates to a page" $ do
+            frameIdsM <- newMVar []
+            CDP.runClient cfg $ \handle -> do
+                -- register handler
+                void $ CDP.subscribe handle $ \e -> modifyMVar_ frameIdsM $ 
+                    \ids -> pure ((CDP.pageFrameId . CDP.pageFrameNavigatedFrame $ e) : ids)
+                -- enable events
+                CDP.sendCommandWait handle $ CDP.PPageEnable
+                -- navigate to page
+                void $ CDP.sendCommandWait handle $
+                    CDP.PPageNavigate "http://wikipedia.com" Nothing Nothing Nothing Nothing
+                -- wait for events
+                threadDelay 5000000
+            
+            -- check at least 1 event was received
+            ids <- readMVar frameIdsM
+            length ids `shouldSatisfy` (> 0)                
